diff --git a/src/floyd_warshall.rs b/src/floyd_warshall.rs index b856d42..2742850 100644 --- a/src/floyd_warshall.rs +++ b/src/floyd_warshall.rs @@ -21,56 +21,56 @@ pub struct Edge { } pub fn floyd_warshall(g: Graph) -> Option { - let n = g.n_nodes; + let n = g.n_nodes; let mut a: Vec> = vec![vec![std::i64::MAX; n]; n]; // nodes have lengths of 0 to themself for i in 0..n { - a[i][i] = 0; + a[i][i] = 0; } // nodes that are connected get the length of their edge for n in &g.nodes { - for e in &n.edges { - a[e.source][e.target] = e.length; - } + for e in &n.edges { + a[e.source][e.target] = e.length; + } } // main workloop for k in 0..n { - let mut new_a = a.to_vec(); - for i in 0..n { - for j in 0..n { - let case_1 = a[i][j]; - let case_2 = match a[i][k].checked_add(a[k][j]) { - Some(v) => v, - None => std::i64::MAX, - }; + let mut new_a = a.to_vec(); + for i in 0..n { + for j in 0..n { + let case_1 = a[i][j]; + let case_2 = match a[i][k].checked_add(a[k][j]) { + Some(v) => v, + None => std::i64::MAX, + }; - new_a[i][j] = min(case_1, case_2); - } - } - a = new_a; + new_a[i][j] = min(case_1, case_2); + } + } + a = new_a; } // node to itself is negative means we have negative cost cycles for i in 0..n { - if a[i][i] < 0 { - return None; - } + if a[i][i] < 0 { + return None; + } } // find min path from v to u let mut r = std::i64::MAX; for i in 0..n { - for j in 0..n { - if i != j { - let d = a[i][j]; - if d < r { - r = d; - } - } - } + for j in 0..n { + if i != j { + let d = a[i][j]; + if d < r { + r = d; + } + } + } } Some(r) diff --git a/src/main.rs b/src/main.rs index 0c8abc9..61d07db 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,6 +12,7 @@ mod mwis; mod prims; mod quick_sort; mod ssc; +mod tsp; mod two_sum; mod util; @@ -27,6 +28,7 @@ use crate::mwis::mwis; use crate::prims::prims; use crate::quick_sort::quick_sort; use crate::ssc::ssc; +use crate::tsp::tsp_heuristic; use crate::two_sum::find_two_sums; use std::cmp::min; @@ -163,12 +165,14 @@ fn c4a2() { #[allow(dead_code)] fn c4a3() { - println!("Continue here"); + let g = util::read_tsp_graph("data/c4a3_tsp.txt").unwrap(); + let r = tsp_heuristic(g); + println!("r = {}", r); } #[allow(dead_code)] fn c4a4() { - println!("we are done!"); + println!("we are done soon!"); } fn main() { diff --git a/src/tsp.rs b/src/tsp.rs new file mode 100644 index 0000000..24bf7a2 --- /dev/null +++ b/src/tsp.rs @@ -0,0 +1,39 @@ +#[derive(Debug)] +pub struct Graph { + pub n_nodes: usize, + pub nodes: Vec, +} + +#[derive(Debug, Copy, Clone)] +pub struct Node { + pub id: usize, + pub x: f64, + pub y: f64, +} + +fn distance(a: &Node, b: &Node) -> f64 { + ((a.x - b.x).powf(2.0) + (a.y - b.y).powf(2.0)).sqrt() +} + +pub fn tsp_heuristic(mut g: Graph) -> f64 { + let mut dist: f64 = 0.0; + let mut current_node = g.nodes.remove(0); + let first_node = current_node; + + while g.nodes.len() > 0 { + let mut min_dist = f64::MAX; + let mut min_id = 0; + for i in 0..g.nodes.len() { + let node = &g.nodes[i]; + let new_dist = distance(node, ¤t_node); + if new_dist < min_dist { + min_dist = new_dist; + min_id = i; + } + } + current_node = g.nodes.remove(min_id); + dist += min_dist; + } + dist += distance(¤t_node, &first_node); + dist +} diff --git a/src/util.rs b/src/util.rs index 44955a0..2a9a9d3 100644 --- a/src/util.rs +++ b/src/util.rs @@ -8,6 +8,7 @@ use crate::min_cut; use crate::mwis; use crate::prims; use crate::ssc; +use crate::tsp; use std::fs::File; use std::io; use std::io::{BufRead, BufReader, Error, ErrorKind}; @@ -353,3 +354,31 @@ pub fn read_floyd_warshall_graph(path: &str) -> Result Result { + let file = File::open(path)?; + let mut lines = BufReader::new(file).lines(); + let line = lines.next().unwrap()?; + let n_nodes = line.parse().unwrap(); + + let mut g = tsp::Graph { + n_nodes: n_nodes, + nodes: Vec::new(), + }; + + for line in lines { + let line = line?; + let mut it = line.split_whitespace(); + let node_id: usize = it.next().unwrap().parse().unwrap(); + let x = it.next().unwrap().parse().unwrap(); + let y = it.next().unwrap().parse().unwrap(); + let n = tsp::Node { + id: node_id - 1, + x: x, + y: y, + }; + g.nodes.push(n); + } + + Ok(g) +}