1use crate::models::graph::{MaximumIndependentSet, MinimumVertexCover};
6use crate::reduction;
7use crate::rules::traits::{ReduceTo, ReductionResult};
8use crate::topology::{Graph, SimpleGraph};
9use crate::types::WeightElement;
10
11#[derive(Debug, Clone)]
13pub struct ReductionISToVC<W> {
14 target: MinimumVertexCover<SimpleGraph, W>,
15}
16
17impl<W> ReductionResult for ReductionISToVC<W>
18where
19 W: WeightElement + crate::variant::VariantParam,
20{
21 type Source = MaximumIndependentSet<SimpleGraph, W>;
22 type Target = MinimumVertexCover<SimpleGraph, W>;
23
24 fn target_problem(&self) -> &Self::Target {
25 &self.target
26 }
27
28 fn extract_solution(&self, target_solution: &[usize]) -> Vec<usize> {
31 target_solution.iter().map(|&x| 1 - x).collect()
32 }
33}
34
35#[reduction(
36 overhead = {
37 num_vertices = "num_vertices",
38 num_edges = "num_edges",
39 }
40)]
41impl ReduceTo<MinimumVertexCover<SimpleGraph, i32>> for MaximumIndependentSet<SimpleGraph, i32> {
42 type Result = ReductionISToVC<i32>;
43
44 fn reduce_to(&self) -> Self::Result {
45 let target = MinimumVertexCover::new(
46 SimpleGraph::new(self.graph().num_vertices(), self.graph().edges()),
47 self.weights().to_vec(),
48 );
49 ReductionISToVC { target }
50 }
51}
52
53#[derive(Debug, Clone)]
55pub struct ReductionVCToIS<W> {
56 target: MaximumIndependentSet<SimpleGraph, W>,
57}
58
59impl<W> ReductionResult for ReductionVCToIS<W>
60where
61 W: WeightElement + crate::variant::VariantParam,
62{
63 type Source = MinimumVertexCover<SimpleGraph, W>;
64 type Target = MaximumIndependentSet<SimpleGraph, W>;
65
66 fn target_problem(&self) -> &Self::Target {
67 &self.target
68 }
69
70 fn extract_solution(&self, target_solution: &[usize]) -> Vec<usize> {
72 target_solution.iter().map(|&x| 1 - x).collect()
73 }
74}
75
76#[reduction(
77 overhead = {
78 num_vertices = "num_vertices",
79 num_edges = "num_edges",
80 }
81)]
82impl ReduceTo<MaximumIndependentSet<SimpleGraph, i32>> for MinimumVertexCover<SimpleGraph, i32> {
83 type Result = ReductionVCToIS<i32>;
84
85 fn reduce_to(&self) -> Self::Result {
86 let target = MaximumIndependentSet::new(
87 SimpleGraph::new(self.graph().num_vertices(), self.graph().edges()),
88 self.weights().to_vec(),
89 );
90 ReductionVCToIS { target }
91 }
92}
93
94#[cfg(feature = "example-db")]
95pub(crate) fn canonical_rule_example_specs() -> Vec<crate::example_db::specs::RuleExampleSpec> {
96 use crate::export::SolutionPair;
97
98 fn vc_petersen() -> MinimumVertexCover<SimpleGraph, i32> {
99 let (n, edges) = crate::topology::small_graphs::petersen();
100 MinimumVertexCover::new(SimpleGraph::new(n, edges), vec![1i32; 10])
101 }
102
103 fn mis_petersen() -> MaximumIndependentSet<SimpleGraph, i32> {
104 let (n, edges) = crate::topology::small_graphs::petersen();
105 MaximumIndependentSet::new(SimpleGraph::new(n, edges), vec![1i32; 10])
106 }
107
108 vec![
109 crate::example_db::specs::RuleExampleSpec {
110 id: "maximumindependentset_to_minimumvertexcover",
111 build: || {
112 crate::example_db::specs::rule_example_with_witness::<
113 _,
114 MinimumVertexCover<SimpleGraph, i32>,
115 >(
116 mis_petersen(),
117 SolutionPair {
118 source_config: vec![1, 0, 0, 1, 0, 0, 1, 1, 0, 0],
119 target_config: vec![0, 1, 1, 0, 1, 1, 0, 0, 1, 1],
120 },
121 )
122 },
123 },
124 crate::example_db::specs::RuleExampleSpec {
125 id: "minimumvertexcover_to_maximumindependentset",
126 build: || {
127 crate::example_db::specs::rule_example_with_witness::<
128 _,
129 MaximumIndependentSet<SimpleGraph, i32>,
130 >(
131 vc_petersen(),
132 SolutionPair {
133 source_config: vec![0, 1, 1, 0, 1, 1, 0, 0, 1, 1],
134 target_config: vec![1, 0, 0, 1, 0, 0, 1, 1, 0, 0],
135 },
136 )
137 },
138 },
139 ]
140}
141
142#[cfg(test)]
143#[path = "../unit_tests/rules/minimumvertexcover_maximumindependentset.rs"]
144mod tests;