Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | solver: Compress minorants with smallest multipliers. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA1: |
a86c952bc8b71b5f634b91dfc4a1d884 |
| User & Date: | fifr 2016-09-28 21:05:48.319 |
Context
|
2016-09-28
| ||
| 21:15 | solver: Fix fractions in time output. check-in: 77d15f47e4 user: fifr tags: trunk | |
| 21:05 | solver: Compress minorants with smallest multipliers. check-in: a86c952bc8 user: fifr tags: trunk | |
| 21:04 | master: Add `multiplier` method. check-in: 3863fc49a4 user: fifr tags: trunk | |
Changes
Changes to src/solver.rs.
| ︙ | ︙ | |||
176 177 178 179 180 181 182 |
/// Parameters for tuning the solver.
#[derive(Clone, Debug)]
pub struct SolverParams {
/// Maximal individual bundle size.
pub max_bundle_size : usize,
| < < < < < < < < | 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
/// Parameters for tuning the solver.
#[derive(Clone, Debug)]
pub struct SolverParams {
/// Maximal individual bundle size.
pub max_bundle_size : usize,
/**
* Factor for doing a descent step.
*
* If the proportion of actual decrease to predicted decrease is
* at least that high, a descent step will be done.
*
* Must be in (0,1).
|
| ︙ | ︙ | |||
254 255 256 257 258 259 260 |
}
}
impl Default for SolverParams {
fn default() -> SolverParams {
SolverParams {
max_bundle_size: 50,
| < | 246 247 248 249 250 251 252 253 254 255 256 257 258 259 |
}
}
impl Default for SolverParams {
fn default() -> SolverParams {
SolverParams {
max_bundle_size: 50,
nullstep_factor: 0.1,
acceptance_factor: 0.1,
min_weight: 0.01,
max_weight: 1000.0,
|
| ︙ | ︙ | |||
279 280 281 282 283 284 285 286 287 288 289 290 291 292 |
Null,
/// A descent step has been performed.
Descent,
/// No step but the algorithm has been terminated.
Term,
}
/**
* Implementation of a bundle method.
*/
pub struct Solver<P>
where P : for <'a> FirstOrderProblem<'a>
{
/// The first order problem description.
| > > > > > > > > > > | 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 |
Null,
/// A descent step has been performed.
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.
|
| ︙ | ︙ | |||
364 365 366 367 368 369 370 |
*/
start_time : Instant,
/// The master problem.
master: Box<MasterProblem<MinorantIndex=usize>>,
/// The active minorant indices for each subproblem.
| | | 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 |
*/
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>
{
/**
|
| ︙ | ︙ | |||
545 546 547 548 549 550 551 |
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];
| > | > > | 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 |
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;
self.master.set_weight(1.0);
|
| ︙ | ︙ | |||
572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 |
fn solve_model(&mut self) -> Result<()> {
try!(self.master.solve(self.cur_val));
self.nxt_d = self.master.get_primopt();
self.nxt_y.add(&self.cur_y, &self.nxt_d);
self.nxt_mod = self.master.get_primoptval();
self.sgnorm = self.master.get_dualoptnorm2().sqrt();
self.expected_progress = self.cur_val - self.nxt_mod;
debug!("Model result");
debug!(" cur_val ={}", self.cur_val);
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 {
| > > > > > | | | > > | 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 |
fn solve_model(&mut self) -> Result<()> {
try!(self.master.solve(self.cur_val));
self.nxt_d = self.master.get_primopt();
self.nxt_y.add(&self.cur_y, &self.nxt_d);
self.nxt_mod = self.master.get_primoptval();
self.sgnorm = self.master.get_dualoptnorm2().sqrt();
self.expected_progress = self.cur_val - self.nxt_mod;
debug!("Model result");
debug!(" cur_val ={}", self.cur_val);
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 {
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.
fn descent_step(&mut self) {
|
| ︙ | ︙ | |||
660 661 662 663 664 665 666 |
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;
| > | > > | 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 |
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;
}
|
| ︙ | ︙ |