problemreductions/rules/
partition_binpacking.rs1use crate::models::misc::{BinPacking, Partition};
16use crate::reduction;
17use crate::rules::traits::{ReduceTo, ReductionResult};
18
19#[derive(Debug, Clone)]
21pub struct ReductionPartitionToBinPacking {
22 target: BinPacking<i32>,
23}
24
25impl ReductionResult for ReductionPartitionToBinPacking {
26 type Source = Partition;
27 type Target = BinPacking<i32>;
28
29 fn target_problem(&self) -> &Self::Target {
30 &self.target
31 }
32
33 fn extract_solution(&self, target_solution: &[usize]) -> Vec<usize> {
34 let first_bin = target_solution[0];
38 target_solution
39 .iter()
40 .map(|&b| if b == first_bin { 0 } else { 1 })
41 .collect()
42 }
43}
44
45fn partition_size_to_i32(value: u64) -> i32 {
46 i32::try_from(value)
47 .expect("Partition -> BinPacking requires all sizes and total_sum / 2 to fit in i32")
48}
49
50#[reduction(overhead = {
51 num_items = "num_elements",
52})]
53impl ReduceTo<BinPacking<i32>> for Partition {
54 type Result = ReductionPartitionToBinPacking;
55
56 fn reduce_to(&self) -> Self::Result {
57 let sizes: Vec<i32> = self
58 .sizes()
59 .iter()
60 .copied()
61 .map(partition_size_to_i32)
62 .collect();
63 let capacity = partition_size_to_i32(self.total_sum() / 2);
64
65 ReductionPartitionToBinPacking {
66 target: BinPacking::new(sizes, capacity),
67 }
68 }
69}
70
71#[cfg(feature = "example-db")]
72pub(crate) fn canonical_rule_example_specs() -> Vec<crate::example_db::specs::RuleExampleSpec> {
73 use crate::export::SolutionPair;
74
75 vec![crate::example_db::specs::RuleExampleSpec {
76 id: "partition_to_binpacking",
77 build: || {
78 crate::example_db::specs::rule_example_with_witness::<_, BinPacking<i32>>(
79 Partition::new(vec![3, 1, 1, 2, 2, 1]),
80 SolutionPair {
81 source_config: vec![0, 1, 1, 0, 1, 1],
82 target_config: vec![0, 1, 1, 0, 1, 1],
83 },
84 )
85 },
86 }]
87}
88
89#[cfg(test)]
90#[path = "../unit_tests/rules/partition_binpacking.rs"]
91mod tests;