Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | solver: Handle minorants correctly. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA1: |
e671068275b483972ceb233dde085ae2 |
| User & Date: | fifr 2016-09-28 16:31:19.538 |
Context
|
2016-09-28
| ||
| 21:04 | master: Add `multiplier` method. check-in: 3863fc49a4 user: fifr tags: trunk | |
| 16:31 | solver: Handle minorants correctly. check-in: e671068275 user: fifr tags: trunk | |
| 16:30 | mcf: Support disaggregated subproblems. check-in: 4a174be0f5 user: fifr tags: trunk | |
Changes
Changes to src/solver.rs.
| ︙ | ︙ | |||
362 363 364 365 366 367 368 369 370 371 372 373 374 375 |
*
* This is actually the time of the last call to `Solver::init`.
*/
start_time : Instant,
/// The master problem.
master: Box<MasterProblem<MinorantIndex=usize>>,
}
impl<P> Solver<P>
where P : for <'a> FirstOrderProblem<'a>
{
/**
| > > > | 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 |
*
* This is actually the time of the last call to `Solver::init`.
*/
start_time : Instant,
/// The master problem.
master: Box<MasterProblem<MinorantIndex=usize>>,
/// The active minorant indices for each subproblem.
minorants: Vec<Vec<usize>>,
}
impl<P> Solver<P>
where P : for <'a> FirstOrderProblem<'a>
{
/**
|
| ︙ | ︙ | |||
403 404 405 406 407 408 409 |
expected_progress: 0.0,
cnt_descent: 0,
cnt_null: 0,
start_time: Instant::now(),
master: match BoxedMasterProblem::<MinimalMaster>::new() {
Ok(master) => Box::new(master),
Err(err) => return Err(Error::Master(Box::new(err))),
| | > | 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 |
expected_progress: 0.0,
cnt_descent: 0,
cnt_null: 0,
start_time: Instant::now(),
master: match BoxedMasterProblem::<MinimalMaster>::new() {
Ok(master) => Box::new(master),
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())
}
|
| ︙ | ︙ | |||
526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 |
}
}
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.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];
| > > | | 530 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 |
}
}
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(try!(self.master.add_minorant(i, minorant)));
} else {
return Err(Error::NoMinorant);
}
}
self.cur_valid = true;
self.master.set_weight(1.0);
|
| ︙ | ︙ | |||
575 576 577 578 579 580 581 |
debug!(" nxt_mod ={}", self.nxt_mod);
debug!(" expected={}", self.expected_progress);
Ok(())
}
/// Reduce size of bundle.
| | | > > > | 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 |
debug!(" nxt_mod ={}", self.nxt_mod);
debug!(" expected={}", self.expected_progress);
Ok(())
}
/// Reduce size of bundle.
fn compress_bundle(&mut self) -> Result<()> {
for i in 0..self.problem.num_subproblems() {
let n = self.master.num_minorants(i);
if n >= self.params.max_bundle_size {
let mut remove = self.minorants[i].split_off(self.params.max_bundle_size-2);
swap(&mut remove, &mut self.minorants[i]);
self.minorants[i].push(try!(self.master.aggregate(i, &remove)));
}
}
Ok(())
}
/// Perform a descent step.
fn descent_step(&mut self) {
let new_weight = self.weighter.weight(¤t_state!(self, Step::Descent), &self.params);
self.master.set_weight(new_weight);
self.cnt_descent += 1;
|
| ︙ | ︙ | |||
625 626 627 628 629 630 631 |
}
let m = self.problem.num_subproblems();
let descent_bnd = self.get_descent_bound();
let nullstep_bnd = if m == 1 { self.get_nullstep_bound() } else { INFINITY };
let relprec = if m == 1 { self.get_relative_precision() } else { 0.0 };
| | | 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 |
}
let m = self.problem.num_subproblems();
let descent_bnd = self.get_descent_bound();
let nullstep_bnd = if m == 1 { self.get_nullstep_bound() } else { INFINITY };
let relprec = if m == 1 { self.get_relative_precision() } else { 0.0 };
try!(self.compress_bundle());
let mut nxt_lb = 0.0;
let mut nxt_ub = 0.0;
for fidx in 0..self.problem.num_subproblems() {
let result = match self.problem.evaluate(fidx, &self.nxt_y, nullstep_bnd, relprec) {
Ok(r) => r,
Err(err) => return Err(Error::Eval(Box::new(err))),
|
| ︙ | ︙ | |||
651 652 653 654 655 656 657 |
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;
| | | 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 |
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(try!(self.master.add_minorant(fidx, nxt_minorant)));
}
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;
}
|
| ︙ | ︙ |