为什么我的 Rust StackDFS 实现会产生不正确的结果?
Why does my Rust StackDFS implementation produce incorrect results?
我正在阅读 Luridas 关于算法的书,现在我在第 2 章尝试实现 StackDFS 函数。这个函数的目的是“访问”图中的每一个元素。
书中的算法:
StackDFS(G, node)→visited
//Input: G = (V,E), a graph
//node, the starting vertex in G
//Output: visited, an array of size |V | such that visited[i] is true if we
//have visited node i, false otherwise
1 S ←CreateStack()
2 visited ←CreateArray(|V |)
3 for i ←0 to |V | do
4 visited[i] ← false
5 Push(S, node)
6 while not IsStackEmpty(S) do
7 c ←Pop(s)
8 visited[c] ← true
9 foreach v in AdjacencyList(G, c) do
10 if not visited[v] then
11 Push(S, v)
12 return visited
我的代码:
use petgraph::graph::NodeIndex;
use petgraph::Undirected;
fn main() {
let mut new = petgraph::Graph::<i32, (i32, i32), Undirected>::new_undirected();
new.extend_with_edges(&[(0, 1), (0, 3), (1, 2), (2, 4)]);
let index = 2;
let mut visited = Vec::new();
for i in 0..new.node_count() {
visited.push(false);
}
StackDFS(&mut new, &index, &mut visited);
}
fn StackDFS<T>(G: &petgraph::Graph<T, (T, T), Undirected>, node: &usize, visited: &mut Vec<bool>) {
let mut s: Vec<usize> = Vec::with_capacity(G.node_count());
// for i in 0..G.node_count(){
// visited.push(false);
//}
s.push(*node);
while s.is_empty() == false {
let c = s.pop().unwrap();
visited[c] = true;
for el in G.neighbors(NodeIndex::new(*node)) {
if visited[el.index()] == false {
s.push(el.index());
}
}
}
println!("{:?}", visited);
}
我得到的输出:
[false, true, true, false, true]
我期望的输出:
[true, true, true, true, true]
我使用了 Vec
而不是堆栈,但我不认为这是问题所在,因为 Vec
可以提供与堆栈相同的功能。
for el in G.neighbors(NodeIndex::new(*node)) {
您总是在访问同一个起始节点的邻居。你应该得到当前处理节点的邻居。
改进版本:
use petgraph::{graph::NodeIndex, Undirected}; // 0.6.0
fn main() {
let mut new = petgraph::Graph::<i32, (i32, i32), Undirected>::new_undirected();
new.extend_with_edges(&[(0, 1), (0, 3), (1, 2), (2, 4)]);
let index = 2;
let mut visited = vec![false; new.node_count()];
stack_dfs(&new, index, &mut visited);
}
fn stack_dfs<T>(
g: &petgraph::Graph<T, (T, T), Undirected>,
start_node: usize,
visited: &mut Vec<bool>,
) {
let mut s = Vec::with_capacity(g.node_count());
s.push(start_node);
while let Some(node) = s.pop() {
visited[node] = true;
for el in g.neighbors(NodeIndex::new(node)) {
let idx = el.index();
if !visited[idx] {
s.push(idx);
}
}
}
println!("{:?}", visited);
}
我正在阅读 Luridas 关于算法的书,现在我在第 2 章尝试实现 StackDFS 函数。这个函数的目的是“访问”图中的每一个元素。
书中的算法:
StackDFS(G, node)→visited
//Input: G = (V,E), a graph
//node, the starting vertex in G
//Output: visited, an array of size |V | such that visited[i] is true if we
//have visited node i, false otherwise
1 S ←CreateStack()
2 visited ←CreateArray(|V |)
3 for i ←0 to |V | do
4 visited[i] ← false
5 Push(S, node)
6 while not IsStackEmpty(S) do
7 c ←Pop(s)
8 visited[c] ← true
9 foreach v in AdjacencyList(G, c) do
10 if not visited[v] then
11 Push(S, v)
12 return visited
我的代码:
use petgraph::graph::NodeIndex;
use petgraph::Undirected;
fn main() {
let mut new = petgraph::Graph::<i32, (i32, i32), Undirected>::new_undirected();
new.extend_with_edges(&[(0, 1), (0, 3), (1, 2), (2, 4)]);
let index = 2;
let mut visited = Vec::new();
for i in 0..new.node_count() {
visited.push(false);
}
StackDFS(&mut new, &index, &mut visited);
}
fn StackDFS<T>(G: &petgraph::Graph<T, (T, T), Undirected>, node: &usize, visited: &mut Vec<bool>) {
let mut s: Vec<usize> = Vec::with_capacity(G.node_count());
// for i in 0..G.node_count(){
// visited.push(false);
//}
s.push(*node);
while s.is_empty() == false {
let c = s.pop().unwrap();
visited[c] = true;
for el in G.neighbors(NodeIndex::new(*node)) {
if visited[el.index()] == false {
s.push(el.index());
}
}
}
println!("{:?}", visited);
}
我得到的输出:
[false, true, true, false, true]
我期望的输出:
[true, true, true, true, true]
我使用了 Vec
而不是堆栈,但我不认为这是问题所在,因为 Vec
可以提供与堆栈相同的功能。
for el in G.neighbors(NodeIndex::new(*node)) {
您总是在访问同一个起始节点的邻居。你应该得到当前处理节点的邻居。
改进版本:
use petgraph::{graph::NodeIndex, Undirected}; // 0.6.0
fn main() {
let mut new = petgraph::Graph::<i32, (i32, i32), Undirected>::new_undirected();
new.extend_with_edges(&[(0, 1), (0, 3), (1, 2), (2, 4)]);
let index = 2;
let mut visited = vec![false; new.node_count()];
stack_dfs(&new, index, &mut visited);
}
fn stack_dfs<T>(
g: &petgraph::Graph<T, (T, T), Undirected>,
start_node: usize,
visited: &mut Vec<bool>,
) {
let mut s = Vec::with_capacity(g.node_count());
s.push(start_node);
while let Some(node) = s.pop() {
visited[node] = true;
for el in g.neighbors(NodeIndex::new(node)) {
let idx = el.index();
if !visited[idx] {
s.push(idx);
}
}
}
println!("{:?}", visited);
}