problemreductions/rules/
optimallineararrangement_consecutiveonesmatrixaugmentation.rs1use crate::models::algebraic::ConsecutiveOnesMatrixAugmentation;
8use crate::models::decision::Decision;
9use crate::models::graph::OptimalLinearArrangement;
10use crate::reduction;
11use crate::rules::traits::{ReduceTo, ReductionResult};
12use crate::topology::{Graph, SimpleGraph};
13
14#[derive(Debug, Clone)]
17pub struct ReductionOptimalLinearArrangementToConsecutiveOnesMatrixAugmentation {
18 target: ConsecutiveOnesMatrixAugmentation,
19}
20
21impl ReductionResult for ReductionOptimalLinearArrangementToConsecutiveOnesMatrixAugmentation {
22 type Source = Decision<OptimalLinearArrangement<SimpleGraph>>;
23 type Target = ConsecutiveOnesMatrixAugmentation;
24
25 fn target_problem(&self) -> &Self::Target {
26 &self.target
27 }
28
29 fn extract_solution(
30 &self,
31 target_solution: &<Self::Target as crate::traits::Problem>::Solution,
32 ) -> crate::rules::ExtractionResult<<Self::Source as crate::traits::Problem>::Solution> {
33 crate::rules::traits::validate_target_witness(
34 self.target_problem(),
35 target_solution,
36 |value| value.0,
37 "target column order is not a satisfying augmentation certificate",
38 )?;
39 let mut arrangement = vec![0; target_solution.len()];
43 for (position, &vertex) in target_solution.iter().enumerate() {
44 arrangement[vertex] = position;
45 }
46 Ok(arrangement)
47 }
48}
49
50#[crate::aggregate_reduction(identity)]
51impl crate::rules::AggregateReductionResult
52 for ReductionOptimalLinearArrangementToConsecutiveOnesMatrixAugmentation
53{
54}
55
56#[reduction(
57 transform = upper_bound {
58 num_rows = "num_edges + 3",
59 num_cols = "num_vertices + 3",
60 }
61)]
62impl ReduceTo<ConsecutiveOnesMatrixAugmentation>
63 for Decision<OptimalLinearArrangement<SimpleGraph>>
64{
65 type Result = ReductionOptimalLinearArrangementToConsecutiveOnesMatrixAugmentation;
66
67 fn reduce_to(&self) -> Result<Self::Result, crate::rules::ReductionError> {
68 let n = self.num_vertices();
69 let edges = self.inner().graph().edges();
70 let non_loops = <Self as ReduceTo<ConsecutiveOnesMatrixAugmentation>>::exact_i64(
71 edges.iter().filter(|(u, v)| u != v).count(),
72 "converting the number of non-loop edges to i64",
73 )?;
74 let k = *self.bound();
75 let (matrix, bound) = if k < non_loops {
76 (
79 vec![
80 vec![true, true, false],
81 vec![false, true, true],
82 vec![true, false, true],
83 ],
84 0,
85 )
86 } else {
87 let mut matrix = vec![vec![false; n]; edges.len().max(1)];
90 for (row, (u, v)) in edges.into_iter().enumerate() {
91 matrix[row][u] = true;
92 matrix[row][v] = true;
93 }
94 (matrix, k - non_loops)
96 };
97 Ok(
98 ReductionOptimalLinearArrangementToConsecutiveOnesMatrixAugmentation {
99 target: ConsecutiveOnesMatrixAugmentation::try_new(matrix, bound).map_err(
100 <Self as ReduceTo<ConsecutiveOnesMatrixAugmentation>>::target_construction,
101 )?,
102 },
103 )
104 }
105}
106
107#[cfg(feature = "example-db")]
108pub(crate) fn canonical_rule_example_specs() -> Vec<crate::example_db::specs::RuleExampleSpec> {
109 use crate::export::SolutionPair;
110
111 vec![crate::example_db::specs::RuleExampleSpec {
112 id: "optimallineararrangement_to_consecutiveonesmatrixaugmentation",
113 build: || {
114 use crate::example_db::specs::assemble_rule_example;
115
116 let source = Decision::new(
120 OptimalLinearArrangement::new(SimpleGraph::new(
121 6,
122 vec![(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (0, 3), (2, 5)],
123 )),
124 11,
125 );
126 let reduction = ReduceTo::<ConsecutiveOnesMatrixAugmentation>::reduce_to(&source)
127 .expect("reduction should succeed");
128 let source_config = vec![0, 1, 2, 3, 4, 5];
130 let target_config = vec![0, 1, 2, 3, 4, 5];
131 assemble_rule_example(
132 &source,
133 reduction.target_problem(),
134 vec![SolutionPair {
135 source_config: serde_json::to_value(source_config)
136 .expect("solution serialization must succeed"),
137 target_config: serde_json::to_value(target_config)
138 .expect("solution serialization must succeed"),
139 }],
140 )
141 },
142 }]
143}
144
145#[cfg(test)]
146#[path = "../unit_tests/rules/optimallineararrangement_consecutiveonesmatrixaugmentation.rs"]
147mod tests;