jagua_rs/probs/bpp/entities/
instance.rs

1use crate::entities::Instance;
2use crate::entities::{Container, Item};
3use crate::probs::bpp::entities::bin::Bin;
4use crate::probs::bpp::util::assertions::instance_item_bin_ids_correct;
5
6#[derive(Debug, Clone)]
7/// Instance of the Bin Packing Problem.
8pub struct BPInstance {
9    /// The items to be packed and their demands
10    pub items: Vec<(Item, usize)>,
11    /// Set of bins available to pack the items
12    pub bins: Vec<Bin>,
13}
14
15impl BPInstance {
16    #[must_use]
17    pub fn new(items: Vec<(Item, usize)>, bins: Vec<Bin>) -> Self {
18        assert!(instance_item_bin_ids_correct(&items, &bins));
19
20        Self { items, bins }
21    }
22
23    #[allow(clippy::cast_precision_loss)]
24    #[must_use]
25    pub fn item_area(&self) -> f32 {
26        self.items
27            .iter()
28            .map(|(item, qty)| item.shape_orig.area() * *qty as f32)
29            .sum()
30    }
31
32    #[must_use]
33    pub fn item_qty(&self, id: usize) -> usize {
34        self.items[id].1
35    }
36
37    pub fn bins(&self) -> impl Iterator<Item = &Bin> {
38        self.bins.iter()
39    }
40
41    #[must_use]
42    pub fn bin_qty(&self, id: usize) -> usize {
43        self.bins[id].stock
44    }
45
46    #[must_use]
47    pub fn total_item_qty(&self) -> usize {
48        self.items.iter().map(|(_, qty)| *qty).sum()
49    }
50}
51
52impl Instance for BPInstance {
53    fn items(&self) -> impl Iterator<Item = &Item> {
54        self.items.iter().map(|(item, _qty)| item)
55    }
56
57    fn containers(&self) -> impl Iterator<Item = &Container> {
58        self.bins.iter().map(|bin| &bin.container)
59    }
60
61    fn item(&self, id: usize) -> &Item {
62        &self.items.get(id).unwrap().0
63    }
64
65    fn container(&self, id: usize) -> &Container {
66        &self.bins[id].container
67    }
68}