problemreductions/rules/
minimumvertexcover_longestcommonsubsequence.rs1use crate::models::graph::MinimumVertexCover;
4use crate::models::misc::LongestCommonSubsequence;
5use crate::reduction;
6use crate::rules::traits::{ReduceTo, ReductionResult};
7use crate::topology::{Graph, SimpleGraph};
8use crate::types::One;
9
10#[derive(Debug, Clone)]
11pub struct ReductionVCToLCS {
12 target: LongestCommonSubsequence,
13 num_vertices: usize,
14}
15
16impl ReductionResult for ReductionVCToLCS {
17 type Source = MinimumVertexCover<SimpleGraph, One>;
18 type Target = LongestCommonSubsequence;
19
20 fn target_problem(&self) -> &Self::Target {
21 &self.target
22 }
23
24 fn extract_solution(
25 &self,
26 target_solution: &<Self::Target as crate::traits::Problem>::Solution,
27 ) -> crate::rules::ExtractionResult<<Self::Source as crate::traits::Problem>::Solution> {
28 crate::rules::traits::validate_target_solution(self.target_problem(), target_solution)?;
29
30 Ok({
31 let mut cover = vec![true; self.num_vertices];
32 for &symbol in target_solution {
33 let Some(symbol) = symbol else { break };
34 cover[symbol] = false;
35 }
36 cover
37 })
38 }
39}
40
41#[reduction(
42 transform = exact {
43 alphabet_size = "num_vertices",
44 num_strings = "num_edges + 1",
45 max_length = "num_vertices",
46 total_length = "num_vertices + 2 * num_edges * num_vertices - 2 * num_edges",
47 },
48 unavailable = {
49 cross_frequency_product = "the exact target parameter is not represented by this reduction's symbolic transform",
50 num_transitions = "the exact target parameter is not represented by this reduction's symbolic transform",
51 sum_triangular_lengths = "the exact target parameter is not represented by this reduction's symbolic transform",
52 }
53)]
54impl ReduceTo<LongestCommonSubsequence> for MinimumVertexCover<SimpleGraph, One> {
55 type Result = ReductionVCToLCS;
56
57 fn reduce_to(&self) -> Result<Self::Result, crate::rules::ReductionError> {
58 let num_vertices = self.graph().num_vertices();
59 let mut strings = Vec::with_capacity(self.graph().num_edges() + 1);
60 strings.push((0..num_vertices).collect());
61
62 for (left, right) in self.graph().edges() {
63 let (u, v) = if left < right {
66 (left, right)
67 } else {
68 (right, left)
69 };
70 let mut edge_string = string_without_vertex(num_vertices, u);
71 edge_string.extend(string_without_vertex(num_vertices, v));
72 strings.push(edge_string);
73 }
74
75 let target = LongestCommonSubsequence::new(num_vertices, strings);
76 Ok(ReductionVCToLCS {
77 target,
78 num_vertices,
79 })
80 }
81}
82
83fn string_without_vertex(num_vertices: usize, omitted: usize) -> Vec<usize> {
84 (0..num_vertices)
85 .filter(|&vertex| vertex != omitted)
86 .collect()
87}
88
89#[cfg(feature = "example-db")]
90pub(crate) fn canonical_rule_example_specs() -> Vec<crate::example_db::specs::RuleExampleSpec> {
91 use crate::export::SolutionPair;
92
93 vec![crate::example_db::specs::RuleExampleSpec {
94 id: "minimumvertexcover_to_longestcommonsubsequence",
95 build: || {
96 let source = MinimumVertexCover::new(
97 SimpleGraph::new(4, vec![(0, 1), (1, 2), (2, 3)]),
98 vec![One; 4],
99 );
100 crate::example_db::specs::rule_example_with_witness::<_, LongestCommonSubsequence>(
101 source,
102 SolutionPair {
103 source_config: serde_json::json!(vec![false, true, true, false]),
104 target_config: serde_json::json!(vec![Some(0), Some(3), None, None]),
105 },
106 )
107 },
108 }]
109}
110
111#[cfg(test)]
112#[path = "../unit_tests/rules/minimumvertexcover_longestcommonsubsequence.rs"]
113mod tests;