extern crate structopt;
use ddo::core::abstraction::mdd::MDD;
use ddo::core::abstraction::solver::Solver;
use ddo::core::common::Decision;
use ddo::core::implementation::heuristics::FixedWidth;
use ddo::core::implementation::mdd::builder::mdd_builder_ref;
use ddo::core::implementation::solver::parallel::ParallelSolver;
use std::fs::File;
use std::time::SystemTime;
use structopt::StructOpt;
mod heuristics;
mod model;
mod relax;
use heuristics::KnapsackOrder;
use model::KnapsackState;
use relax::KnapsackRelax;
#[derive(StructOpt)]
struct Knapsack {
fname: String,
#[structopt(short, long, parse(from_occurrences))]
verbose: u8,
#[structopt(name="threads", short, long)]
threads: Option<usize>,
#[structopt(name="width", short, long)]
width: Option<usize>
}
fn main() {
let args = Knapsack::from_args();
knapsack(&args.fname, args.verbose, args.threads, args.width);
}
fn knapsack(fname: &str, verbose: u8, threads: Option<usize>, width: Option<usize>) {
let problem = File::open(fname).expect("File not found").into();
match width {
Some(max_width) => solve(mdd_builder_ref(&problem, KnapsackRelax::new(&problem))
.with_branch_heuristic(KnapsackOrder::new(&problem))
.with_max_width(FixedWidth(max_width))
.into_flat(), verbose, threads),
None => solve(mdd_builder_ref(&problem, KnapsackRelax::new(&problem))
.with_branch_heuristic(KnapsackOrder::new(&problem))
.into_flat(), verbose, threads)
}
}
fn solve<DD: MDD<KnapsackState> + Clone + Send >(mdd: DD, verbose: u8, threads: Option<usize>) {
let threads = threads.unwrap_or_else(num_cpus::get);
let mut solver = ParallelSolver::customized(mdd, verbose, threads);
let start = SystemTime::now();
let (opt, sln) = solver.maximize();
let end = SystemTime::now();
if verbose >= 1 {
println!("Optimum {} computed in {:?} with {} threads", opt, end.duration_since(start).unwrap(), threads);
}
maybe_print_solution(verbose, sln)
}
fn maybe_print_solution(verbose: u8, sln: &Option<Vec<Decision>>) {
if verbose >= 2 {
println!("### Solution: ################################################");
if let Some(sln) = sln {
let mut sln = sln.clone();
sln.sort_by_key(|d| d.variable.0);
for i in sln.iter() {
println!("{} -> {}", (i.variable.0 + 1), i.value);
}
}
}
if verbose >= 1 && sln.is_none() {
println!("No solution !");
}
}