Add reduction rules for degree 2 and vertex cover

This commit is contained in:
hal8174 2024-11-10 20:10:02 +01:00
parent f0a1257b25
commit ec0592cb05
10 changed files with 769 additions and 1 deletions

View file

@ -135,6 +135,11 @@ fn vertex_cover(graph: &Graph, k: u16, method: Method) -> Option<Vec<u16>> {
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)]

View file

@ -96,6 +96,11 @@ impl Graph {
fn get_edge(&self, v: u16) -> Option<u16> {
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<Vec<u16>> {
@ -222,3 +227,153 @@ pub fn reduction(graph: &mut Graph, k: u16) -> Option<Vec<u16>> {
unreachable!()
}
}
pub fn reduction2(graph: &mut Graph, k: u16) -> Option<Vec<u16>> {
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!()
}
}