master > master: code-rust - algorithmus sauberer + Kommentare
This commit is contained in:
parent
859a779ba5
commit
d5a79e77ce
@ -35,51 +35,48 @@ pub fn tarjan_algorithm<T>(gph: &Graph<T>, debug: bool) -> Vec<Vec<T>>
|
|||||||
let mut ctx = Context::new(&gph, debug);
|
let mut ctx = Context::new(&gph, debug);
|
||||||
|
|
||||||
for u in gph.nodes.iter() {
|
for u in gph.nodes.iter() {
|
||||||
tarjan_visit(gph, u, &mut ctx);
|
if ctx.get_state(&u) == State::UNTOUCHED {
|
||||||
|
tarjan_visit(gph, &u, &mut ctx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ctx.components;
|
return ctx.components;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// recursive depth-first search algorithm to compute components
|
/// Recursive depth-first search algorithm to compute strongly components of a graph.
|
||||||
fn tarjan_visit<T>(gph: &Graph<T>, v: &T, ctx: &mut Context<T>)
|
fn tarjan_visit<T>(gph: &Graph<T>, &u: &T, ctx: &mut Context<T>)
|
||||||
where T: Eq + Hash + Clone + Copy + Display
|
where T: Eq + Hash + Clone + Copy + Display
|
||||||
{
|
{
|
||||||
// do nothing, if v already visited
|
// Place node on stack + initialise visit-index + component-index.
|
||||||
if !(ctx.get_state(v) == State::UNTOUCHED) { return; }
|
ctx.max_index += 1;
|
||||||
|
ctx.push(&u);
|
||||||
|
ctx.set_root(&u, ctx.max_index);
|
||||||
|
ctx.set_index(&u, ctx.max_index);
|
||||||
|
ctx.set_state(&u, State::PENDING);
|
||||||
|
|
||||||
/****************
|
/****************
|
||||||
* First visit of v.
|
* Compute strongly connected components of each child node.
|
||||||
* - Place v on stack.
|
* NOTE: Child nodes remain on stack, if and only if parent is in same component.
|
||||||
* - Initialise visit-index + component-index.
|
|
||||||
* - After each rekursiv call, only those all
|
|
||||||
****************/
|
****************/
|
||||||
ctx.max_index += 1;
|
for v in gph.successors(&u) {
|
||||||
ctx.push(v);
|
// Visit child node only if untouched:
|
||||||
ctx.set_root(v, ctx.max_index);
|
if ctx.get_state(&v) == State::UNTOUCHED {
|
||||||
ctx.set_index(v, ctx.max_index);
|
tarjan_visit(gph, &v, ctx);
|
||||||
ctx.set_state(v, State::PENDING);
|
}
|
||||||
|
// Update associated component-index of parent node, if in same component as child:
|
||||||
// depth first search:
|
if ctx.stack.contains(&v) {
|
||||||
for u in gph.successors(&v) {
|
ctx.set_root(&u, value_min!(ctx.get_root(&u), ctx.get_root(&v)));
|
||||||
tarjan_visit(gph, &u, ctx);
|
|
||||||
/****
|
|
||||||
* u is in the same component as v, if and only if u is still on the stack.
|
|
||||||
* In this case, update the associated component-index of v:
|
|
||||||
****/
|
|
||||||
if ctx.stack.contains(&u) {
|
|
||||||
ctx.set_root(v, value_min!(ctx.get_root(v), ctx.get_root(&u)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ctx.set_state(v, State::FINISHED);
|
ctx.set_state(&u, State::FINISHED);
|
||||||
ctx.log_info(&v);
|
ctx.log_info(&u);
|
||||||
|
|
||||||
if ctx.get_index(v) == ctx.get_root(v) {
|
if ctx.get_index(&u) == ctx.get_root(&u) {
|
||||||
let mut component: Vec<T> = Vec::new();
|
let mut component: Vec<T> = Vec::new();
|
||||||
loop {
|
loop {
|
||||||
let u = ctx.top();
|
let v = ctx.top();
|
||||||
ctx.pop();
|
ctx.pop();
|
||||||
component.push(u.clone());
|
component.push(v.clone());
|
||||||
if u == *v { break; }
|
if u == v { break; }
|
||||||
}
|
}
|
||||||
ctx.components.push(component);
|
ctx.components.push(component);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user