use std::{num::ParseIntError, path::Path, fs::File, io::{BufReader, BufRead}};
use crate::model::Psp;
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("io error {0}")]
Io(#[from] std::io::Error),
#[error("parse int {0}")]
ParseInt(#[from] ParseIntError),
#[error("ill formed instance")]
Format,
}
pub fn read_instance<P: AsRef<Path>>(fname: P) -> Result<Psp, Error> {
let f = File::open(fname)?;
let f = BufReader::new(f);
let mut lines = f.lines();
let nb_periods = lines.next().ok_or(Error::Format)??.parse::<usize>()?;
let nb_items = lines.next().ok_or(Error::Format)??.parse::<usize>()?;
let _nb_orders = lines.next().ok_or(Error::Format)??.parse::<usize>()?;
let _blank = lines.next();
let mut changeover_cost = vec![];
for line in &mut lines {
let line = line?;
let line = line.trim();
if line.is_empty() {
break;
}
let costs = line.split_whitespace()
.map(|x| x.parse::<usize>().unwrap())
.collect::<Vec<_>>();
changeover_cost.push(costs);
}
let stocking_cost = lines.next().ok_or(Error::Format)??.split_whitespace()
.map(|x| x.parse::<usize>().unwrap())
.collect::<Vec<usize>>();
let _blank = lines.next();
let mut demands = vec![];
for line in &mut lines {
let line = line?;
let line = line.trim();
if line.is_empty() { break;
}
let demands_for_item = line.split_whitespace()
.map(|n| n.parse::<usize>().unwrap())
.collect::<Vec<_>>();
demands.push(demands_for_item);
}
let mut prev_demands = vec![ vec![-1; nb_periods + 1] ; nb_items];
for t in 1..=nb_periods {
for i in 0..nb_items {
if demands[i][t-1] > 0 {
prev_demands[i][t] = (t-1) as isize;
} else {
prev_demands[i][t] = prev_demands[i][t-1];
}
}
}
let mut rem_demands = vec![ vec![0; nb_periods] ; nb_items];
for t in 0..nb_periods {
for i in 0..nb_items {
if t == 0 {
rem_demands[i][t] = demands[i][t] as isize;
} else {
rem_demands[i][t] = rem_demands[i][t-1] + demands[i][t] as isize;
}
}
}
Ok(Psp {
n_items: nb_items,
horizon: nb_periods,
stocking: stocking_cost,
changeover: changeover_cost,
prev_demands,
rem_demands
})
}