Finish assignment for course 1 week 4

This commit is contained in:
2020-11-28 12:59:14 -05:00
parent 47e5fec4bd
commit 9a8ffa64e1
4 changed files with 80 additions and 10 deletions

View File

@@ -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() {

View File

@@ -1,4 +1,55 @@
use rand::Rng;
use std::convert::TryInto;
#[derive(Debug, Clone)]
pub struct Graph {
pub nodes: Vec<u32>,
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()
}

View File

@@ -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<u32>,
edges: Vec<(u32, u32)>,
}
pub fn read_to_vector(path: &str) -> Result<Vec<i64>, io::Error> {
let file = File::open(path)?;
let br = BufReader::new(file);
@@ -34,8 +28,20 @@ pub fn read_to_graph(path: &str) -> Result<Graph, io::Error> {
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)
}