Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Remove unused parameters from `SolverParam` |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | async |
| Files: | files | file ages | folders |
| SHA1: |
f5557bc6afdbd0bfad51536d180a98ea |
| User & Date: | fifr 2019-07-20 14:17:40.921 |
Context
|
2019-07-21
| ||
| 17:28 | Move master process code to `masterprocess` check-in: a7b5649186 user: fifr tags: async | |
|
2019-07-20
| ||
| 14:17 | Remove unused parameters from `SolverParam` check-in: f5557bc6af user: fifr tags: async | |
| 13:58 | Merge terminator check-in: 071e757395 user: fifr tags: async | |
Changes
Changes to examples/mmcf.rs.
| ︙ | ︙ | |||
20 21 22 23 24 25 26 |
use log::info;
use bundle::mcf;
use bundle::{DefaultSolver, FirstOrderProblem, SolverParams};
use std::env;
| | | | < < | < > | > > | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
use log::info;
use bundle::mcf;
use bundle::{DefaultSolver, FirstOrderProblem, SolverParams};
use std::env;
fn main() -> std::result::Result<(), Box<std::error::Error>> {
env_logger::init();
let mut args = env::args();
let program = args.next().ok_or_else(|| "Missing filename".to_string())?;
if let Some(filename) = args.next() {
info!("Reading instance: {}", filename);
let mut mmcf = mcf::MMCFProblem::read_mnetgen(&filename)?;
mmcf.multimodel = false;
let mut solver = DefaultSolver::new_params(
mmcf,
SolverParams {
max_bundle_size: 25,
..Default::default()
},
)?;
solver.weighter.set_weight_bounds(1e-3, 100.0);
solver.terminator.termination_precision = 1e-6;
solver.solve()?;
let costs: f64 = (0..solver.problem().num_subproblems())
.map(|i| {
let aggr_primals = solver.aggregated_primals(i);
solver.problem().get_primal_costs(i, &aggr_primals)
})
.sum();
info!("Primal costs: {}", costs);
} else {
panic!("Usage: {} FILENAME", program);
}
Ok(())
}
|
Changes to examples/quadratic.rs.
| ︙ | ︙ | |||
17 18 19 20 21 22 23 |
use std::error::Error;
use bundle::{self, dvec};
use env_logger;
use log::debug;
| | | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
use std::error::Error;
use bundle::{self, dvec};
use env_logger;
use log::debug;
use bundle::{DVector, DefaultSolver, FirstOrderProblem, Minorant, Real, SimpleEvaluation};
struct QuadraticProblem {
a: [[Real; 2]; 2],
b: [Real; 2],
c: Real,
}
|
| ︙ | ︙ | |||
79 80 81 82 83 84 85 |
},
(),
)],
})
}
}
| | | < < | < < < > | | < | 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
},
(),
)],
})
}
}
fn main() -> Result<(), Box<Error>> {
env_logger::init();
let f = QuadraticProblem::new();
let mut solver = DefaultSolver::new(f).map_err(|e| format!("{}", e))?;
solver.weighter.set_weight_bounds(1.0, 1.0);
solver.solve().map_err(|e| format!("{}", e))?;
Ok(())
}
|
Changes to src/master/boxed.rs.
| ︙ | ︙ | |||
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
* Turn unconstrained master problem into box-constrained one.
*
* This master problem adds box constraints to an unconstrainted
* master problem implementation. The box constraints are enforced by
* an additional outer optimization loop.
*/
pub struct BoxedMasterProblem<M> {
lb: DVector,
ub: DVector,
eta: DVector,
/// Primal optimal solution.
primopt: DVector,
/// Primal optimal solution value.
primoptval: Real,
/// Square of norm of dual optimal solution.
dualoptnorm2: Real,
/// Model precision.
model_eps: Real,
need_new_candidate: bool,
| > > > > > > > > > > > < < < < < < > > < < | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
* Turn unconstrained master problem into box-constrained one.
*
* This master problem adds box constraints to an unconstrainted
* master problem implementation. The box constraints are enforced by
* an additional outer optimization loop.
*/
pub struct BoxedMasterProblem<M> {
/// The unconstrained master problem solver.
pub master: M,
/// Maximal number of updates of box multipliers.
pub max_updates: usize,
/// Variable lower bounds.
lb: DVector,
/// Variable upper bounds.
ub: DVector,
/// Multipliers for box constraints.
eta: DVector,
/// Primal optimal solution.
primopt: DVector,
/// Primal optimal solution value.
primoptval: Real,
/// Square of norm of dual optimal solution.
dualoptnorm2: Real,
/// Model precision.
model_eps: Real,
need_new_candidate: bool,
/// Current number of updates.
cnt_updates: usize,
}
impl<M> BoxedMasterProblem<M>
where
M: UnconstrainedMasterProblem,
{
pub fn with_master(master: M) -> BoxedMasterProblem<M> {
BoxedMasterProblem {
master,
max_updates: 50,
lb: dvec![],
ub: dvec![],
eta: dvec![],
primopt: dvec![],
primoptval: 0.0,
dualoptnorm2: 0.0,
model_eps: 0.6,
cnt_updates: 0,
need_new_candidate: true,
}
}
pub fn set_max_updates(&mut self, max_updates: usize) -> Result<(), M::Err> {
assert!(max_updates > 0);
self.max_updates = max_updates;
Ok(())
|
| ︙ | ︙ |
Changes to src/parallel/solver.rs.
| ︙ | ︙ | |||
104 105 106 107 108 109 110 |
num_subproblems: usize,
/// The number of variables.
num_vars: usize,
/// The lower bounds on the variables.
lower_bounds: Option<DVector>,
/// The lower bounds on the variables.
upper_bounds: Option<DVector>,
| < < | 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
num_subproblems: usize,
/// The number of variables.
num_vars: usize,
/// The lower bounds on the variables.
lower_bounds: Option<DVector>,
/// The lower bounds on the variables.
upper_bounds: Option<DVector>,
}
/// A task for the master problem.
enum MasterTask<Pr> {
/// Add a new minorant for a subfunction to the master problem.
AddMinorant(usize, Minorant, Pr),
|
| ︙ | ︙ | |||
353 354 355 356 357 358 359 |
self.master_rx = Some(rev_rx);
let master_config = MasterConfig {
num_subproblems: m,
num_vars: n,
lower_bounds: self.problem.lower_bounds().map(DVector),
upper_bounds: self.problem.upper_bounds().map(DVector),
| < | 351 352 353 354 355 356 357 358 359 360 361 362 363 364 |
self.master_rx = Some(rev_rx);
let master_config = MasterConfig {
num_subproblems: m,
num_vars: n,
lower_bounds: self.problem.lower_bounds().map(DVector),
upper_bounds: self.problem.upper_bounds().map(DVector),
};
if master_config
.lower_bounds
.as_ref()
.map(|lb| lb.len() != n)
.unwrap_or(false)
|
| ︙ | ︙ | |||
462 463 464 465 466 467 468 |
// Initialize the master problem.
master.set_num_subproblems(master_config.num_subproblems)?;
master.set_vars(
master_config.num_vars,
master_config.lower_bounds,
master_config.upper_bounds,
)?;
| < | 459 460 461 462 463 464 465 466 467 468 469 470 471 472 |
// Initialize the master problem.
master.set_num_subproblems(master_config.num_subproblems)?;
master.set_vars(
master_config.num_vars,
master_config.lower_bounds,
master_config.upper_bounds,
)?;
// The main iteration: wait for new tasks.
for m in rx {
match m {
MasterTask::AddMinorant(i, m, primal) => {
debug!("master: add minorant to subproblem {}", i);
let index = master.add_minorant(i, m)?;
|
| ︙ | ︙ |
Changes to src/solver.rs.
| ︙ | ︙ | |||
244 245 246 247 248 249 250 |
* step. If the function is evaluated by some iterative method that ensures
* an objective value that is at least as large as this bound, the
* oracle can stop returning an appropriate $\varepsilon$-subgradient.
*
* Must be in (0, acceptance_factor).
*/
pub nullstep_factor: Real,
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 |
* step. If the function is evaluated by some iterative method that ensures
* an objective value that is at least as large as this bound, the
* oracle can stop returning an appropriate $\varepsilon$-subgradient.
*
* Must be in (0, acceptance_factor).
*/
pub nullstep_factor: Real,
}
impl SolverParams {
/// Verify that all parameters are valid.
fn check(&self) -> Result<(), ParameterError> {
if self.max_bundle_size < 2 {
Err(ParameterError(format!(
"max_bundle_size must be >= 2 (got: {})",
self.max_bundle_size
)))
} else if self.acceptance_factor <= 0.0 || self.acceptance_factor >= 1.0 {
Err(ParameterError(format!(
"acceptance_factor must be in (0,1) (got: {})",
self.acceptance_factor
)))
} else if self.nullstep_factor <= 0.0 || self.nullstep_factor > self.acceptance_factor {
Err(ParameterError(format!(
"nullstep_factor must be in (0,acceptance_factor] (got: {}, acceptance_factor:{})",
self.nullstep_factor, self.acceptance_factor
)))
} else {
Ok(())
}
}
}
impl Default for SolverParams {
fn default() -> SolverParams {
SolverParams {
max_bundle_size: 50,
nullstep_factor: 0.1,
acceptance_factor: 0.1,
}
}
}
/// The step type that has been performed.
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum Step {
|
| ︙ | ︙ | |||
816 817 818 819 820 821 822 |
.unwrap_or(false)
{
return Err(SolverError::Dimension);
}
self.master.set_num_subproblems(m)?;
self.master.set_vars(self.problem.num_variables(), lb, ub)?;
| < | 778 779 780 781 782 783 784 785 786 787 788 789 790 791 |
.unwrap_or(false)
{
return Err(SolverError::Dimension);
}
self.master.set_num_subproblems(m)?;
self.master.set_vars(self.problem.num_variables(), lb, ub)?;
self.minorants = (0..m).map(|_| vec![]).collect();
self.cur_val = 0.0;
for i in 0..m {
let result = self
.problem
|
| ︙ | ︙ |