rustsat_tools/encodings/pb/
knapsack.rsuse rustsat::{
instances::fio::opb,
lit,
types::{constraints::PBConstraint, Lit},
};
use crate::encodings::knapsack::Knapsack;
#[derive(Default)]
enum Line {
#[default]
Hint,
Description,
Objective(usize),
Capacity,
}
pub struct Encoding {
data: Knapsack,
next_line: Option<Line>,
}
impl Encoding {
pub fn new(data: Knapsack) -> Self {
Self {
data,
next_line: Some(Line::default()),
}
}
}
impl Iterator for Encoding {
type Item = opb::FileLine<<Vec<(Lit, usize)> as IntoIterator>::IntoIter>;
fn next(&mut self) -> Option<Self::Item> {
match self.next_line.take() {
Some(line) => Some(match line {
Line::Hint => {
self.next_line = Some(Line::Description);
opb::FileLine::Comment(format!(
"#variable= {} #constraint= 1",
self.data.items.len()
))
}
Line::Description => {
self.next_line = Some(Line::Objective(0));
opb::FileLine::Comment("MO Knapsack instance generated by RustSAT".to_string())
}
Line::Objective(oidx) => {
let obj: Vec<_> = self
.data
.items
.iter()
.enumerate()
.map(|(iidx, item)| (!lit![iidx as u32], item.values[oidx]))
.collect();
self.next_line = Some(if oidx + 1 < self.data.items[0].values.len() {
Line::Objective(oidx + 1)
} else {
Line::Capacity
});
opb::FileLine::Objective(obj.into_iter())
}
Line::Capacity => {
self.next_line = None;
let cap_constr = PBConstraint::new_ub(
self.data
.items
.iter()
.enumerate()
.map(|(idx, item)| (lit![idx as u32], item.weight as isize)),
self.data.capacity as isize,
);
opb::FileLine::Pb(cap_constr)
}
}),
None => None,
}
}
}