problemreductions/rules/
partition_productionplanning.rs1use crate::models::misc::{Partition, ProductionPlanning};
4use crate::reduction;
5use crate::rules::traits::{ReduceTo, ReductionResult};
6
7#[derive(Debug, Clone)]
8pub struct ReductionPartitionToProductionPlanning {
9 target: ProductionPlanning,
10}
11
12impl ReductionResult for ReductionPartitionToProductionPlanning {
13 type Source = Partition;
14 type Target = ProductionPlanning;
15
16 fn target_problem(&self) -> &Self::Target {
17 &self.target
18 }
19
20 fn extract_solution(&self, target_solution: &[usize]) -> Vec<usize> {
21 target_solution
22 .iter()
23 .take(self.target.num_periods().saturating_sub(1))
24 .map(|&production| usize::from(production > 0))
25 .collect()
26 }
27}
28
29#[reduction(overhead = {
30 num_periods = "num_elements + 1",
31})]
32impl ReduceTo<ProductionPlanning> for Partition {
33 type Result = ReductionPartitionToProductionPlanning;
34
35 fn reduce_to(&self) -> Self::Result {
36 let half_floor = self.total_sum() / 2;
37 let half_ceil = half_floor + (self.total_sum() % 2);
38 let mut demands = vec![0; self.num_elements()];
39 demands.push(half_ceil);
40
41 let mut capacities = self.sizes().to_vec();
42 capacities.push(0);
43
44 let mut setup_costs = self.sizes().to_vec();
45 setup_costs.push(0);
46
47 let production_costs = vec![0; self.num_elements() + 1];
48 let inventory_costs = vec![0; self.num_elements() + 1];
49
50 let num_periods = self.num_elements() + 1;
51 ReductionPartitionToProductionPlanning {
52 target: ProductionPlanning::new(
53 num_periods,
54 demands,
55 capacities,
56 setup_costs,
57 production_costs,
58 inventory_costs,
59 half_floor,
60 ),
61 }
62 }
63}
64
65#[cfg(feature = "example-db")]
66pub(crate) fn canonical_rule_example_specs() -> Vec<crate::example_db::specs::RuleExampleSpec> {
67 use crate::export::SolutionPair;
68
69 vec![crate::example_db::specs::RuleExampleSpec {
70 id: "partition_to_production_planning",
71 build: || {
72 crate::example_db::specs::rule_example_with_witness::<_, ProductionPlanning>(
73 Partition::new(vec![3, 5, 2, 4, 6]),
74 SolutionPair {
75 source_config: vec![0, 0, 0, 1, 1],
76 target_config: vec![0, 0, 0, 4, 6, 0],
77 },
78 )
79 },
80 }]
81}
82
83#[cfg(test)]
84#[path = "../unit_tests/rules/partition_productionplanning.rs"]
85mod tests;