diff --git a/.gitignore b/.gitignore index fe44c22..aa5795f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ */target */flamegraph.svg */perf.data* -*/*.out diff --git a/vertex_cover/src/main.rs b/vertex_cover/src/main.rs index aec5c03..fc75d3c 100644 --- a/vertex_cover/src/main.rs +++ b/vertex_cover/src/main.rs @@ -135,6 +135,11 @@ fn vertex_cover(graph: &Graph, k: u16, method: Method) -> Option> { owned::reduction(&mut g, k) } + Method::Reduction2 => { + let mut g = owned::Graph::new(graph); + + owned::reduction2(&mut g, k) + } } } @@ -144,6 +149,7 @@ enum Method { Vertex, OwnedVertex, Reduction, + Reduction2, } #[derive(Debug, Parser)] diff --git a/vertex_cover/src/owned.rs b/vertex_cover/src/owned.rs index 5661b8f..1171e0c 100644 --- a/vertex_cover/src/owned.rs +++ b/vertex_cover/src/owned.rs @@ -96,6 +96,11 @@ impl Graph { fn get_edge(&self, v: u16) -> Option { self.get_edges(v).next() } + + fn get_degree(&self, v: u16) -> u16 { + let i = self.index[v as usize]; + self.vertices[i as usize].edges.len() as u16 + } } pub fn binary_vertex(graph: &mut Graph, k: u16) -> Option> { @@ -222,3 +227,153 @@ pub fn reduction(graph: &mut Graph, k: u16) -> Option> { unreachable!() } } + +pub fn reduction2(graph: &mut Graph, k: u16) -> Option> { + if let Some(vertex) = graph.get_vertex_with_degree(0) { + graph.remove_vertex(vertex); + + let r = reduction2(graph, k); + + let _ = graph.reinsert_vertices(1); + + r + } else if k == 0 { + if graph.is_empty() { + Some(Vec::new()) + } else { + None + } + } else if let Some(vertex) = graph.get_vertex_with_degree(1) { + let neighbor = graph.get_edge(vertex).unwrap(); + + if k < 1 { + return None; + } + + graph.remove_vertex(neighbor); + let mut r = reduction2(graph, k - 1); + + let i = graph.reinsert_vertices(1); + if let Some(r) = &mut r { + r.extend(i.map(|v| v.name)); + } + + r + } else if let Some(vertex) = graph.get_vertex_with_degree(2) { + let (a, b) = { + let mut i = graph.get_edges(vertex); + (i.next().unwrap(), i.next().unwrap()) + }; + + if graph.get_edges(a).any(|n| n == b) { + if k < 2 { + return None; + } + graph.remove_vertex(a); + graph.remove_vertex(b); + + let mut r = reduction2(graph, k - 2); + + let i = graph.reinsert_vertices(2); + if let Some(r) = &mut r { + r.extend(i.map(|v| v.name)); + } + + r + } else if graph.get_degree(a) == 2 + && graph.get_degree(b) == 2 + && graph.get_edges(a).find(|&v| v != vertex).unwrap() + == graph.get_edges(b).find(|&v| v != vertex).unwrap() + { + if k < 2 { + return None; + } + let w = graph.get_edges(a).find(|&v| v != vertex).unwrap(); + + graph.remove_vertex(vertex); + graph.remove_vertex(w); + + let mut r = reduction2(graph, k - 2); + + let i = graph.reinsert_vertices(2); + if let Some(r) = &mut r { + r.extend(i.map(|v| v.name)); + } + + r + } else { + if k < 2 { + return None; + } + graph.remove_vertex(a); + graph.remove_vertex(b); + + match reduction2(graph, k - 2) { + Some(mut s) => { + let i = graph.reinsert_vertices(2); + s.extend(i.map(|v| v.name)); + Some(s) + } + None => { + let _ = graph.reinsert_vertices(2); + + let mut c = 0; + while let Some(e) = graph.get_edge(a) { + graph.remove_vertex(e); + c += 1; + } + while let Some(e) = graph.get_edge(b) { + graph.remove_vertex(e); + c += 1; + } + + if c <= k { + let mut r = reduction2(graph, k - c); + + let i = graph.reinsert_vertices(c as usize); + if let Some(r) = &mut r { + r.extend(i.map(|v| v.name)); + } + r + } else { + let _ = graph.reinsert_vertices(c as usize); + None + } + } + } + } + } else if let Some(vertex) = graph.get_vertex_with_degree_greater(3) { + graph.remove_vertex(vertex); + + match reduction2(graph, k - 1) { + Some(mut s) => { + let i = graph.reinsert_vertices(1); + s.extend(i.map(|v| v.name)); + Some(s) + } + None => { + let _ = graph.reinsert_vertices(1); + let num_neighbors = graph.get_edges(vertex).count(); + + if num_neighbors <= k as usize { + let mut c = 0; + while let Some(e) = graph.get_edge(vertex) { + graph.remove_vertex(e); + c += 1; + } + let mut r = reduction2(graph, k - c); + + let i = graph.reinsert_vertices(c as usize); + if let Some(r) = &mut r { + r.extend(i.map(|v| v.name)); + } + r + } else { + None + } + } + } + } else { + unreachable!() + } +} diff --git a/vertex_cover/vc0.out b/vertex_cover/vc0.out new file mode 100644 index 0000000..3bcc763 --- /dev/null +++ b/vertex_cover/vc0.out @@ -0,0 +1,36 @@ +35 +1 +2 +3 +5 +7 +8 +11 +12 +13 +14 +17 +18 +20 +21 +22 +23 +24 +27 +29 +33 +34 +36 +37 +38 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 diff --git a/vertex_cover/vc1.out b/vertex_cover/vc1.out new file mode 100644 index 0000000..c87e620 --- /dev/null +++ b/vertex_cover/vc1.out @@ -0,0 +1,120 @@ +119 +2 +3 +4 +5 +12 +18 +20 +24 +26 +27 +30 +34 +37 +38 +39 +41 +43 +44 +46 +47 +48 +50 +51 +56 +61 +63 +64 +65 +66 +67 +69 +73 +74 +80 +82 +83 +85 +86 +90 +97 +104 +105 +106 +108 +109 +110 +111 +112 +113 +114 +117 +119 +120 +123 +124 +130 +131 +133 +134 +135 +138 +139 +140 +141 +142 +143 +144 +147 +149 +152 +155 +161 +162 +169 +170 +173 +175 +177 +182 +184 +185 +186 +189 +195 +199 +200 +203 +204 +209 +212 +215 +217 +218 +231 +233 +240 +241 +242 +243 +244 +247 +249 +251 +257 +258 +262 +264 +265 +271 +275 +276 +279 +280 +281 +284 +286 +287 +295 +296 diff --git a/vertex_cover/vc2.out b/vertex_cover/vc2.out new file mode 100644 index 0000000..94c97c8 --- /dev/null +++ b/vertex_cover/vc2.out @@ -0,0 +1,103 @@ +102 +1 +2 +7 +9 +10 +11 +13 +17 +19 +20 +21 +22 +23 +26 +28 +33 +34 +35 +37 +38 +40 +41 +46 +49 +51 +52 +56 +57 +60 +61 +62 +63 +64 +65 +66 +69 +72 +73 +75 +76 +78 +79 +80 +81 +86 +90 +91 +95 +96 +98 +99 +100 +102 +105 +106 +107 +108 +109 +110 +112 +113 +114 +115 +116 +118 +120 +121 +122 +124 +125 +126 +127 +129 +137 +138 +139 +142 +146 +148 +150 +153 +157 +158 +160 +161 +165 +173 +176 +178 +179 +180 +181 +182 +186 +189 +190 +192 +194 +195 +196 +197 +199 diff --git a/vertex_cover/vc3.out b/vertex_cover/vc3.out new file mode 100644 index 0000000..bdc86e6 --- /dev/null +++ b/vertex_cover/vc3.out @@ -0,0 +1,82 @@ +81 +2 +3 +8 +9 +10 +12 +13 +14 +16 +17 +21 +22 +23 +24 +25 +26 +30 +32 +33 +34 +35 +36 +37 +38 +39 +41 +42 +43 +44 +45 +49 +51 +52 +53 +54 +55 +56 +58 +63 +65 +67 +69 +72 +73 +74 +76 +77 +78 +81 +82 +83 +86 +87 +89 +90 +91 +93 +94 +95 +97 +99 +101 +104 +105 +108 +109 +110 +111 +113 +116 +117 +118 +119 +120 +121 +123 +127 +129 +132 +135 +136 diff --git a/vertex_cover/vc4.out b/vertex_cover/vc4.out new file mode 100644 index 0000000..9e91703 --- /dev/null +++ b/vertex_cover/vc4.out @@ -0,0 +1,73 @@ +72 +1 +3 +4 +5 +6 +7 +9 +10 +11 +12 +13 +15 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +28 +29 +30 +31 +32 +34 +35 +36 +39 +40 +41 +43 +44 +45 +46 +47 +49 +52 +54 +55 +56 +57 +59 +60 +61 +62 +63 +65 +66 +67 +69 +72 +73 +76 +77 +80 +81 +82 +83 +84 +85 +86 +91 +93 +95 +96 +97 +98 +99 +100 diff --git a/vertex_cover/vc5.out b/vertex_cover/vc5.out new file mode 100644 index 0000000..5e02835 --- /dev/null +++ b/vertex_cover/vc5.out @@ -0,0 +1,81 @@ +80 +1 +2 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +35 +37 +38 +39 +40 +42 +43 +44 +45 +46 +47 +48 +50 +51 +52 +54 +55 +57 +58 +59 +61 +62 +63 +64 +65 +66 +70 +71 +72 +73 +74 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 diff --git a/vertex_cover/vc6.out b/vertex_cover/vc6.out new file mode 100644 index 0000000..50c6dfa --- /dev/null +++ b/vertex_cover/vc6.out @@ -0,0 +1,113 @@ +112 +1 +4 +5 +6 +8 +12 +13 +15 +17 +20 +21 +23 +25 +27 +28 +30 +31 +32 +33 +35 +36 +37 +38 +40 +43 +45 +50 +51 +52 +53 +54 +58 +59 +60 +63 +64 +66 +70 +71 +72 +73 +74 +75 +76 +78 +79 +80 +82 +83 +84 +86 +87 +90 +93 +94 +96 +98 +100 +102 +103 +105 +106 +107 +108 +109 +110 +111 +112 +113 +115 +116 +119 +121 +122 +123 +124 +125 +127 +128 +130 +131 +133 +134 +136 +138 +139 +141 +143 +144 +146 +147 +148 +150 +152 +153 +154 +155 +156 +157 +159 +160 +163 +164 +166 +168 +169 +170 +172 +173 +174 +175 +176