problemreductions/rules/
optimallineararrangement_consecutiveonesmatrixaugmentation.rs1use crate::models::algebraic::ConsecutiveOnesMatrixAugmentation;
14use crate::models::decision::Decision;
15use crate::models::graph::OptimalLinearArrangement;
16use crate::reduction;
17use crate::rules::traits::{ReduceTo, ReductionResult};
18use crate::topology::{Graph, SimpleGraph};
19
20#[derive(Debug, Clone)]
22enum ConstructionKind {
23 EdgelessYes { num_vertices: usize },
26 FixedNo { num_vertices: usize },
28 Incidence { num_vertices: usize },
30}
31
32#[derive(Debug, Clone)]
35pub struct ReductionOptimalLinearArrangementToConsecutiveOnesMatrixAugmentation {
36 target: ConsecutiveOnesMatrixAugmentation,
37 construction: ConstructionKind,
38}
39
40impl ReductionResult for ReductionOptimalLinearArrangementToConsecutiveOnesMatrixAugmentation {
41 type Source = Decision<OptimalLinearArrangement<SimpleGraph>>;
42 type Target = ConsecutiveOnesMatrixAugmentation;
43
44 fn target_problem(&self) -> &Self::Target {
45 &self.target
46 }
47
48 fn extract_solution(&self, target_solution: &[usize]) -> Vec<usize> {
49 match &self.construction {
50 ConstructionKind::EdgelessYes { num_vertices } => (0..*num_vertices).collect(),
53 ConstructionKind::FixedNo { num_vertices } => (0..*num_vertices).collect(),
56 ConstructionKind::Incidence { num_vertices } => {
57 let n = *num_vertices;
62 if target_solution.len() != n {
63 return (0..n).collect();
64 }
65 let mut arrangement = vec![0usize; n];
66 let mut seen = vec![false; n];
67 for (position, &vertex) in target_solution.iter().enumerate() {
68 if vertex >= n || seen[vertex] {
69 return (0..n).collect();
71 }
72 seen[vertex] = true;
73 arrangement[vertex] = position;
74 }
75 arrangement
76 }
77 }
78 }
79}
80
81fn no_sentinel() -> ConsecutiveOnesMatrixAugmentation {
85 ConsecutiveOnesMatrixAugmentation::new(
86 vec![
87 vec![true, true, false],
88 vec![false, true, true],
89 vec![true, false, true],
90 ],
91 0,
92 )
93}
94
95#[reduction(
96 overhead = {
97 num_rows = "num_edges",
98 num_cols = "num_vertices",
99 bound = "k - num_edges",
100 }
101)]
102impl ReduceTo<ConsecutiveOnesMatrixAugmentation>
103 for Decision<OptimalLinearArrangement<SimpleGraph>>
104{
105 type Result = ReductionOptimalLinearArrangementToConsecutiveOnesMatrixAugmentation;
106
107 fn reduce_to(&self) -> Self::Result {
108 let n = self.num_vertices();
109 let m = self.num_edges();
110 let k = self.k();
111
112 if m == 0 {
116 return ReductionOptimalLinearArrangementToConsecutiveOnesMatrixAugmentation {
117 target: ConsecutiveOnesMatrixAugmentation::new(vec![vec![false]], k as i64),
118 construction: ConstructionKind::EdgelessYes { num_vertices: n },
119 };
120 }
121
122 if k < m {
126 return ReductionOptimalLinearArrangementToConsecutiveOnesMatrixAugmentation {
127 target: no_sentinel(),
128 construction: ConstructionKind::FixedNo { num_vertices: n },
129 };
130 }
131
132 let mut matrix = vec![vec![false; n]; m];
134 for (edge_idx, (u, v)) in self.inner().graph().edges().into_iter().enumerate() {
135 matrix[edge_idx][u] = true;
136 matrix[edge_idx][v] = true;
137 }
138 let bound = (k - m) as i64;
139
140 ReductionOptimalLinearArrangementToConsecutiveOnesMatrixAugmentation {
141 target: ConsecutiveOnesMatrixAugmentation::new(matrix, bound),
142 construction: ConstructionKind::Incidence { num_vertices: n },
143 }
144 }
145}
146
147#[cfg(feature = "example-db")]
148pub(crate) fn canonical_rule_example_specs() -> Vec<crate::example_db::specs::RuleExampleSpec> {
149 use crate::export::SolutionPair;
150
151 vec![crate::example_db::specs::RuleExampleSpec {
152 id: "optimallineararrangement_to_consecutiveonesmatrixaugmentation",
153 build: || {
154 use crate::example_db::specs::assemble_rule_example;
155
156 let source = Decision::new(
160 OptimalLinearArrangement::new(SimpleGraph::new(
161 6,
162 vec![(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (0, 3), (2, 5)],
163 )),
164 11,
165 );
166 let reduction = ReduceTo::<ConsecutiveOnesMatrixAugmentation>::reduce_to(&source);
167 let source_config = vec![0, 1, 2, 3, 4, 5];
169 let target_config = vec![0, 1, 2, 3, 4, 5];
170 assemble_rule_example(
171 &source,
172 reduction.target_problem(),
173 vec![SolutionPair {
174 source_config,
175 target_config,
176 }],
177 )
178 },
179 }]
180}
181
182#[cfg(test)]
183#[path = "../unit_tests/rules/optimallineararrangement_consecutiveonesmatrixaugmentation.rs"]
184mod tests;