我如何才能找到(遍历)有向图中从/到给定节点的所有周期?
例如,我想要这样的东西:
A->B->A
A->B->C->A
而不是: B - > C > B
我如何才能找到(遍历)有向图中从/到给定节点的所有周期?
例如,我想要这样的东西:
A->B->A
A->B->C->A
而不是: B - > C > B
当前回答
从节点X开始,检查所有子节点(如果无方向,父节点和子节点是等价的)。将这些子节点标记为X的子节点。对于任何这样的子节点A,标记它的子节点是A的子节点,X',其中X'标记为2步远。)如果您稍后点击X并将其标记为X的子节点”,这意味着X处于3节点周期中。回溯到它的父节点很容易(因为算法不支持这一点,所以你可以找到任何一个有X'的父节点)。
注意:如果图是无向的或者有任何双向边,这个算法会变得更复杂,假设你不想在一个周期内两次遍历同一条边。
其他回答
我曾经在面试中遇到过这样的问题,我怀疑你遇到过这种情况,你来这里寻求帮助。把这个问题分解成三个问题就容易多了。
如何确定下一个有效点 路线 你如何确定一个点是否存在 被使用 你如何避免越过 同样的观点
问题1) 使用迭代器模式提供迭代路由结果的方法。放置获取下一个路由的逻辑的一个好地方可能是迭代器的“moveNext”。要找到有效的路由,这取决于您的数据结构。对我来说,这是一个sql表充满有效的路由可能性,所以我必须建立一个查询,以获得有效的目的地给定的源。
问题2) 当您找到每个节点时,将它们推入一个集合,这意味着您可以通过动态询问正在构建的集合,很容易地查看是否在某个点上“返回”。
问题3) 如果在任何时候你看到你正在折回,你可以从集合中弹出东西并“后退”。然后从这一点开始,再次尝试“前进”。
黑客:如果你正在使用Sql Server 2008,有一些新的“层次结构”的东西,你可以用它来快速解决这个问题,如果你把你的数据结构成树状。
从节点X开始,检查所有子节点(如果无方向,父节点和子节点是等价的)。将这些子节点标记为X的子节点。对于任何这样的子节点A,标记它的子节点是A的子节点,X',其中X'标记为2步远。)如果您稍后点击X并将其标记为X的子节点”,这意味着X处于3节点周期中。回溯到它的父节点很容易(因为算法不支持这一点,所以你可以找到任何一个有X'的父节点)。
注意:如果图是无向的或者有任何双向边,这个算法会变得更复杂,假设你不想在一个周期内两次遍历同一条边。
从开始节点s开始的DFS,在遍历过程中跟踪DFS路径,如果在到s的路径中发现从节点v开始的边,则记录该路径。(v,s)是DFS树中的后边,因此表示包含s的周期。
CXXGraph库提供了一组检测周期的算法和函数。
要获得完整的算法解释,请访问wiki。
DFS c++版本的伪代码在二楼的答案:
void findCircleUnit(int start, int v, bool* visited, vector<int>& path) {
if(visited[v]) {
if(v == start) {
for(auto c : path)
cout << c << " ";
cout << endl;
return;
}
else
return;
}
visited[v] = true;
path.push_back(v);
for(auto i : G[v])
findCircleUnit(start, i, visited, path);
visited[v] = false;
path.pop_back();
}