push to github

main
Antonio De Lucreziis 4 weeks ago
parent e3b5d1f7da
commit 509f0a54e8

@ -1,6 +1,7 @@
# code # Algorithm from GeeksforGeeks (wrong)
import random # https://www.geeksforgeeks.org/tree-back-edge-and-cross-edges-in-dfs-of-graph/
import random
class Graph: class Graph:
# instance variables # instance variables

@ -1,3 +1,6 @@
# Algorithm from MIT OpenCourseWare (seems correct)
# https://courses.csail.mit.edu/6.006/fall11/rec/rec14.pdf
class DFSResult: class DFSResult:
def __init__(self): def __init__(self):
self.parent = {} self.parent = {}

@ -22,93 +22,101 @@ where
V: Hash + Eq + Clone + Debug, V: Hash + Eq + Clone + Debug,
{ {
pub fn compute_edge_types(&self) -> HashMap<(&V, &V), EdgeType> { pub fn compute_edge_types(&self) -> HashMap<(&V, &V), EdgeType> {
/// To correctly compute the start and end times of the nodes in the
/// graph, we need to keep do work before and after the recursion call
enum RecurseState<'a, V> {
Before(&'a V),
BeforeNeighbor(&'a V, &'a V),
AfterNeighbor(&'a V),
}
let mut edge_types = HashMap::new(); let mut edge_types = HashMap::new();
let mut visited = HashSet::new(); // TODO: ...
let mut start_times = HashMap::new();
let mut finished_nodes = HashSet::new(); return edge_types;
}
let mut time = 0;
// pub fn compute_edge_types(&self) -> HashMap<(&V, &V), EdgeType> {
let progress_bar = ProgressBar::new(self.nodes().len() as u64); // /// To correctly compute the start and end times of the nodes in the
// /// graph, we need to keep do work before and after the recursion call
for node in self.nodes().iter() { // enum RecurseState<'a, V> {
if visited.contains(node) { // Before(&'a V),
continue; // BeforeNeighbor(&'a V, &'a V),
} // AfterNeighbor(&'a V),
// }
let mut stack = Vec::new();
// let mut edge_types = HashMap::new();
stack.push(RecurseState::Before(node));
// let mut visited = HashSet::new();
while let Some(state) = stack.pop() { // let mut start_times = HashMap::new();
match state { // let mut finished_nodes = HashSet::new();
RecurseState::Before(node) => {
progress_bar.inc(1); // let mut time = 0;
visited.insert(node.clone());
start_times.insert(node, time); // let progress_bar = ProgressBar::new(self.nodes().len() as u64);
time += 1;
// for node in self.nodes().iter() {
// this is extremely important that is before the adjacencies to correctly // if visited.contains(node) {
// iterate over the graph // continue;
// }
if let Some(adjacencies) = self.get_adjacencies(node) {
for adj in adjacencies { // let mut stack = Vec::new();
println!("Node: {:?} Adj: {:?}", node, adj,);
// stack.push(RecurseState::Before(node));
stack.push(RecurseState::AfterNeighbor(node));
// while let Some(state) = stack.pop() {
if !visited.contains(adj) { // match state {
edge_types.insert((node, adj), EdgeType::TreeEdge); // RecurseState::Before(node) => {
stack.push(RecurseState::Before(adj)); // progress_bar.inc(1);
} else { // visited.insert(node.clone());
stack.push(RecurseState::BeforeNeighbor(node, adj)); // start_times.insert(node, time);
} // time += 1;
}
} // // it is extremely important that this before the adjacencies to correctly
} // // iterate over the graph
RecurseState::AfterNeighbor(node) => {
finished_nodes.insert(node, time); // if let Some(adjacencies) = self.get_adjacencies(node) {
time += 1; // for adj in adjacencies {
} // println!("Node: {:?} Adj: {:?}", node, adj,);
RecurseState::BeforeNeighbor(node, adj) => {
let start_time_node = start_times.get(node).unwrap(); // stack.push(RecurseState::AfterNeighbor(node));
let start_time_adj = start_times.get(adj).unwrap();
let end_time_node = finished_nodes.get(node).unwrap_or(&0); // if !visited.contains(adj) {
let end_time_adj = finished_nodes.get(adj).unwrap_or(&0); // edge_types.insert((node, adj), EdgeType::TreeEdge);
// stack.push(RecurseState::Before(adj));
println!( // } else {
"Times: ({:?}, {:?}) ({:?}, {:?})", // stack.push(RecurseState::BeforeNeighbor(node, adj));
start_time_node, end_time_node, start_time_adj, end_time_adj // }
); // }
// }
match ( // }
start_time_node.cmp(start_time_adj), // RecurseState::AfterNeighbor(node) => {
end_time_node.cmp(end_time_adj), // finished_nodes.insert(node);
) { // time += 1;
(Ordering::Less, Ordering::Greater) => { // }
edge_types.insert((node, adj), EdgeType::ForwardEdge); // RecurseState::BeforeNeighbor(node, adj) => {
} // let start_time_node = start_times.get(node).unwrap();
(Ordering::Greater, Ordering::Less) => { // let start_time_adj = start_times.get(adj).unwrap();
edge_types.insert((node, adj), EdgeType::BackEdge); // let end_time_node = finished_nodes.get(node).unwrap_or(&0);
} // let end_time_adj = finished_nodes.get(adj).unwrap_or(&0);
_ => {
edge_types.insert((node, adj), EdgeType::CrossEdge); // println!(
} // "Times: ({:?}, {:?}) ({:?}, {:?})",
} // start_time_node, end_time_node, start_time_adj, end_time_adj
} // );
}
} // match (
} // start_time_node.cmp(start_time_adj),
// end_time_node.cmp(end_time_adj),
edge_types // ) {
} // (Ordering::Less, Ordering::Greater) => {
// edge_types.insert((node, adj), EdgeType::ForwardEdge);
// }
// (Ordering::Greater, Ordering::Less) => {
// edge_types.insert((node, adj), EdgeType::BackEdge);
// }
// _ => {
// edge_types.insert((node, adj), EdgeType::CrossEdge);
// }
// }
// }
// }
// }
// }
// edge_types
// }
} }

Loading…
Cancel
Save