RsBundle  Diff

Differences From Artifact [5e30ccea47]:

  • File src/mcf/problem.rs — part of check-in [4d96ced3a6] at 2019-07-23 11:21:52 on branch mmcf-parallel — mmcf: split data in `Subproblem` structure (user: fifr size: 12280)

To Artifact [42c0648a42]:

  • File src/mcf/problem.rs — part of check-in [7138078a5c] at 2019-07-23 11:57:19 on branch mmcf-parallel — mmcf: move lhs data to `Subproblem` (user: fifr size: 12337)

13
14
15
16
17
18
19

20
21
22
23
24
25
26
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27







+







// You should have received a copy of the GNU General Public License
// along with this program.  If not, see  <http://www.gnu.org/licenses/>
//

use crate::mcf;
use crate::{Aggregatable, DVector, FirstOrderProblem, Minorant, Real, SimpleEvaluation};

use itertools::izip;
use log::debug;

use std::f64::INFINITY;
use std::fmt;
use std::fs::File;
use std::io::Read;
use std::result;
97
98
99
100
101
102
103

104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113

114
115
116
117
118
119
120







+








-







    ind: usize,
    val: Real,
}

/// A single MMCF subproblem, i.e. one network.
struct Subproblem {
    net: mcf::Solver,
    lhs: Vec<Vec<Elem>>,
    cbase: DVector,
    c: DVector,
}

pub struct MMCFProblem {
    pub multimodel: bool,

    subs: Vec<Subproblem>,
    lhs: Vec<Vec<Vec<Elem>>>,
    rhs: DVector,
    rhsval: Real,
}

impl MMCFProblem {
    pub fn read_mnetgen(basename: &str) -> std::result::Result<MMCFProblem, MMCFReadError> {
        let mut buffer = String::new();
209
210
211
212
213
214
215
216

217
218
219



220
221
222
223
224
225
226







227
228
229
230
231
232
233
234
235
236
237
238
239
210
211
212
213
214
215
216

217



218
219
220
221
222
223




224
225
226
227
228
229
230
231
232
233
234
235

236
237
238
239
240
241
242







-
+
-
-
-
+
+
+



-
-
-
-
+
+
+
+
+
+
+





-







            let mut data = line.split_whitespace();
            let mt = data.next().unwrap().parse::<usize>()? - 1;
            let cap = data.next().unwrap().parse::<Real>()?;
            rhs[mt] = cap;
        }

        // set lhs
        let mut lhs = vec![vec![vec![]; ncom]; ncaps];
        let mut lhs = vec![vec![vec![]; ncaps]; ncom];
        for i in 0..ncaps {
            for fidx in 0..ncom {
                lhs[i][fidx] = lhsidx[i][fidx].iter().map(|&j| Elem { ind: j, val: 1.0 }).collect();
        for fidx in 0..ncom {
            for i in 0..ncaps {
                lhs[fidx][i] = lhsidx[i][fidx].iter().map(|&j| Elem { ind: j, val: 1.0 }).collect();
            }
        }

        let subproblems = nets
            .into_iter()
            .zip(cbase)
            .map(|(net, cbase)| Subproblem { net, cbase, c: dvec![] })
        let subproblems = izip!(nets, cbase, lhs)
            .map(|(net, cbase, lhs)| Subproblem {
                net,
                cbase,
                c: dvec![],
                lhs,
            })
            .collect();

        Ok(MMCFProblem {
            multimodel: false,
            subs: subproblems,
            lhs,
            rhs,
            rhsval: 0.0,
        })
    }

    /// Compute costs for a primal solution.
    pub fn get_primal_costs(&self, fidx: usize, primals: &[DVector]) -> Real {
304
305
306
307
308
309
310
311

312
313
314
315

316
317
318
319
320
321
322
307
308
309
310
311
312
313

314
315
316
317

318
319
320
321
322
323
324
325







-
+



-
+







    type Err = Error;

    type Primal = Vec<DVector>;

    type EvalResult = SimpleEvaluation<Vec<DVector>>;

    fn num_variables(&self) -> usize {
        self.lhs.len()
        self.rhs.len()
    }

    fn lower_bounds(&self) -> Option<Vec<Real>> {
        Some(vec![0.0; self.lhs.len()])
        Some(vec![0.0; self.rhs.len()])
    }

    fn upper_bounds(&self) -> Option<Vec<Real>> {
        None
    }

    fn num_subproblems(&self) -> usize {
335
336
337
338
339
340
341
342

343
344
345
346
347
348
349
338
339
340
341
342
343
344

345
346
347
348
349
350
351
352







-
+







            sub.c.clear();
            sub.c.extend(sub.cbase.iter());
        }

        for (i, &y) in y.iter().enumerate().filter(|&(i, &y)| y != 0.0) {
            self.rhsval += self.rhs[i] * y;
            for (fidx, sub) in self.subs.iter_mut().enumerate() {
                for elem in &self.lhs[i][fidx] {
                for elem in &sub.lhs[i] {
                    sub.c[elem.ind] += y * elem.val;
                }
            }
        }

        debug!("y={:?}", y);
        for (i, sub) in self.subs.iter_mut().enumerate() {
366
367
368
369
370
371
372
373
374


375
376
377
378
379
380
381
369
370
371
372
373
374
375


376
377
378
379
380
381
382
383
384







-
-
+
+







                objective = self.rhsval - self.subs[fidx].net.objective()?;
            } else {
                subg = dvec![0.0; self.rhs.len()];
                objective = -self.subs[fidx].net.objective()?;
            }

            let sol = self.subs[fidx].net.get_solution()?;
            for (i, lhs) in self.lhs.iter().enumerate() {
                subg[i] -= lhs[fidx].iter().map(|elem| elem.val * sol[elem.ind]).sum::<Real>();
            for (i, lhs) in self.subs[fidx].lhs.iter().enumerate() {
                subg[i] -= lhs.iter().map(|elem| elem.val * sol[elem.ind]).sum::<Real>();
            }

            Ok(SimpleEvaluation {
                objective,
                minorants: vec![(
                    Minorant {
                        constant: objective,
389
390
391
392
393
394
395
396
397
398



399
400
401
402
403
404
405
392
393
394
395
396
397
398



399
400
401
402
403
404
405
406
407
408







-
-
-
+
+
+







            let mut sols = Vec::with_capacity(self.subs.len());
            for sub in &self.subs {
                objective -= sub.net.objective()?;
                sols.push(sub.net.get_solution()?);
            }

            let mut subg = self.rhs.clone();
            for (i, lhs) in self.lhs.iter().enumerate() {
                for (fidx, flhs) in lhs.iter().enumerate() {
                    subg[i] -= flhs.iter().map(|elem| elem.val * sols[fidx][elem.ind]).sum::<Real>();
            for (fidx, sub) in self.subs.iter().enumerate() {
                for (i, lhs) in sub.lhs.iter().enumerate() {
                    subg[i] -= lhs.iter().map(|elem| elem.val * sols[fidx][elem.ind]).sum::<Real>();
                }
            }

            Ok(SimpleEvaluation {
                objective,
                minorants: vec![(
                    Minorant {