problemreductions/rules/
hamiltoniancircuit_bottlenecktravelingsalesman.rs1use crate::models::graph::{BottleneckTravelingSalesman, HamiltonianCircuit};
8use crate::reduction;
9use crate::rules::traits::{ReduceTo, ReductionResult};
10use crate::topology::{Graph, SimpleGraph};
11
12#[derive(Debug, Clone)]
14pub struct ReductionHamiltonianCircuitToBottleneckTravelingSalesman {
15 target: BottleneckTravelingSalesman,
16}
17
18impl ReductionResult for ReductionHamiltonianCircuitToBottleneckTravelingSalesman {
19 type Source = HamiltonianCircuit<SimpleGraph>;
20 type Target = BottleneckTravelingSalesman;
21
22 fn target_problem(&self) -> &Self::Target {
23 &self.target
24 }
25
26 fn extract_solution(&self, target_solution: &[usize]) -> Vec<usize> {
27 crate::rules::graph_helpers::edges_to_cycle_order(self.target.graph(), target_solution)
28 }
29}
30
31#[reduction(
32 overhead = {
33 num_vertices = "num_vertices",
34 num_edges = "num_vertices * (num_vertices - 1) / 2",
35 }
36)]
37impl ReduceTo<BottleneckTravelingSalesman> for HamiltonianCircuit<SimpleGraph> {
38 type Result = ReductionHamiltonianCircuitToBottleneckTravelingSalesman;
39
40 fn reduce_to(&self) -> Self::Result {
41 let num_vertices = self.num_vertices();
42 let target_graph = SimpleGraph::complete(num_vertices);
43 let weights = target_graph
44 .edges()
45 .into_iter()
46 .map(|(u, v)| if self.graph().has_edge(u, v) { 1 } else { 2 })
47 .collect();
48 let target = BottleneckTravelingSalesman::new(target_graph, weights);
49
50 ReductionHamiltonianCircuitToBottleneckTravelingSalesman { target }
51 }
52}
53
54#[cfg(feature = "example-db")]
55pub(crate) fn canonical_rule_example_specs() -> Vec<crate::example_db::specs::RuleExampleSpec> {
56 use crate::export::SolutionPair;
57
58 vec![crate::example_db::specs::RuleExampleSpec {
59 id: "hamiltoniancircuit_to_bottlenecktravelingsalesman",
60 build: || {
61 let source = HamiltonianCircuit::new(SimpleGraph::cycle(4));
62 crate::example_db::specs::rule_example_with_witness::<_, BottleneckTravelingSalesman>(
63 source,
64 SolutionPair {
65 source_config: vec![0, 1, 2, 3],
66 target_config: vec![1, 0, 1, 1, 0, 1],
67 },
68 )
69 },
70 }]
71}
72
73#[cfg(test)]
74#[path = "../unit_tests/rules/hamiltoniancircuit_bottlenecktravelingsalesman.rs"]
75mod tests;