mirror of
https://github.com/aziis98/asd-2024.git
synced 2026-10-06 14:44:59 +00:00
push to github
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
# code
|
||||
import random
|
||||
# Algorithm from GeeksforGeeks (wrong)
|
||||
# https://www.geeksforgeeks.org/tree-back-edge-and-cross-edges-in-dfs-of-graph/
|
||||
|
||||
import random
|
||||
|
||||
class Graph:
|
||||
# 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:
|
||||
def __init__(self):
|
||||
self.parent = {}
|
||||
|
||||
+93
-85
@@ -22,93 +22,101 @@ where
|
||||
V: Hash + Eq + Clone + Debug,
|
||||
{
|
||||
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 visited = HashSet::new();
|
||||
let mut start_times = HashMap::new();
|
||||
let mut finished_nodes = HashSet::new();
|
||||
// TODO: ...
|
||||
|
||||
let mut time = 0;
|
||||
|
||||
let progress_bar = ProgressBar::new(self.nodes().len() as u64);
|
||||
|
||||
for node in self.nodes().iter() {
|
||||
if visited.contains(node) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let mut stack = Vec::new();
|
||||
|
||||
stack.push(RecurseState::Before(node));
|
||||
|
||||
while let Some(state) = stack.pop() {
|
||||
match state {
|
||||
RecurseState::Before(node) => {
|
||||
progress_bar.inc(1);
|
||||
visited.insert(node.clone());
|
||||
start_times.insert(node, time);
|
||||
time += 1;
|
||||
|
||||
// this is extremely important that is before the adjacencies to correctly
|
||||
// iterate over the graph
|
||||
|
||||
if let Some(adjacencies) = self.get_adjacencies(node) {
|
||||
for adj in adjacencies {
|
||||
println!("Node: {:?} Adj: {:?}", node, adj,);
|
||||
|
||||
stack.push(RecurseState::AfterNeighbor(node));
|
||||
|
||||
if !visited.contains(adj) {
|
||||
edge_types.insert((node, adj), EdgeType::TreeEdge);
|
||||
stack.push(RecurseState::Before(adj));
|
||||
} else {
|
||||
stack.push(RecurseState::BeforeNeighbor(node, adj));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
RecurseState::AfterNeighbor(node) => {
|
||||
finished_nodes.insert(node, time);
|
||||
time += 1;
|
||||
}
|
||||
RecurseState::BeforeNeighbor(node, adj) => {
|
||||
let start_time_node = start_times.get(node).unwrap();
|
||||
let start_time_adj = start_times.get(adj).unwrap();
|
||||
let end_time_node = finished_nodes.get(node).unwrap_or(&0);
|
||||
let end_time_adj = finished_nodes.get(adj).unwrap_or(&0);
|
||||
|
||||
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),
|
||||
) {
|
||||
(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
|
||||
return edge_types;
|
||||
}
|
||||
|
||||
// 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 visited = HashSet::new();
|
||||
// let mut start_times = HashMap::new();
|
||||
// let mut finished_nodes = HashSet::new();
|
||||
|
||||
// let mut time = 0;
|
||||
|
||||
// let progress_bar = ProgressBar::new(self.nodes().len() as u64);
|
||||
|
||||
// for node in self.nodes().iter() {
|
||||
// if visited.contains(node) {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// let mut stack = Vec::new();
|
||||
|
||||
// stack.push(RecurseState::Before(node));
|
||||
|
||||
// while let Some(state) = stack.pop() {
|
||||
// match state {
|
||||
// RecurseState::Before(node) => {
|
||||
// progress_bar.inc(1);
|
||||
// visited.insert(node.clone());
|
||||
// start_times.insert(node, time);
|
||||
// time += 1;
|
||||
|
||||
// // it is extremely important that this before the adjacencies to correctly
|
||||
// // iterate over the graph
|
||||
|
||||
// if let Some(adjacencies) = self.get_adjacencies(node) {
|
||||
// for adj in adjacencies {
|
||||
// println!("Node: {:?} Adj: {:?}", node, adj,);
|
||||
|
||||
// stack.push(RecurseState::AfterNeighbor(node));
|
||||
|
||||
// if !visited.contains(adj) {
|
||||
// edge_types.insert((node, adj), EdgeType::TreeEdge);
|
||||
// stack.push(RecurseState::Before(adj));
|
||||
// } else {
|
||||
// stack.push(RecurseState::BeforeNeighbor(node, adj));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// RecurseState::AfterNeighbor(node) => {
|
||||
// finished_nodes.insert(node);
|
||||
// time += 1;
|
||||
// }
|
||||
// RecurseState::BeforeNeighbor(node, adj) => {
|
||||
// let start_time_node = start_times.get(node).unwrap();
|
||||
// let start_time_adj = start_times.get(adj).unwrap();
|
||||
// let end_time_node = finished_nodes.get(node).unwrap_or(&0);
|
||||
// let end_time_adj = finished_nodes.get(adj).unwrap_or(&0);
|
||||
|
||||
// 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),
|
||||
// ) {
|
||||
// (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
|
||||
// }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user