use rs_graph::dimacs;
use rs_graph::mcf::{MinCostFlow, NetworkSimplex};
use rs_graph::traits::*;
use rs_graph::vec::{EdgeVec, NodeVec};
use rs_graph::Net;
use std::error::Error;
use std::io::Write;
use std::path::PathBuf;
use std::result::Result;
use rustop::opts;
use time::OffsetDateTime;
fn main() -> Result<(), Box<dyn Error>> {
let (args, _) = opts! {
synopsis "Solve min-cost-flow problem with a network simplex algorithm.";
param file:String, desc:"Instance file name";
}
.parse_or_exit();
let tstart = OffsetDateTime::now_utc();
let instance = dimacs::min::read_from_file(&args.file).unwrap();
let g: Net = instance.graph;
let balances = NodeVec::new_from_vec(&g, instance.balances);
let lower = EdgeVec::new_from_vec(&g, instance.lower);
let upper = EdgeVec::new_from_vec(&g, instance.upper);
let costs = EdgeVec::new_from_vec(&g, instance.costs);
let tend = OffsetDateTime::now_utc();
println!("Instance : {}", args.file);
println!("Read Time (seconds) : {}", (tend - tstart).as_seconds_f64());
println!("Graph type : {}", std::any::type_name::<Net>());
println!("Number of nodes : {}", g.num_nodes());
println!("Number of edges : {}", g.num_edges());
let mut spx = NetworkSimplex::new(&g);
spx.set_balances(|u| balances[u]);
spx.set_lowers(|e| lower[e]);
spx.set_uppers(|e| upper[e]);
spx.set_costs(|e| costs[e]);
let tstart = OffsetDateTime::now_utc();
let state = spx.solve();
let tend = OffsetDateTime::now_utc();
let soltime = (tend - tstart).as_seconds_f64();
println!();
println!("Solution state : {:?}", state);
println!("Value : {:.2}", spx.value());
println!("Time (seconds) : {:.2}", soltime);
println!("Iterations (total) : {}", spx.num_iterations());
println!();
println!("Write solution to : {}.sol", args.file);
let solfile = PathBuf::from(args.file + ".sol");
let f = &mut std::fs::File::create(&solfile)?;
let fname = solfile
.file_name()
.map(|s| s.to_string_lossy())
.unwrap_or_else(|| "".into());
writeln!(f, "c Solved with a primal network simplex")?;
writeln!(f, "c instance : {}", fname)?;
writeln!(f, "c solution time : {:.2} seconds", soltime)?;
writeln!(f, "c number of iterations: {}", spx.num_iterations())?;
dimacs::min::write_solution(f, &g, |e| spx.flow(e) as isize, spx.value() as isize)?;
Ok(())
}