Add owned and reduction implementation for vertex cover
This commit is contained in:
		
							parent
							
								
									68bfda7077
								
							
						
					
					
						commit
						f0a1257b25
					
				
					 3 changed files with 256 additions and 7 deletions
				
			
		|  | @ -24,13 +24,13 @@ pub fn binary_edge(graph: &Graph, k: u16, v: HashSet<u16>) -> Option<HashSet<u16 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub fn binary_vertex(graph: &Graph, k: u16, v: HashSet<u16>) -> Option<HashSet<u16>> { | pub fn binary_vertex(graph: &Graph, k: u16, v: HashSet<u16>) -> Option<HashSet<u16>> { | ||||||
|     let vertex = match graph.get_vertex_filtered_with_degree_grater(&v, 2) { |     let vertex = match graph.get_vertex_filtered_with_degree_greater(&v, 2) { | ||||||
|         Some(vertex) => vertex, |         Some(vertex) => vertex, | ||||||
|         None => { |         None => { | ||||||
|             return { |             return { | ||||||
|                 let mut v3 = v; |                 let mut v3 = v; | ||||||
|                 let mut c = 0; |                 let mut c = 0; | ||||||
|                 while let Some(vertex) = graph.get_vertex_filtered_with_degree_grater(&v3, 1) { |                 while let Some(vertex) = graph.get_vertex_filtered_with_degree_greater(&v3, 1) { | ||||||
|                     v3.insert(vertex); |                     v3.insert(vertex); | ||||||
|                     c += 1; |                     c += 1; | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|  | @ -5,6 +5,7 @@ use std::{ | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| mod filtered; | mod filtered; | ||||||
|  | mod owned; | ||||||
| 
 | 
 | ||||||
| fn parse(filename: impl AsRef<Path>) -> Graph { | fn parse(filename: impl AsRef<Path>) -> Graph { | ||||||
|     let content = std::fs::read_to_string(filename).unwrap(); |     let content = std::fs::read_to_string(filename).unwrap(); | ||||||
|  | @ -50,6 +51,10 @@ impl Graph { | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     fn num_vertices(&self) -> u16 { | ||||||
|  |         self.edge_list.len() as u16 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     fn add_edge(&mut self, from: u16, to: u16) { |     fn add_edge(&mut self, from: u16, to: u16) { | ||||||
|         self.edge_list[(from) as usize].push(to); |         self.edge_list[(from) as usize].push(to); | ||||||
|         self.edge_list[(to) as usize].push(from); |         self.edge_list[(to) as usize].push(from); | ||||||
|  | @ -99,7 +104,7 @@ impl Graph { | ||||||
|         }) |         }) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fn get_vertex_filtered_with_degree_grater( |     fn get_vertex_filtered_with_degree_greater( | ||||||
|         &self, |         &self, | ||||||
|         v: &HashSet<u16>, |         v: &HashSet<u16>, | ||||||
|         min_degree: u16, |         min_degree: u16, | ||||||
|  | @ -109,10 +114,27 @@ impl Graph { | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn vertex_cover(graph: &Graph, k: u16, method: Method) -> Option<HashSet<u16>> { | fn vertex_cover(graph: &Graph, k: u16, method: Method) -> Option<Vec<u16>> { | ||||||
|     match method { |     match method { | ||||||
|         Method::Edge => filtered::binary_edge(graph, k, HashSet::new()), |         Method::Edge => { | ||||||
|         Method::Vertex => filtered::binary_vertex(graph, k, HashSet::new()), |             let r = filtered::binary_edge(graph, k, HashSet::new()); | ||||||
|  | 
 | ||||||
|  |             r.map(|mut r| r.drain().collect()) | ||||||
|  |         } | ||||||
|  |         Method::Vertex => { | ||||||
|  |             let r = filtered::binary_vertex(graph, k, HashSet::new()); | ||||||
|  |             r.map(|mut r| r.drain().collect()) | ||||||
|  |         } | ||||||
|  |         Method::OwnedVertex => { | ||||||
|  |             let mut g = owned::Graph::new(graph); | ||||||
|  | 
 | ||||||
|  |             owned::binary_vertex(&mut g, k) | ||||||
|  |         } | ||||||
|  |         Method::Reduction => { | ||||||
|  |             let mut g = owned::Graph::new(graph); | ||||||
|  | 
 | ||||||
|  |             owned::reduction(&mut g, k) | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -120,6 +142,8 @@ fn vertex_cover(graph: &Graph, k: u16, method: Method) -> Option<HashSet<u16>> { | ||||||
| enum Method { | enum Method { | ||||||
|     Edge, |     Edge, | ||||||
|     Vertex, |     Vertex, | ||||||
|  |     OwnedVertex, | ||||||
|  |     Reduction, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[derive(Debug, Parser)] | #[derive(Debug, Parser)] | ||||||
|  | @ -152,7 +176,8 @@ fn main() { | ||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     if let Some(solution) = result { |     if let Some(mut solution) = result { | ||||||
|  |         solution.sort(); | ||||||
|         println!("{}", solution.len()); |         println!("{}", solution.len()); | ||||||
| 
 | 
 | ||||||
|         for n in solution { |         for n in solution { | ||||||
|  |  | ||||||
							
								
								
									
										224
									
								
								vertex_cover/src/owned.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										224
									
								
								vertex_cover/src/owned.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,224 @@ | ||||||
|  | use std::collections::HashSet; | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | struct Vertex { | ||||||
|  |     name: u16, | ||||||
|  |     edges: Vec<u16>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub struct Graph { | ||||||
|  |     index: Vec<u16>, | ||||||
|  |     vertices: Vec<Vertex>, | ||||||
|  |     stack: Vec<Vertex>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl Graph { | ||||||
|  |     pub fn new(g: &crate::Graph) -> Self { | ||||||
|  |         let mut vertices: Vec<_> = (0..g.num_vertices()) | ||||||
|  |             .map(|i| Vertex { | ||||||
|  |                 name: i, | ||||||
|  |                 edges: Vec::new(), | ||||||
|  |             }) | ||||||
|  |             .collect(); | ||||||
|  | 
 | ||||||
|  |         for (start, s) in g.edge_list.iter().enumerate() { | ||||||
|  |             vertices[start].edges.extend_from_slice(s); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         Self { | ||||||
|  |             index: (0..g.num_vertices()).collect(), | ||||||
|  |             vertices, | ||||||
|  |             stack: Vec::new(), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn is_empty(&self) -> bool { | ||||||
|  |         self.vertices.is_empty() | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn remove_vertex(&mut self, v: u16) -> &Vertex { | ||||||
|  |         let i = self.index[v as usize]; | ||||||
|  |         // dbg!(&self.index, v, i);
 | ||||||
|  |         let vertex = self.vertices.swap_remove(i as usize); | ||||||
|  | 
 | ||||||
|  |         assert_eq!(vertex.name, v); | ||||||
|  | 
 | ||||||
|  |         if (i as usize) < self.vertices.len() { | ||||||
|  |             self.index[self.vertices[i as usize].name as usize] = i; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         for &e in &vertex.edges { | ||||||
|  |             let i = self.index[e as usize]; | ||||||
|  |             self.vertices[i as usize].edges.retain(|&o| o != v); | ||||||
|  |         } | ||||||
|  |         // dbg!(&self.index);
 | ||||||
|  | 
 | ||||||
|  |         self.stack.push(vertex); | ||||||
|  | 
 | ||||||
|  |         self.stack.last().unwrap() | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn reinsert_vertices(&mut self, n: usize) -> impl Iterator<Item = &Vertex> { | ||||||
|  |         for _ in 0..n { | ||||||
|  |             let v = self.stack.pop().unwrap(); | ||||||
|  |             for &e in &v.edges { | ||||||
|  |                 let i = self.index[e as usize]; | ||||||
|  |                 self.vertices[i as usize].edges.push(v.name); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             self.index[v.name as usize] = self.vertices.len() as u16; | ||||||
|  |             self.vertices.push(v); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         self.vertices[(self.vertices.len() - n)..].iter() | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn get_vertex_with_degree_greater(&self, min_degree: u16) -> Option<u16> { | ||||||
|  |         self.vertices | ||||||
|  |             .iter() | ||||||
|  |             .find(|&v| v.edges.len() >= min_degree as usize) | ||||||
|  |             .map(|v| v.name) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn get_vertex_with_degree(&self, degree: u16) -> Option<u16> { | ||||||
|  |         self.vertices | ||||||
|  |             .iter() | ||||||
|  |             .find(|&v| v.edges.len() == degree as usize) | ||||||
|  |             .map(|v| v.name) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn get_edges(&self, v: u16) -> impl Iterator<Item = u16> + '_ { | ||||||
|  |         let i = self.index[v as usize]; | ||||||
|  |         self.vertices[i as usize].edges.iter().copied() | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn get_edge(&self, v: u16) -> Option<u16> { | ||||||
|  |         self.get_edges(v).next() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pub fn binary_vertex(graph: &mut Graph, k: u16) -> Option<Vec<u16>> { | ||||||
|  |     let vertex = match graph.get_vertex_with_degree_greater(2) { | ||||||
|  |         Some(vertex) => vertex, | ||||||
|  |         None => { | ||||||
|  |             return { | ||||||
|  |                 let mut c = 0; | ||||||
|  |                 while let Some(vertex) = graph.get_vertex_with_degree_greater(1) { | ||||||
|  |                     graph.remove_vertex(vertex); | ||||||
|  |                     c += 1; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 if c <= k { | ||||||
|  |                     Some( | ||||||
|  |                         graph | ||||||
|  |                             .reinsert_vertices(c as usize) | ||||||
|  |                             .map(|v| v.name) | ||||||
|  |                             .collect(), | ||||||
|  |                     ) | ||||||
|  |                 } else { | ||||||
|  |                     let _ = graph.reinsert_vertices(c as usize); | ||||||
|  |                     None | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     if k == 0 { | ||||||
|  |         return None; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     graph.remove_vertex(vertex); | ||||||
|  | 
 | ||||||
|  |     match binary_vertex(graph, k - 1) { | ||||||
|  |         Some(mut s) => { | ||||||
|  |             s.push(vertex); | ||||||
|  |             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 = binary_vertex(graph, k - c); | ||||||
|  |                 if let Some(r) = &mut r { | ||||||
|  |                     r.extend(graph.reinsert_vertices(c as usize).map(|v| v.name)); | ||||||
|  |                 } else { | ||||||
|  |                     let _ = graph.reinsert_vertices(c as usize); | ||||||
|  |                 } | ||||||
|  |                 r | ||||||
|  |             } else { | ||||||
|  |                 None | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pub fn reduction(graph: &mut Graph, k: u16) -> Option<Vec<u16>> { | ||||||
|  |     if let Some(vertex) = graph.get_vertex_with_degree(0) { | ||||||
|  |         graph.remove_vertex(vertex); | ||||||
|  | 
 | ||||||
|  |         let r = reduction(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(); | ||||||
|  | 
 | ||||||
|  |         graph.remove_vertex(neighbor); | ||||||
|  |         let mut r = reduction(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_greater(2) { | ||||||
|  |         graph.remove_vertex(vertex); | ||||||
|  | 
 | ||||||
|  |         match reduction(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 = reduction(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!() | ||||||
|  |     } | ||||||
|  | } | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue