| ︙ | | | ︙ | |
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
|
Descent,
/// No step but the algorithm has been terminated.
Term,
}
/// Information about a minorant.
#[derive(Debug, Clone, Copy)]
struct MinorantInfo {
/// The minorant's index in the master problem
index: usize,
/// Current multiplier.
multiplier: usize,
}
/**
* Implementation of a bundle method.
*/
pub struct Solver<P>
where P : for <'a> FirstOrderProblem<'a>
{
/// The first order problem description.
problem : P,
/// The solver parameter.
pub params : SolverParams,
|
|
|
>
>
|
|
>
|
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
|
Descent,
/// No step but the algorithm has been terminated.
Term,
}
/// Information about a minorant.
#[derive(Debug, Clone)]
struct MinorantInfo<Pr> {
/// The minorant's index in the master problem
index: usize,
/// Current multiplier.
multiplier: usize,
/// Primal associated with this minorant.
primal: Option<Pr>,
}
/**
* Implementation of a bundle method.
*/
pub struct Solver<P, Pr, E>
where P : for <'a> FirstOrderProblem<'a,Primal=Pr,EvalResult=E>,
E : Evaluation<Pr>,
{
/// The first order problem description.
problem : P,
/// The solver parameter.
pub params : SolverParams,
|
| ︙ | | | ︙ | |
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
|
*/
start_time : Instant,
/// The master problem.
master: Box<MasterProblem<MinorantIndex=usize>>,
/// The active minorant indices for each subproblem.
minorants: Vec<Vec<MinorantInfo>>,
}
impl<P> Solver<P>
where P : for <'a> FirstOrderProblem<'a>
{
/**
* Create a new solver for the given problem.
*
* Note that the solver owns the problem, so you cannot use the
* same problem description elsewhere as long as it is assigned to
* the solver. However, it is possible to get a reference to the
* internally stored problem using `Solver::problem()`.
*/
pub fn new_params(problem : P, params : SolverParams) -> Result<Solver<P>> {
Ok(Solver{
problem: problem,
params: params,
terminator: Box::new(StandardTerminator { termination_precision: 1e-3 }),
weighter: Box::new(HKWeighter::new()),
cur_y : dvec![],
cur_val : 0.0,
|
|
|
|
>
|
|
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
|
*/
start_time : Instant,
/// The master problem.
master: Box<MasterProblem<MinorantIndex=usize>>,
/// The active minorant indices for each subproblem.
minorants: Vec<Vec<MinorantInfo<Pr>>>,
}
impl<P, Pr, E> Solver<P, Pr, E>
where P : for <'a> FirstOrderProblem<'a, Primal=Pr,EvalResult=E>,
E : Evaluation<Pr>
{
/**
* Create a new solver for the given problem.
*
* Note that the solver owns the problem, so you cannot use the
* same problem description elsewhere as long as it is assigned to
* the solver. However, it is possible to get a reference to the
* internally stored problem using `Solver::problem()`.
*/
pub fn new_params(problem : P, params : SolverParams) -> Result<Solver<P, Pr, E>> {
Ok(Solver{
problem: problem,
params: params,
terminator: Box::new(StandardTerminator { termination_precision: 1e-3 }),
weighter: Box::new(HKWeighter::new()),
cur_y : dvec![],
cur_val : 0.0,
|
| ︙ | | | ︙ | |
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
|
Err(err) => return Err(Error::Master(Box::new(err))),
},
minorants: vec![],
})
}
/// A new solver with default parameter.
pub fn new(problem : P) -> Result<Solver<P>> {
Solver::new_params(problem, SolverParams::default())
}
/**
* Set the first order problem description associated with this
* solver.
*
|
|
|
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
|
Err(err) => return Err(Error::Master(Box::new(err))),
},
minorants: vec![],
})
}
/// A new solver with default parameter.
pub fn new(problem : P) -> Result<Solver<P,Pr,E>> {
Solver::new_params(problem, SolverParams::default())
}
/**
* Set the first order problem description associated with this
* solver.
*
|
| ︙ | | | ︙ | |
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
|
}
}
try!(self.master.set_num_subproblems(m));
self.master.set_vars(self.problem.num_variables(), lb, ub);
self.master.set_max_updates(self.params.max_updates);
self.minorants = vec![vec![]; m];
self.cur_val = 0.0;
for i in 0..m {
let result = match self.problem.evaluate(i, &self.cur_y, INFINITY, 0.0) {
Ok(r) => r,
Err(err) => return Err(Error::Eval(Box::new(err))),
};
self.cur_vals[i] = result.objective();
self.cur_val += self.cur_vals[i];
let mut minorants = result.into_iter();
if let Some((minorant, _)) = minorants.next() {
self.cur_mods[i] = minorant.constant;
self.cur_mod += self.cur_mods[i];
self.minorants[i].push(MinorantInfo {
index: try!(self.master.add_minorant(i, minorant)),
multiplier: 0,
});
} else {
return Err(Error::NoMinorant);
}
}
self.cur_valid = true;
|
|
>
|
>
|
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
|
}
}
try!(self.master.set_num_subproblems(m));
self.master.set_vars(self.problem.num_variables(), lb, ub);
self.master.set_max_updates(self.params.max_updates);
self.minorants = Vec::with_capacity(m);
for _ in 0..m { self.minorants.push(vec![]); }
self.cur_val = 0.0;
for i in 0..m {
let result = match self.problem.evaluate(i, &self.cur_y, INFINITY, 0.0) {
Ok(r) => r,
Err(err) => return Err(Error::Eval(Box::new(err))),
};
self.cur_vals[i] = result.objective();
self.cur_val += self.cur_vals[i];
let mut minorants = result.into_iter();
if let Some((minorant, primal)) = minorants.next() {
self.cur_mods[i] = minorant.constant;
self.cur_mod += self.cur_mods[i];
self.minorants[i].push(MinorantInfo {
index: try!(self.master.add_minorant(i, minorant)),
multiplier: 0,
primal: Some(primal),
});
} else {
return Err(Error::NoMinorant);
}
}
self.cur_valid = true;
|
| ︙ | | | ︙ | |
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
|
for i in 0..self.problem.num_subproblems() {
let n = self.master.num_minorants(i);
if n >= self.params.max_bundle_size {
for m in self.minorants[i].iter_mut() {
m.multiplier = (1e6 * self.master.multiplier(m.index)) as usize;
}
self.minorants[i].sort_by_key(|m| -(m.multiplier as isize));
let remove = self.minorants[i].split_off(self.params.max_bundle_size-2);
self.minorants[i].push(MinorantInfo{
index: try!(self.master.aggregate(i, &remove.iter().map(|m| m.index).collect::<Vec<_>>())),
multiplier: 0,
});
}
}
Ok(())
}
/// Perform a descent step.
|
|
>
>
>
>
|
>
|
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
|
for i in 0..self.problem.num_subproblems() {
let n = self.master.num_minorants(i);
if n >= self.params.max_bundle_size {
for m in self.minorants[i].iter_mut() {
m.multiplier = (1e6 * self.master.multiplier(m.index)) as usize;
}
self.minorants[i].sort_by_key(|m| -(m.multiplier as isize));
let aggr = self.minorants[i].split_off(self.params.max_bundle_size-2);
let (aggr_mins, aggr_primals) : (Vec<_>, Vec<_>) = aggr.into_iter().map(|m| {
(m.index, m.primal.unwrap())
}).unzip();
let (aggr_min, aggr_coeffs) = try!(self.master.aggregate(i, &aggr_mins));
self.minorants[i].push(MinorantInfo{
index: aggr_min,
multiplier: 0,
primal: Some(self.problem.aggregate_primals(&aggr_coeffs, aggr_primals)),
});
}
}
Ok(())
}
/// Perform a descent step.
|
| ︙ | | | ︙ | |
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
|
let new_weight = self.weighter.weight(¤t_state!(self, Step::Null), &self.params);
self.master.set_weight(new_weight);
self.cnt_null += 1;
debug!("Null Step");
}
/// Perform one bundle iteration.
pub fn step(&mut self) -> Result<Step> {
if !self.cur_valid {
// current point needs new evaluation
try!(self.init_master());
}
try!(self.solve_model());
if self.terminator.terminate(¤t_state!(self, Step::Term), &self.params) {
|
|
>
|
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
|
let new_weight = self.weighter.weight(¤t_state!(self, Step::Null), &self.params);
self.master.set_weight(new_weight);
self.cnt_null += 1;
debug!("Null Step");
}
/// Perform one bundle iteration.
pub fn step(&mut self) -> Result<Step>
{
if !self.cur_valid {
// current point needs new evaluation
try!(self.init_master());
}
try!(self.solve_model());
if self.terminator.terminate(¤t_state!(self, Step::Term), &self.params) {
|
| ︙ | | | ︙ | |
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
|
Ok(r) => r,
Err(err) => return Err(Error::Eval(Box::new(err))),
};
let fun_ub = result.objective();
let mut minorants = result.into_iter();
let mut nxt_minorant = match minorants.next() {
Some((m, _)) => m,
None => return Err(Error::NoMinorant)
};
let fun_lb = nxt_minorant.constant;
nxt_lb += fun_lb;
nxt_ub += fun_ub;
self.nxt_vals[fidx] = fun_ub;
// move center of minorant to cur_y
nxt_minorant.move_center(-1.0, &self.nxt_d);
self.new_cutval += nxt_minorant.constant;
self.minorants[fidx].push(MinorantInfo{
index: try!(self.master.add_minorant(fidx, nxt_minorant)),
multiplier: 0,
});
}
if self.new_cutval > self.cur_val + 1e-3 {
warn!("New minorant has higher value in center new:{} old:{}", self.new_cutval, self.cur_val);
self.cur_val = self.new_cutval;
}
|
|
>
>
|
>
>
>
<
>
>
|
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
|
Ok(r) => r,
Err(err) => return Err(Error::Eval(Box::new(err))),
};
let fun_ub = result.objective();
let mut minorants = result.into_iter();
let mut nxt_minorant;
let nxt_primal;
match minorants.next() {
Some((m, p)) => {
nxt_minorant = m;
nxt_primal = p;
},
None => return Err(Error::NoMinorant)
}
let fun_lb = nxt_minorant.constant;
nxt_lb += fun_lb;
nxt_ub += fun_ub;
self.nxt_vals[fidx] = fun_ub;
// move center of minorant to cur_y
nxt_minorant.move_center(-1.0, &self.nxt_d);
self.new_cutval += nxt_minorant.constant;
self.minorants[fidx].push(MinorantInfo{
index: try!(self.master.add_minorant(fidx, nxt_minorant)),
multiplier: 0,
primal: Some(nxt_primal),
});
}
if self.new_cutval > self.cur_val + 1e-3 {
warn!("New minorant has higher value in center new:{} old:{}", self.new_cutval, self.cur_val);
self.cur_val = self.new_cutval;
}
|
| ︙ | | | ︙ | |