From 9a8ffa64e1d948066be3f53b7b29a81de394b213 Mon Sep 17 00:00:00 2001 From: Felix Martin Date: Sat, 28 Nov 2020 12:59:14 -0500 Subject: [PATCH] Finish assignment for course 1 week 4 --- Cargo.toml | 1 + src/main.rs | 14 +++++++++++++- src/min_cut.rs | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/util.rs | 24 +++++++++++++++--------- 4 files changed, 80 insertions(+), 10 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6839c06..0936d0f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,3 +7,4 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +rand = "0.7.3" \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 3b6a633..be80f40 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,11 @@ mod merge_sort; mod quick_sort; +mod min_cut; mod util; use crate::util::read_to_graph; use crate::util::read_to_vector; +use crate::min_cut::min_cut; use crate::quick_sort::quick_sort; use crate::merge_sort::merge_sort_inversions; @@ -27,9 +29,19 @@ fn c1a3() { */ } +#[allow(dead_code)] fn c1a4() { let g = read_to_graph("data/course_1_assignment_4.txt").unwrap(); - println!("{:?}", g); + let mut smalles_min_cut = u32::MAX; + let iterations = g.nodes.len().pow(1); + for _ in 0..iterations { + let new_min_cut = min_cut(g.clone()); + if new_min_cut < smalles_min_cut { + smalles_min_cut = new_min_cut; + } + } + /* 17 */ + println!("course 1 assignment 4: {:?}", smalles_min_cut); } fn main() { diff --git a/src/min_cut.rs b/src/min_cut.rs index fd40910..db45f02 100644 --- a/src/min_cut.rs +++ b/src/min_cut.rs @@ -1,4 +1,55 @@ +use rand::Rng; +use std::convert::TryInto; +#[derive(Debug, Clone)] +pub struct Graph { + pub nodes: Vec, + pub edges: Vec<(u32, u32)>, +} +pub fn min_cut(mut g: Graph) -> u32 { + let mut rng = rand::thread_rng(); + // println!("min_cut({:?})\n", g); + while g.nodes.len() > 2 { + // pick random edge (u, v) + let edge_index = rng.gen_range(0, g.edges.len()); + let removed_edge = g.edges.swap_remove(edge_index); + // merge u and v into a single node u + let mut self_loops = vec![]; + let u = removed_edge.0; + let v = removed_edge.1; + for i in 0..g.edges.len() { + // replace all v with u + if g.edges[i].0 == v { + g.edges[i].0 = u; + } + if g.edges[i].1 == v { + g.edges[i].1 = u; + } + // make sure lower node comes first + if g.edges[i].0 > g.edges[i].1 { + g.edges[i] = (g.edges[i].1, g.edges[i]. 0); + } + if g.edges[i].0 == g.edges[i].1 { + self_loops.push(i); + } + } + + // remove v from nodes + g.nodes.pop(); // we only use the nodes.len() + // if let Some(i) = g.nodes.iter().position(|x| *x == v) { + // g.nodes.swap_remove(i); + // } + + // remove self-loops + let mut self_loops_removed: usize = 0; + for i in self_loops { + g.edges.remove(i - self_loops_removed); + self_loops_removed += 1; + } + } + // return cut represented by the final two nodes + g.edges.len().try_into().unwrap() +} diff --git a/src/util.rs b/src/util.rs index b4c5bfc..543a9f1 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,16 +1,10 @@ +use crate::min_cut::Graph; use std::fs::File; use std::io; use std::io::{BufRead, BufReader, Error, ErrorKind}; use std::vec::Vec; -#[derive(Debug)] -pub struct Graph { - nodes: Vec, - edges: Vec<(u32, u32)>, -} - - pub fn read_to_vector(path: &str) -> Result, io::Error> { let file = File::open(path)?; let br = BufReader::new(file); @@ -34,8 +28,20 @@ pub fn read_to_graph(path: &str) -> Result { for line in br.lines() { let line = line?; - println!("{:?}", line); - } + let mut nodes = line.split_whitespace(); + let current_node = nodes.next().unwrap().parse().unwrap(); + g.nodes.push(current_node); + for neightbor in nodes { + let neightbor: u32 = neightbor.parse().unwrap(); + // If the neighbor is smaller than the current node that means we + // have already added it when we iterated over that smaller node. + // Hence, we do not add the edge again. + if neightbor > current_node { + let edge = (current_node, neightbor); + g.edges.push(edge); + } + } + } Ok(g) } \ No newline at end of file