Implement SSC algorithm to finish course 2 assignment 1
This commit is contained in:
11
data/course_2_assignment_1_test.txt
Normal file
11
data/course_2_assignment_1_test.txt
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
1 4
|
||||||
|
2 8
|
||||||
|
3 6
|
||||||
|
4 7
|
||||||
|
5 2
|
||||||
|
6 9
|
||||||
|
7 1
|
||||||
|
8 5
|
||||||
|
8 6
|
||||||
|
9 3
|
||||||
|
9 7
|
||||||
@@ -4,6 +4,7 @@ mod quick_sort;
|
|||||||
mod ssc;
|
mod ssc;
|
||||||
mod util;
|
mod util;
|
||||||
|
|
||||||
|
use std::cmp::min;
|
||||||
use crate::util::read_to_graph;
|
use crate::util::read_to_graph;
|
||||||
|
|
||||||
use crate::merge_sort::merge_sort_inversions;
|
use crate::merge_sort::merge_sort_inversions;
|
||||||
@@ -50,10 +51,12 @@ fn c1a4() {
|
|||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
fn c2a1() {
|
fn c2a1() {
|
||||||
|
// I have not checked in the graph file, because it has 70MB.
|
||||||
// let g = read_to_directed_graph("data/course_2_assignment_1.txt").unwrap();
|
// let g = read_to_directed_graph("data/course_2_assignment_1.txt").unwrap();
|
||||||
let g = read_to_directed_graph("data/course_2_assignment_1_test.txt").unwrap();
|
let g = read_to_directed_graph("data/course_2_assignment_1_test.txt").unwrap();
|
||||||
let s = ssc(g.0, g.1);
|
let sizes = ssc(g.0, g.1);
|
||||||
println!("{:?}", s);
|
let max_size = min(sizes.len(), 5);
|
||||||
|
println!("{:?}", &sizes[0..max_size]);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|||||||
91
src/ssc.rs
91
src/ssc.rs
@@ -1,47 +1,90 @@
|
|||||||
use crate::util::DirectedGraph;
|
use crate::util::DirectedGraph;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
fn dfs(mut g: &mut DirectedGraph, node: usize, mut time: &mut usize) -> () {
|
fn dfs(g: &mut DirectedGraph, node: usize, time: &mut usize) -> () {
|
||||||
|
let mut nodes: Vec<(usize, usize)> = vec![(node, 0)];
|
||||||
g.explored[node] = true;
|
g.explored[node] = true;
|
||||||
for i in 0..g.nodes[node].len() {
|
|
||||||
let j = g.nodes[node][i];
|
while nodes.len() > 0 {
|
||||||
if !g.explored[j] {
|
let (mut current_node, mut current_edge) = nodes.pop().unwrap();
|
||||||
dfs(&mut g, j, &mut time);
|
while current_edge < g.nodes[current_node].len() {
|
||||||
|
let next_node = g.nodes[current_node][current_edge];
|
||||||
|
if !g.explored[next_node] {
|
||||||
|
nodes.push((current_node, current_edge + 1));
|
||||||
|
current_node = next_node;
|
||||||
|
current_edge = 0;
|
||||||
|
g.explored[current_node] = true;
|
||||||
|
} else {
|
||||||
|
current_edge += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*time += 1;
|
*time += 1;
|
||||||
g.time[node] = *time;
|
g.time[current_node] = *time;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ssc(g: DirectedGraph, mut g_dash: DirectedGraph) -> u32 {
|
fn second_dfs(g: &mut DirectedGraph, node: usize, leader: usize) -> () {
|
||||||
let mut time: usize = 0;
|
let mut nodes: Vec<(usize, usize)> = vec![(node, 0)];
|
||||||
println!("ssc");
|
g.explored[node] = true;
|
||||||
|
g.leader[node] = leader;
|
||||||
|
while nodes.len() > 0 {
|
||||||
|
let (mut current_node, mut current_edge) = nodes.pop().unwrap();
|
||||||
|
while current_edge < g.nodes[current_node].len() {
|
||||||
|
let next_node = g.nodes[current_node][current_edge];
|
||||||
|
if !g.explored[next_node] {
|
||||||
|
nodes.push((current_node, current_edge + 1));
|
||||||
|
current_node = next_node;
|
||||||
|
current_edge = 0;
|
||||||
|
g.leader[current_node] = leader;
|
||||||
|
g.explored[current_node] = true;
|
||||||
|
} else {
|
||||||
|
current_edge += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ssc(mut g: DirectedGraph, mut g_dash: DirectedGraph) -> Vec<usize> {
|
||||||
|
println!("1. start first dfs");
|
||||||
|
let mut time: usize = 0;
|
||||||
for i in (0..g_dash.nodes.len()).rev() {
|
for i in (0..g_dash.nodes.len()).rev() {
|
||||||
if !g_dash.explored[i] {
|
if !g_dash.explored[i] {
|
||||||
dfs(&mut g_dash, i, &mut time);
|
dfs(&mut g_dash, i, &mut time);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("finished first dfs");
|
println!("2. create time to index mapping");
|
||||||
|
|
||||||
let mut time_to_index: Vec<usize> = vec![0; g.nodes.len()];
|
let mut time_to_index: Vec<usize> = vec![0; g.nodes.len()];
|
||||||
|
for node in 0..g_dash.nodes.len() {
|
||||||
for i in 0..g_dash.nodes.len() {
|
time_to_index[g_dash.time[node] - 1] = node;
|
||||||
time_to_index[g_dash.time[i] - 1] = i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("finish time look-up");
|
println!("3. start second dfs");
|
||||||
|
for time in (0..time_to_index.len()).rev() {
|
||||||
for i in (0..time_to_index.len()).rev() {
|
let node = time_to_index[time];
|
||||||
let _node = time_to_index[i];
|
if !g.explored[node] {
|
||||||
// println!("time: {:?} node: {:?}", i, node);
|
second_dfs(&mut g, node, node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("finished second dfs");
|
println!("4. print results");
|
||||||
|
let mut leader_size: HashMap<usize, usize> = HashMap::new();
|
||||||
for i in 0..g_dash.nodes.len() {
|
for node in 0..g.nodes.len() {
|
||||||
println!("f({})={}", i + 1, g_dash.time[i]);
|
let leader = g.leader[node];
|
||||||
|
let leader_size = leader_size.entry(leader).or_insert(0);
|
||||||
|
*leader_size += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
0
|
let mut sizes: Vec<usize> = leader_size.values().cloned().collect();
|
||||||
|
sizes.sort();
|
||||||
|
sizes.reverse();
|
||||||
|
|
||||||
|
// For debugging the finish time and leader functions.
|
||||||
|
// for i in 0..g_dash.nodes.len() {
|
||||||
|
// println!("f({})={}", i + 1, g_dash.time[i]);
|
||||||
|
// }
|
||||||
|
// for i in 0..g.nodes.len() {
|
||||||
|
// println!("leader({})={}", i + 1, g.leader[i] + 1);
|
||||||
|
// }
|
||||||
|
sizes
|
||||||
}
|
}
|
||||||
|
|||||||
34
src/util.rs
34
src/util.rs
@@ -14,6 +14,7 @@ pub struct DirectedGraph {
|
|||||||
pub nodes: Vec<Vec<usize>>,
|
pub nodes: Vec<Vec<usize>>,
|
||||||
pub explored: Vec<bool>,
|
pub explored: Vec<bool>,
|
||||||
pub time: Vec<usize>,
|
pub time: Vec<usize>,
|
||||||
|
pub leader: Vec<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_to_vector(path: &str) -> Result<Vec<i64>, io::Error> {
|
pub fn read_to_vector(path: &str) -> Result<Vec<i64>, io::Error> {
|
||||||
@@ -59,19 +60,36 @@ pub fn read_to_graph(path: &str) -> Result<Graph, io::Error> {
|
|||||||
Ok(g)
|
Ok(g)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_node_size(path: &str) -> Result<usize, io::Error> {
|
||||||
|
let mut node_size = 0;
|
||||||
|
let file = File::open(path)?;
|
||||||
|
let br = BufReader::new(file);
|
||||||
|
|
||||||
|
for line in br.lines() {
|
||||||
|
let line = line?;
|
||||||
|
let mut nodes = line.split_whitespace();
|
||||||
|
let node: usize = nodes.next().unwrap().parse().unwrap();
|
||||||
|
if node > node_size {
|
||||||
|
node_size = node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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<(DirectedGraph, DirectedGraph), io::Error> {
|
||||||
const NODES: usize = 9;
|
let nodes: usize = get_node_size(path).unwrap();
|
||||||
// const NODES: usize = 875714;
|
|
||||||
let mut g = DirectedGraph {
|
let mut g = DirectedGraph {
|
||||||
nodes: vec![vec![]; NODES],
|
nodes: vec![vec![]; nodes],
|
||||||
explored: vec![false; NODES],
|
explored: vec![false; nodes],
|
||||||
time: vec![0; NODES],
|
time: vec![0; nodes],
|
||||||
|
leader: vec![0; nodes],
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut g_dash = DirectedGraph {
|
let mut g_dash = DirectedGraph {
|
||||||
nodes: vec![vec![]; NODES],
|
nodes: vec![vec![]; nodes],
|
||||||
explored: vec![false; NODES],
|
explored: vec![false; nodes],
|
||||||
time: vec![0; NODES],
|
time: vec![0; nodes],
|
||||||
|
leader: vec![0; nodes],
|
||||||
};
|
};
|
||||||
|
|
||||||
let file = File::open(path)?;
|
let file = File::open(path)?;
|
||||||
|
|||||||
Reference in New Issue
Block a user