problemreductions/rules/
hamiltoniancircuit_stackercrane.rs1use crate::models::graph::HamiltonianCircuit;
16use crate::models::misc::StackerCrane;
17use crate::reduction;
18use crate::rules::traits::{ReduceTo, ReductionResult};
19use crate::topology::{Graph, SimpleGraph};
20
21#[derive(Debug, Clone)]
23pub struct ReductionHamiltonianCircuitToStackerCrane {
24 target: StackerCrane,
25}
26
27impl ReductionResult for ReductionHamiltonianCircuitToStackerCrane {
28 type Source = HamiltonianCircuit<SimpleGraph>;
29 type Target = StackerCrane;
30
31 fn target_problem(&self) -> &Self::Target {
32 &self.target
33 }
34
35 fn extract_solution(&self, target_solution: &[usize]) -> Vec<usize> {
36 target_solution.to_vec()
40 }
41}
42
43#[reduction(
44 overhead = {
45 num_vertices = "2 * num_vertices",
46 num_arcs = "num_vertices",
47 num_edges = "2 * num_edges",
48 }
49)]
50impl ReduceTo<StackerCrane> for HamiltonianCircuit<SimpleGraph> {
51 type Result = ReductionHamiltonianCircuitToStackerCrane;
52
53 fn reduce_to(&self) -> Self::Result {
54 let n = self.num_vertices();
55
56 let target_num_vertices = 2 * n;
58
59 let arcs: Vec<(usize, usize)> = (0..n).map(|i| (2 * i, 2 * i + 1)).collect();
61 let arc_lengths: Vec<i32> = vec![1; n];
62
63 let mut edges = Vec::new();
69 let mut edge_lengths = Vec::new();
70 for (u, v) in self.graph().edges() {
71 edges.push((2 * u + 1, 2 * v));
72 edge_lengths.push(1);
73 edges.push((2 * v + 1, 2 * u));
74 edge_lengths.push(1);
75 }
76
77 let target = StackerCrane::new(target_num_vertices, arcs, edges, arc_lengths, edge_lengths);
78
79 ReductionHamiltonianCircuitToStackerCrane { target }
80 }
81}
82
83#[cfg(feature = "example-db")]
84pub(crate) fn canonical_rule_example_specs() -> Vec<crate::example_db::specs::RuleExampleSpec> {
85 use crate::export::SolutionPair;
86
87 vec![crate::example_db::specs::RuleExampleSpec {
88 id: "hamiltoniancircuit_to_stackercrane",
89 build: || {
90 let source = HamiltonianCircuit::new(SimpleGraph::cycle(4));
91 crate::example_db::specs::rule_example_with_witness::<_, StackerCrane>(
92 source,
93 SolutionPair {
94 source_config: vec![0, 1, 2, 3],
95 target_config: vec![0, 1, 2, 3],
96 },
97 )
98 },
99 }]
100}
101
102#[cfg(test)]
103#[path = "../unit_tests/rules/hamiltoniancircuit_stackercrane.rs"]
104mod tests;