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(&self, target_solution: &[usize]) -> Vec<usize> {
25 let mut cover = vec![1; self.num_vertices];
26 for &symbol in target_solution {
27 if symbol >= self.num_vertices {
28 break;
29 }
30 cover[symbol] = 0;
31 }
32 cover
33 }
34}
35
36#[reduction(
37 overhead = {
38 alphabet_size = "num_vertices",
39 num_strings = "num_edges + 1",
40 max_length = "num_vertices",
41 total_length = "num_vertices + 2 * num_edges * num_vertices - 2 * num_edges",
42 }
43)]
44impl ReduceTo<LongestCommonSubsequence> for MinimumVertexCover<SimpleGraph, One> {
45 type Result = ReductionVCToLCS;
46
47 fn reduce_to(&self) -> Self::Result {
48 let num_vertices = self.graph().num_vertices();
49 let mut strings = Vec::with_capacity(self.graph().num_edges() + 1);
50 strings.push((0..num_vertices).collect());
51
52 for (left, right) in self.graph().edges() {
53 let (u, v) = if left < right {
56 (left, right)
57 } else {
58 (right, left)
59 };
60 let mut edge_string = string_without_vertex(num_vertices, u);
61 edge_string.extend(string_without_vertex(num_vertices, v));
62 strings.push(edge_string);
63 }
64
65 let target = LongestCommonSubsequence::new(num_vertices, strings);
66 ReductionVCToLCS {
67 target,
68 num_vertices,
69 }
70 }
71}
72
73fn string_without_vertex(num_vertices: usize, omitted: usize) -> Vec<usize> {
74 (0..num_vertices)
75 .filter(|&vertex| vertex != omitted)
76 .collect()
77}
78
79#[cfg(feature = "example-db")]
80pub(crate) fn canonical_rule_example_specs() -> Vec<crate::example_db::specs::RuleExampleSpec> {
81 use crate::export::SolutionPair;
82
83 vec![crate::example_db::specs::RuleExampleSpec {
84 id: "minimumvertexcover_to_longestcommonsubsequence",
85 build: || {
86 let source = MinimumVertexCover::new(
87 SimpleGraph::new(4, vec![(0, 1), (1, 2), (2, 3)]),
88 vec![One; 4],
89 );
90 crate::example_db::specs::rule_example_with_witness::<_, LongestCommonSubsequence>(
91 source,
92 SolutionPair {
93 source_config: vec![0, 1, 1, 0],
94 target_config: vec![0, 3, 4, 4],
95 },
96 )
97 },
98 }]
99}
100
101#[cfg(test)]
102#[path = "../unit_tests/rules/minimumvertexcover_longestcommonsubsequence.rs"]
103mod tests;