From 687bb45eca74a5e82250b0b52fc361411aa033dd Mon Sep 17 00:00:00 2001 From: Felix Martin Date: Fri, 5 Feb 2021 19:28:19 -0500 Subject: [PATCH] Work on week 3 assignment 2 --- src/dijkstra.rs | 6 ++- src/k_clustering.rs | 67 ++++++++++++++++++++++++++++++---- src/main.rs | 12 +++--- src/min_cut.rs | 7 +++- src/ssc.rs | 9 ++++- src/util.rs | 89 +++++++++++++++++++++++++++------------------ 6 files changed, 139 insertions(+), 51 deletions(-) diff --git a/src/dijkstra.rs b/src/dijkstra.rs index c04c605..3ac1a32 100644 --- a/src/dijkstra.rs +++ b/src/dijkstra.rs @@ -1,4 +1,8 @@ -use crate::util::DirectedWeightedGraph; +#[derive(Debug)] +pub struct DirectedWeightedGraph { + pub nodes: Vec>, + pub distance: Vec, +} pub fn dijkstra(g: &mut DirectedWeightedGraph) -> () { let mut x: Vec = vec![0]; diff --git a/src/k_clustering.rs b/src/k_clustering.rs index bef99a7..9bbf7c7 100644 --- a/src/k_clustering.rs +++ b/src/k_clustering.rs @@ -1,10 +1,63 @@ -use crate::prims::WeightedGraph; -use std::convert::TryInto; +use std::collections::HashSet; -pub fn k_clustering(graph: &WeightedGraph) -> i32 { - for vertex in graph { - println!("{:?}", vertex.edges.len()); - } - graph.len().try_into().unwrap() +#[derive(Debug, Clone, Copy)] +pub struct Edge { + pub weight: i32, + pub source_id: usize, + pub target_id: usize, } +pub struct WeightedGraph { + pub n_nodes: usize, + pub cluster: Vec, + pub edges: Vec, +} + +pub fn k_clustering(graph: &mut WeightedGraph) -> usize { + let k: usize = 4; + + let mut cluster_count = graph.n_nodes; + let mut clusters: Vec> = (0..graph.n_nodes).map(|x| vec![x]).collect(); + println!("{:?}", clusters); + + // Sort edges by decreasing weight + graph + .edges + .sort_by(|a, b| b.weight.partial_cmp(&a.weight).unwrap()); + + for edge in &graph.edges { + let ca_id = graph.cluster[edge.source_id]; + let cb_id = graph.cluster[edge.target_id]; + + if ca_id == cb_id { + continue; // Nodes are already in the same cluster + } + + let ca: &mut Vec = &mut clusters[ca_id]; + let cb = clusters[cb_id].clone(); + + for node in cb { + ca.push(node); + } + + // clusters[ca].append(&mut clusters[cb]); + + // clusters[] + // clusters[cluster_target].clear(); + // graph.cluster[edge.target_id]= cluster_source; + + cluster_count -= 1; + + if cluster_count <= k { + break; + } + } + + for cluster in &clusters { + if cluster.len() > 0 { + // println!("{:?}", cluster); + } + } + + graph.n_nodes +} diff --git a/src/main.rs b/src/main.rs index 781f9e0..ba45ad6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,7 @@ mod dijkstra; mod heap; mod jobs; +mod k_clustering; mod merge_sort; mod min_cut; mod prims; @@ -8,18 +9,17 @@ mod quick_sort; mod ssc; mod two_sum; mod util; -mod k_clustering; use crate::dijkstra::dijkstra; use crate::heap::heap; use crate::jobs::{jobs_1, jobs_2}; +use crate::k_clustering::k_clustering; use crate::merge_sort::merge_sort_inversions; use crate::min_cut::min_cut; use crate::prims::prims; use crate::quick_sort::quick_sort; use crate::ssc::ssc; use crate::two_sum::find_two_sums; -use crate::k_clustering::k_clustering; use std::cmp::min; #[allow(dead_code)] @@ -96,7 +96,7 @@ fn c3a1() { let mut jobs = util::read_jobs("data/c3a1_jobs.txt").unwrap(); let r1 = jobs_1(&mut jobs); let r2 = jobs_2(&mut jobs); - let g = util::read_weighted_graph("data/c3a1_edges.txt").unwrap(); + let g = util::read_weighted_graph_prims("data/c3a1_edges.txt").unwrap(); let r3 = prims(&g); println!("r1 = {}; r2 = {}; r3 = {} ", r1, r2, r3); @@ -105,9 +105,9 @@ fn c3a1() { #[allow(dead_code)] fn c3a2() { - let graph = util::read_weighted_graph("data/c3a2_clustering.txt").unwrap(); - let r1 = k_clustering(&graph); - println!("r1 = {:?}", r1); + let mut graph = util::read_weighted_graph_clustering("data/c3a2_clustering.txt").unwrap(); + let r1 = k_clustering(&mut graph); + println!("r1 = {:?}", r1); } fn main() { diff --git a/src/min_cut.rs b/src/min_cut.rs index 132b2a7..30344f2 100644 --- a/src/min_cut.rs +++ b/src/min_cut.rs @@ -1,7 +1,12 @@ -use crate::util::Graph; 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); diff --git a/src/ssc.rs b/src/ssc.rs index 30bdfde..24cf33b 100644 --- a/src/ssc.rs +++ b/src/ssc.rs @@ -1,6 +1,13 @@ -use crate::util::DirectedGraph; use std::collections::HashMap; +#[derive(Debug)] +pub struct DirectedGraph { + pub nodes: Vec>, + pub explored: Vec, + pub time: Vec, + pub leader: Vec, +} + fn dfs(g: &mut DirectedGraph, node: usize, time: &mut usize) -> () { let mut nodes: Vec<(usize, usize)> = vec![(node, 0)]; g.explored[node] = true; diff --git a/src/util.rs b/src/util.rs index 48874b0..b03f667 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,30 +1,13 @@ -use crate::jobs::{Job, Jobs}; -use crate::prims::{Edge, Vertex, WeightedGraph}; +use crate::jobs; +use crate::k_clustering; +use crate::min_cut; +use crate::prims; +use crate::ssc; use std::fs::File; use std::io; use std::io::{BufRead, BufReader, Error, ErrorKind}; use std::vec::Vec; -#[derive(Debug, Clone)] -pub struct Graph { - pub nodes: Vec, - pub edges: Vec<(u32, u32)>, -} - -#[derive(Debug)] -pub struct DirectedGraph { - pub nodes: Vec>, - pub explored: Vec, - pub time: Vec, - pub leader: Vec, -} - -#[derive(Debug)] -pub struct DirectedWeightedGraph { - pub nodes: Vec>, - pub distance: Vec, -} - pub fn read_to_vector(path: &str) -> Result, io::Error> { let file = File::open(path)?; let br = BufReader::new(file); @@ -40,8 +23,8 @@ pub fn read_to_vector(path: &str) -> Result, io::Error> { Ok(v) } -pub fn read_to_graph(path: &str) -> Result { - let mut g = Graph { +pub fn read_to_graph(path: &str) -> Result { + let mut g = min_cut::Graph { nodes: vec![], edges: vec![], }; @@ -84,16 +67,18 @@ fn get_node_size(path: &str) -> Result { Ok(node_size) } -pub fn read_to_directed_graph(path: &str) -> Result<(DirectedGraph, DirectedGraph), io::Error> { +pub fn read_to_directed_graph( + path: &str, +) -> Result<(ssc::DirectedGraph, ssc::DirectedGraph), io::Error> { let nodes: usize = get_node_size(path).unwrap(); - let mut g = DirectedGraph { + let mut g = ssc::DirectedGraph { nodes: vec![vec![]; nodes], explored: vec![false; nodes], time: vec![0; nodes], leader: vec![0; nodes], }; - let mut g_dash = DirectedGraph { + let mut g_dash = ssc::DirectedGraph { nodes: vec![vec![]; nodes], explored: vec![false; nodes], time: vec![0; nodes], @@ -116,9 +101,11 @@ pub fn read_to_directed_graph(path: &str) -> Result<(DirectedGraph, DirectedGrap Ok((g, g_dash)) } -pub fn read_to_directed_weighted_graph(path: &str) -> Result { +pub fn read_to_directed_weighted_graph( + path: &str, +) -> Result { let nodes: usize = get_node_size(path).unwrap(); - let mut g = DirectedWeightedGraph { + let mut g = crate::dijkstra::DirectedWeightedGraph { nodes: vec![vec![]; nodes], distance: vec![1000000; nodes], // initial distance based on instructions }; @@ -141,7 +128,7 @@ pub fn read_to_directed_weighted_graph(path: &str) -> Result Result { +pub fn read_jobs(path: &str) -> Result { let mut jobs = Vec::new(); let file = File::open(path)?; let br = BufReader::new(file); @@ -152,7 +139,7 @@ pub fn read_jobs(path: &str) -> Result { let mut nodes = line.split_whitespace(); let weight = nodes.next().unwrap().parse().unwrap(); let length = nodes.next().unwrap().parse().unwrap(); - let job = Job { + let job = jobs::Job { weight: weight, length: length, }; @@ -162,7 +149,7 @@ pub fn read_jobs(path: &str) -> Result { Ok(jobs) } -pub fn read_weighted_graph(path: &str) -> Result { +pub fn read_weighted_graph_prims(path: &str) -> Result { let mut g = Vec::new(); let file = File::open(path)?; let br = BufReader::new(file); @@ -173,7 +160,7 @@ pub fn read_weighted_graph(path: &str) -> Result { // let n_edges: usize = fields.next().unwrap().parse().unwrap(); for i in 0..n_nodes { - let node = Vertex { + let node = prims::Vertex { id: i, edges: vec![], }; @@ -187,14 +174,14 @@ pub fn read_weighted_graph(path: &str) -> Result { let id_b: usize = nodes.next().unwrap().parse::().unwrap() - 1; let weight = nodes.next().unwrap().parse().unwrap(); - let edge = Edge { + let edge = prims::Edge { weight: weight, source_id: id_a, target_id: id_b, }; g[id_a].edges.push(edge); - let edge = Edge { + let edge = crate::prims::Edge { weight: weight, source_id: id_b, target_id: id_a, @@ -204,3 +191,35 @@ pub fn read_weighted_graph(path: &str) -> Result { Ok(g) } + +pub fn read_weighted_graph_clustering( + path: &str, +) -> Result { + let file = File::open(path)?; + let mut lines = BufReader::new(file).lines(); + let line = lines.next().unwrap().unwrap(); + let n_nodes: usize = line.parse().unwrap(); + + let mut g = k_clustering::WeightedGraph { + n_nodes: n_nodes, + cluster: (0..n_nodes).collect(), + edges: Vec::new(), + }; + + for line in lines { + let line = line?; + let mut nodes = line.split_whitespace(); + let id_a: usize = nodes.next().unwrap().parse::().unwrap() - 1; + let id_b: usize = nodes.next().unwrap().parse::().unwrap() - 1; + let weight = nodes.next().unwrap().parse().unwrap(); + + let edge = k_clustering::Edge { + weight: weight, + source_id: id_a, + target_id: id_b, + }; + g.edges.push(edge) + } + + Ok(g) +}