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(
31 &self,
32 target_solution: &<Self::Target as crate::traits::Problem>::Solution,
33 ) -> crate::rules::ExtractionResult<<Self::Source as crate::traits::Problem>::Solution> {
34 crate::rules::traits::validate_target_solution(self.target_problem(), target_solution)?;
35
36 Ok(target_solution.iter().map(|&x| !x).collect())
37 }
38}
39
40#[reduction(
41 transform = exact {
42 num_vertices = "num_vertices",
43 num_edges = "num_edges",
44 }
45)]
46impl ReduceTo<MinimumVertexCover<SimpleGraph, i64>> for MaximumIndependentSet<SimpleGraph, i64> {
47 type Result = ReductionISToVC<i64>;
48
49 fn reduce_to(&self) -> Result<Self::Result, crate::rules::ReductionError> {
50 let target = MinimumVertexCover::new(
51 SimpleGraph::new(self.graph().num_vertices(), self.graph().edges()),
52 self.weights().to_vec(),
53 );
54 Ok(ReductionISToVC { target })
55 }
56}
57
58#[derive(Debug, Clone)]
60pub struct ReductionVCToIS<W> {
61 target: MaximumIndependentSet<SimpleGraph, W>,
62}
63
64impl<W> ReductionResult for ReductionVCToIS<W>
65where
66 W: WeightElement + crate::variant::VariantParam,
67{
68 type Source = MinimumVertexCover<SimpleGraph, W>;
69 type Target = MaximumIndependentSet<SimpleGraph, W>;
70
71 fn target_problem(&self) -> &Self::Target {
72 &self.target
73 }
74
75 fn extract_solution(
77 &self,
78 target_solution: &<Self::Target as crate::traits::Problem>::Solution,
79 ) -> crate::rules::ExtractionResult<<Self::Source as crate::traits::Problem>::Solution> {
80 crate::rules::traits::validate_target_solution(self.target_problem(), target_solution)?;
81
82 Ok(target_solution.iter().map(|&x| !x).collect())
83 }
84}
85
86#[reduction(
87 transform = exact {
88 num_vertices = "num_vertices",
89 num_edges = "num_edges",
90 }
91)]
92impl ReduceTo<MaximumIndependentSet<SimpleGraph, i64>> for MinimumVertexCover<SimpleGraph, i64> {
93 type Result = ReductionVCToIS<i64>;
94
95 fn reduce_to(&self) -> Result<Self::Result, crate::rules::ReductionError> {
96 let target = MaximumIndependentSet::new(
97 SimpleGraph::new(self.graph().num_vertices(), self.graph().edges()),
98 self.weights().to_vec(),
99 );
100 Ok(ReductionVCToIS { target })
101 }
102}
103
104#[cfg(feature = "example-db")]
105pub(crate) fn canonical_rule_example_specs() -> Vec<crate::example_db::specs::RuleExampleSpec> {
106 use crate::export::SolutionPair;
107
108 fn vc_petersen() -> MinimumVertexCover<SimpleGraph, i64> {
109 let (n, edges) = crate::topology::small_graphs::petersen();
110 MinimumVertexCover::new(SimpleGraph::new(n, edges), vec![1i64; 10])
111 }
112
113 fn mis_petersen() -> MaximumIndependentSet<SimpleGraph, i64> {
114 let (n, edges) = crate::topology::small_graphs::petersen();
115 MaximumIndependentSet::new(SimpleGraph::new(n, edges), vec![1i64; 10])
116 }
117
118 vec![
119 crate::example_db::specs::RuleExampleSpec {
120 id: "maximumindependentset_to_minimumvertexcover",
121 build: || {
122 crate::example_db::specs::rule_example_with_witness::<
123 _,
124 MinimumVertexCover<SimpleGraph, i64>,
125 >(
126 mis_petersen(),
127 SolutionPair {
128 source_config: serde_json::json!(vec![
129 true, false, false, true, false, false, true, true, false, false
130 ]),
131 target_config: serde_json::json!(vec![
132 false, true, true, false, true, true, false, false, true, true
133 ]),
134 },
135 )
136 },
137 },
138 crate::example_db::specs::RuleExampleSpec {
139 id: "minimumvertexcover_to_maximumindependentset",
140 build: || {
141 crate::example_db::specs::rule_example_with_witness::<
142 _,
143 MaximumIndependentSet<SimpleGraph, i64>,
144 >(
145 vc_petersen(),
146 SolutionPair {
147 source_config: serde_json::json!(vec![
148 false, true, true, false, true, true, false, false, true, true
149 ]),
150 target_config: serde_json::json!(vec![
151 true, false, false, true, false, false, true, true, false, false
152 ]),
153 },
154 )
155 },
156 },
157 ]
158}
159
160#[cfg(test)]
161#[path = "../unit_tests/rules/minimumvertexcover_maximumindependentset.rs"]
162mod tests;