Implement floyd-warshall algorithm for course 4 assignment 1
parent
82cbb528b1
commit
1a9f178c97
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,77 @@
|
|||
use std::cmp::min;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Graph {
|
||||
pub n_nodes: usize,
|
||||
pub n_edges: usize,
|
||||
pub nodes: Vec<Node>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Node {
|
||||
pub id: usize,
|
||||
pub edges: Vec<Edge>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Edge {
|
||||
pub source: usize,
|
||||
pub target: usize,
|
||||
pub length: i64,
|
||||
}
|
||||
|
||||
pub fn floyd_warshall(g: Graph) -> Option<i64> {
|
||||
let n = g.n_nodes;
|
||||
let mut a: Vec<Vec<i64>> = vec![vec![std::i64::MAX; n]; n];
|
||||
|
||||
// nodes have lengths of 0 to themself
|
||||
for i in 0..n {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// 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,
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some(r)
|
||||
}
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct Knapsack {
|
||||
pub size: usize,
|
||||
|
|
30
src/main.rs
30
src/main.rs
|
@ -1,32 +1,33 @@
|
|||
mod dijkstra;
|
||||
mod floyd_warshall;
|
||||
mod heap;
|
||||
mod huffman;
|
||||
mod jobs;
|
||||
mod k_clustering;
|
||||
mod k_clustering_big;
|
||||
mod mwis;
|
||||
mod knapsack;
|
||||
mod merge_sort;
|
||||
mod min_cut;
|
||||
mod mwis;
|
||||
mod prims;
|
||||
mod quick_sort;
|
||||
mod ssc;
|
||||
mod two_sum;
|
||||
mod util;
|
||||
mod knapsack;
|
||||
|
||||
use crate::dijkstra::dijkstra;
|
||||
use crate::heap::heap;
|
||||
use crate::jobs::{jobs_1, jobs_2};
|
||||
use crate::k_clustering::k_clustering;
|
||||
use crate::k_clustering_big::k_clustering_big;
|
||||
use crate::knapsack::knapsack;
|
||||
use crate::merge_sort::merge_sort_inversions;
|
||||
use crate::min_cut::min_cut;
|
||||
use crate::mwis::mwis;
|
||||
use crate::prims::prims;
|
||||
use crate::quick_sort::quick_sort;
|
||||
use crate::ssc::ssc;
|
||||
use crate::two_sum::find_two_sums;
|
||||
use crate::mwis::mwis;
|
||||
use crate::knapsack::knapsack;
|
||||
use std::cmp::min;
|
||||
|
||||
#[allow(dead_code)]
|
||||
|
@ -143,8 +144,20 @@ fn c3a4() {
|
|||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn c4a4() {
|
||||
println!("Final course!");
|
||||
fn c4a1() {
|
||||
let g1 = util::read_floyd_warshall_graph("data/c4a1_g1.txt").unwrap();
|
||||
let r1 = floyd_warshall::floyd_warshall(g1);
|
||||
let g2 = util::read_floyd_warshall_graph("data/c4a1_g2.txt").unwrap();
|
||||
let r2 = floyd_warshall::floyd_warshall(g2);
|
||||
let g3 = util::read_floyd_warshall_graph("data/c4a1_g3.txt").unwrap();
|
||||
let r3 = floyd_warshall::floyd_warshall(g3);
|
||||
println!("r1 = {:?} r2 = {:?} r3 = {:?}", r1, r2, r3);
|
||||
// r = -19
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn c4a2() {
|
||||
println!("continue here");
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
@ -158,6 +171,7 @@ fn main() {
|
|||
// c3a1();
|
||||
// c3a2();
|
||||
// c3a3();
|
||||
c3a4();
|
||||
c4a4();
|
||||
// c3a4();
|
||||
// c4a1();
|
||||
c4a2();
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct IndependentSet {
|
||||
pub length: usize,
|
||||
|
@ -14,7 +13,6 @@ struct Solution {
|
|||
pub fn mwis(s: &IndependentSet) -> Vec<usize> {
|
||||
let mut solutions: Vec<Solution> = Vec::new();
|
||||
|
||||
|
||||
solutions.push(Solution {
|
||||
weight: s.weights[0],
|
||||
nodes: vec![0],
|
||||
|
@ -43,7 +41,6 @@ pub fn mwis(s: &IndependentSet) -> Vec<usize> {
|
|||
} else {
|
||||
solutions.push(s2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
let solution = solutions.pop().unwrap();
|
||||
|
|
47
src/util.rs
47
src/util.rs
|
@ -1,12 +1,13 @@
|
|||
use crate::floyd_warshall;
|
||||
use crate::huffman;
|
||||
use crate::jobs;
|
||||
use crate::k_clustering;
|
||||
use crate::k_clustering_big;
|
||||
use crate::knapsack;
|
||||
use crate::min_cut;
|
||||
use crate::mwis;
|
||||
use crate::prims;
|
||||
use crate::ssc;
|
||||
use crate::mwis;
|
||||
use crate::knapsack;
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
use std::io::{BufRead, BufReader, Error, ErrorKind};
|
||||
|
@ -310,3 +311,45 @@ pub fn read_knapsack(path: &str) -> Result<knapsack::Knapsack, io::Error> {
|
|||
|
||||
Ok(k)
|
||||
}
|
||||
|
||||
pub fn read_floyd_warshall_graph(path: &str) -> Result<floyd_warshall::Graph, io::Error> {
|
||||
let file = File::open(path)?;
|
||||
let mut lines = BufReader::new(file).lines();
|
||||
let line = lines.next().unwrap()?;
|
||||
let mut fields = line.split_whitespace();
|
||||
let n_nodes = fields.next().unwrap().parse().unwrap();
|
||||
let n_edges = fields.next().unwrap().parse().unwrap();
|
||||
|
||||
let mut g = floyd_warshall::Graph {
|
||||
n_nodes: n_nodes,
|
||||
n_edges: n_edges,
|
||||
nodes: Vec::new(),
|
||||
};
|
||||
|
||||
for i in 0..n_nodes {
|
||||
let n = floyd_warshall::Node {
|
||||
id: i,
|
||||
edges: Vec::new(),
|
||||
};
|
||||
g.nodes.push(n);
|
||||
}
|
||||
|
||||
for line in lines {
|
||||
let line = line?;
|
||||
let mut it = line.split_whitespace();
|
||||
let mut source = it.next().unwrap().parse().unwrap();
|
||||
let mut target = it.next().unwrap().parse().unwrap();
|
||||
let length = it.next().unwrap().parse().unwrap();
|
||||
source = source - 1;
|
||||
target = target - 1;
|
||||
|
||||
let e = floyd_warshall::Edge {
|
||||
source: source,
|
||||
target: target,
|
||||
length: length,
|
||||
};
|
||||
g.nodes[source].edges.push(e);
|
||||
}
|
||||
|
||||
Ok(g)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue