problemreductions/rules/
partition_knapsack.rs1use crate::models::misc::{Knapsack, Partition};
4use crate::reduction;
5use crate::rules::traits::{ReduceTo, ReductionResult};
6
7#[derive(Debug, Clone)]
9pub struct ReductionPartitionToKnapsack {
10 target: Knapsack,
11}
12
13impl ReductionResult for ReductionPartitionToKnapsack {
14 type Source = Partition;
15 type Target = Knapsack;
16
17 fn target_problem(&self) -> &Self::Target {
18 &self.target
19 }
20
21 fn extract_solution(&self, target_solution: &[usize]) -> Vec<usize> {
22 target_solution.to_vec()
23 }
24}
25
26fn partition_size_to_i64(value: u64) -> i64 {
27 i64::try_from(value)
28 .expect("Partition -> Knapsack requires all sizes and total_sum / 2 to fit in i64")
29}
30
31#[reduction(overhead = {
32 num_items = "num_elements",
33})]
34impl ReduceTo<Knapsack> for Partition {
35 type Result = ReductionPartitionToKnapsack;
36
37 fn reduce_to(&self) -> Self::Result {
38 let weights: Vec<i64> = self
39 .sizes()
40 .iter()
41 .copied()
42 .map(partition_size_to_i64)
43 .collect();
44 let values = weights.clone();
45 let capacity = partition_size_to_i64(self.total_sum() / 2);
46
47 ReductionPartitionToKnapsack {
48 target: Knapsack::new(weights, values, capacity),
49 }
50 }
51}
52
53#[cfg(feature = "example-db")]
54pub(crate) fn canonical_rule_example_specs() -> Vec<crate::example_db::specs::RuleExampleSpec> {
55 use crate::export::SolutionPair;
56
57 vec![crate::example_db::specs::RuleExampleSpec {
58 id: "partition_to_knapsack",
59 build: || {
60 crate::example_db::specs::rule_example_with_witness::<_, Knapsack>(
61 Partition::new(vec![3, 1, 1, 2, 2, 1]),
62 SolutionPair {
63 source_config: vec![1, 0, 0, 1, 0, 0],
64 target_config: vec![1, 0, 0, 1, 0, 0],
65 },
66 )
67 },
68 }]
69}
70
71#[cfg(test)]
72#[path = "../unit_tests/rules/partition_knapsack.rs"]
73mod tests;