【发布时间】:2013-08-25 11:12:35
【问题描述】:
鉴于以下深度优先搜索,为什么 ProcessEdge 方法中的检查 if(Parent[currVertex] != successorVertex) 会检测到循环?此代码遵循 S.Skiena 的 Algortim Design Manual 一书中给出的算法。支票可能是错字,应该是if(Parent[successorVertex] != currVertex)。请要求任何澄清。我真的被困在这个问题上。
public void Search(int start)
{
/* NOTE: the differences from BFS are: this uses a stack instead of a queue AND this maintains 'time' variable */
Stack<int> s = new Stack<int>();
int currVertex;
int successorVertex;
int time = 0;
s.Push(start);
Discovered[start] = true;
while (s.Count != 0)
{
currVertex = s.Pop();
// time increments every time we enter a node (when discovered) and every time we exit a node (when processed_late, i.e. when all its neighbours have been processed)
time++;
EntryTime[currVertex] = time;
ProcessVertexEarly(currVertex);
Processed[currVertex] = true;
for (int i = 0; i < Graph.Vertices[currVertex].Count; i++)
{
successorVertex = Graph.Vertices[currVertex][i].Y;
if (!Processed[successorVertex] || Graph.IsDirected)
{
ProcessEdge(currVertex, successorVertex);
}
if (!Discovered[successorVertex])
{
s.Push(successorVertex);
Discovered[successorVertex] = true;
Parent[successorVertex] = currVertex;
}
}
// time increments every time we enter a node (when discovered) and every time we exit a node (when processed_late, i.e. when all its neighbours have been processed)
time++;
ExitTime[currVertex] = time;
ProcessVertexLate(currVertex);
}
}
private void ProcessEdge(int currVertex, int successorVertex)
{
if(Parent[currVertex] != successorVertex) // then we've found a cycle
{
/* Found cycle*/
}
}
更新
在勘误表http://www.cs.sunysb.edu/~skiena/algorist/book/errata 中找到此代码的更正。请参阅 (*) 第 173 页,process_edge 程序——正确的测试应该是
if (discovered[y] && (parent[x] != y)) { /* found back edge */
但这会检测周期吗? if 检查永远不会通过,因为在 DFS 方法中,process_edge 仅在 discovered[y] == false 时被调用。
【问题讨论】:
-
回复您的更新:如果
y未被发现或未处理,Skiena 的dfs将调用process_edge。在探索离开它们的每条边之前,不会将顶点标记为已处理。
标签: algorithm graph depth-first-search