problemreductions/rules/
paintshop_qubo.rs1use crate::models::algebraic::QUBO;
11use crate::models::misc::PaintShop;
12use crate::reduction;
13use crate::rules::traits::{ReduceTo, ReductionResult};
14
15#[derive(Debug, Clone)]
17pub struct ReductionPaintShopToQUBO {
18 target: QUBO<f64>,
19}
20
21impl ReductionResult for ReductionPaintShopToQUBO {
22 type Source = PaintShop;
23 type Target = QUBO<f64>;
24
25 fn target_problem(&self) -> &Self::Target {
26 &self.target
27 }
28
29 fn extract_solution(&self, target_solution: &[usize]) -> Vec<usize> {
32 target_solution.to_vec()
33 }
34}
35
36#[reduction(overhead = { num_vars = "num_cars" })]
37impl ReduceTo<QUBO<f64>> for PaintShop {
38 type Result = ReductionPaintShopToQUBO;
39
40 fn reduce_to(&self) -> Self::Result {
41 let n = self.num_cars();
42 let seq = self.sequence_indices();
43 let is_first = self.is_first();
44 let seq_len = seq.len();
45
46 let mut matrix = vec![vec![0.0f64; n]; n];
47
48 for pos in 0..seq_len.saturating_sub(1) {
50 let a = seq[pos];
51 let b = seq[pos + 1];
52
53 if a == b {
55 continue;
56 }
57
58 let parity_a = is_first[pos];
59 let parity_b = is_first[pos + 1];
60
61 let (lo, hi) = if a < b { (a, b) } else { (b, a) };
63
64 if parity_a == parity_b {
65 matrix[a][a] += 1.0;
68 matrix[b][b] += 1.0;
69 matrix[lo][hi] -= 2.0;
70 } else {
71 matrix[a][a] -= 1.0;
74 matrix[b][b] -= 1.0;
75 matrix[lo][hi] += 2.0;
76 }
77 }
78
79 ReductionPaintShopToQUBO {
80 target: QUBO::from_matrix(matrix),
81 }
82 }
83}
84
85#[cfg(feature = "example-db")]
86pub(crate) fn canonical_rule_example_specs() -> Vec<crate::example_db::specs::RuleExampleSpec> {
87 use crate::export::SolutionPair;
88
89 vec![crate::example_db::specs::RuleExampleSpec {
90 id: "paintshop_to_qubo",
91 build: || {
92 let source = PaintShop::new(vec!["A", "B", "C", "A", "D", "B", "D", "C"]);
94 crate::example_db::specs::rule_example_with_witness::<_, QUBO<f64>>(
95 source,
96 SolutionPair {
97 source_config: vec![1, 0, 0, 0],
98 target_config: vec![1, 0, 0, 0],
99 },
100 )
101 },
102 }]
103}
104
105#[cfg(test)]
106#[path = "../unit_tests/rules/paintshop_qubo.rs"]
107mod tests;