problemreductions/rules/
ksatisfiability_minimumvertexcover.rs1use crate::models::formula::KSatisfiability;
15use crate::models::graph::MinimumVertexCover;
16use crate::reduction;
17use crate::rules::traits::{ReduceTo, ReductionResult};
18use crate::topology::SimpleGraph;
19use crate::variant::K3;
20
21#[derive(Debug, Clone)]
23pub struct Reduction3SATToMVC {
24 target: MinimumVertexCover<SimpleGraph, i64>,
25 source_num_vars: usize,
26}
27
28impl ReductionResult for Reduction3SATToMVC {
29 type Source = KSatisfiability<K3>;
30 type Target = MinimumVertexCover<SimpleGraph, i64>;
31
32 fn target_problem(&self) -> &Self::Target {
33 &self.target
34 }
35
36 fn extract_solution(
44 &self,
45 target_solution: &<Self::Target as crate::traits::Problem>::Solution,
46 ) -> crate::rules::ExtractionResult<<Self::Source as crate::traits::Problem>::Solution> {
47 crate::rules::traits::validate_target_solution(self.target_problem(), target_solution)?;
48
49 Ok({
50 (0..self.source_num_vars)
51 .map(|i| {
52 target_solution[2 * i]
54 })
55 .collect()
56 })
57 }
58}
59
60#[reduction(
61 transform = exact {
62 num_vertices = "2 * num_vars + 3 * num_clauses",
63 num_edges = "num_vars + 6 * num_clauses",
64 }
65)]
66impl ReduceTo<MinimumVertexCover<SimpleGraph, i64>> for KSatisfiability<K3> {
67 type Result = Reduction3SATToMVC;
68
69 fn reduce_to(&self) -> Result<Self::Result, crate::rules::ReductionError> {
70 let n = self.num_vars();
71 let m = self.num_clauses();
72 let total_vertices = 2 * n + 3 * m;
73 let mut edges: Vec<(usize, usize)> = Vec::with_capacity(n + 6 * m);
74
75 for i in 0..n {
78 edges.push((2 * i, 2 * i + 1));
79 }
80
81 for (j, clause) in self.clauses().iter().enumerate() {
84 let base = 2 * n + 3 * j;
85
86 edges.push((base, base + 1));
88 edges.push((base + 1, base + 2));
89 edges.push((base, base + 2));
90
91 for (k, &lit) in clause.literals.iter().enumerate() {
93 let var_idx = lit.unsigned_abs() as usize - 1; let literal_vertex = if lit > 0 {
95 2 * var_idx } else {
97 2 * var_idx + 1 };
99 edges.push((base + k, literal_vertex));
100 }
101 }
102
103 let graph = SimpleGraph::new(total_vertices, edges);
104 let weights = vec![1i64; total_vertices];
105 let target = MinimumVertexCover::new(graph, weights);
106
107 Ok(Reduction3SATToMVC {
108 target,
109 source_num_vars: n,
110 })
111 }
112}
113
114#[cfg(feature = "example-db")]
115pub(crate) fn canonical_rule_example_specs() -> Vec<crate::example_db::specs::RuleExampleSpec> {
116 use crate::export::SolutionPair;
117 use crate::models::formula::CNFClause;
118
119 vec![crate::example_db::specs::RuleExampleSpec {
120 id: "ksatisfiability_to_minimumvertexcover",
121 build: || {
122 let source = KSatisfiability::<K3>::new(
123 3,
124 vec![
125 CNFClause::new(vec![1, 2, 3]),
126 CNFClause::new(vec![-1, -2, 3]),
127 ],
128 );
129 crate::example_db::specs::rule_example_with_witness::<
130 _,
131 MinimumVertexCover<SimpleGraph, i64>,
132 >(
133 source,
134 SolutionPair {
135 source_config: serde_json::json!(vec![false, false, true]),
137 target_config: serde_json::json!(vec![
145 false, true, false, true, true, false, true, true, false, true, true, false
146 ]),
147 },
148 )
149 },
150 }]
151}
152
153#[cfg(test)]
154#[path = "../unit_tests/rules/ksatisfiability_minimumvertexcover.rs"]
155mod tests;