Algorithm 图表:计算包含节点的循环数
我想计算非有向图中节点所属的圈数 这些循环可以在它们之间共享节点。这两项都很重要:Algorithm 图表:计算包含节点的循环数,algorithm,graph,Algorithm,Graph,我想计算非有向图中节点所属的圈数 这些循环可以在它们之间共享节点。这两项都很重要: A -> B -> A A -> B -> C -> A 我已经试了一段时间了。我当前的实现计算周期两次:一次走一次,然后另一次走一次。它可能还有其他bug 这是查找路径的递归函数(从countCycles包装): 如果唯一的问题是循环计数两次,我可以将结果减半,但我希望每个循环只行走一次。同样的算法可能适用于其他方面。这是一个模棱两可的问题。如果一个图有圈,它可以有无限多条路径
A -> B -> A
A -> B -> C -> A
我已经试了一段时间了。我当前的实现计算周期两次:一次走一次,然后另一次走一次。它可能还有其他bug
这是查找路径的递归函数(从countCycles
包装):
如果唯一的问题是循环计数两次,我可以将结果减半,但我希望每个循环只行走一次。同样的算法可能适用于其他方面。这是一个模棱两可的问题。如果一个图有圈,它可以有无限多条路径 一般来说,所有可能路径问题都是NP难问题,并且可能有大量的路径,即使对于小图也是如此 一般策略是将广度优先搜索与队列或某些其他机制结合使用,这些机制只存储当前分支的访问节点 有关更多信息,请参见这里是我的
O(VE^2)
算法,其中V
是顶点数,E
是边数。它不是递归算法
(1) Initialize table `m` for the base case of set `{1,2,3}`. I'll assume you can do this.
(2) For each time you add a vertex `A` into consideration, do the following:
(2.1) Update the cycle count
For every (B,C) pair of vertices that are both adjacent to vertex A
[Meaning we have a path (B,A,C)]
that the table m has an entry of path (B,...,1,...,C)
We can deduce that there is a simple cycle (A,B,...,1,...C,A).
count it.
(2.2) Update the table m
For every vertex X that is adjacent to A and there is a path (X,...,1,...,Y)
Remember that there is a path (A,...,1,...,Y) into table m.
我将顶点编号从1到V
。其中,1将始终是问题中必须在计数循环中出现的顶点
草图是:
我将计算所有顶点的较小子集内的循环,并逐渐添加更多的顶点。
也就是说,从集合{1,2,3}
您需要维护的内容:
m[x][y]
一个大小为vxv
的布尔表
已发现通过顶点1
的简单路径,该路径具有x
和y
以及路径的端点。简单路径我指的是路径
没有重复的顶点(1) Initialize table `m` for the base case of set `{1,2,3}`. I'll assume you can do this.
(2) For each time you add a vertex `A` into consideration, do the following:
(2.1) Update the cycle count
For every (B,C) pair of vertices that are both adjacent to vertex A
[Meaning we have a path (B,A,C)]
that the table m has an entry of path (B,...,1,...,C)
We can deduce that there is a simple cycle (A,B,...,1,...C,A).
count it.
(2.2) Update the table m
For every vertex X that is adjacent to A and there is a path (X,...,1,...,Y)
Remember that there is a path (A,...,1,...,Y) into table m.
算法描述完成
复杂性分析:
外环穿过每个顶点,因此乘以系数V
。
步骤(2.1)
穿过与A
相邻的每对边,因此乘以E^2
。
总的来说,
O(VE^2)
最后一段是一个真正的WTF。如果是我,我会再花一个小时来做这件事。我的老板不会这么高兴的。我们不知道出了什么问题,给我们看看你当前的(非工作)解决方案。在伪代码中,你的算法听起来是正确的,但你的代码可能是错误的。如果由于某个节点是另一个循环的一部分而拒绝重新访问该节点,则无法正确擦除标记。如果您不止一次走同一条路径,那么您没有正确地对节点的邻居进行迭代。你能为这些错误中的一个或两个做一个最小的例子吗?pSueDO代码使他只考虑没有重复节点的循环——一个简单的循环。对,这就是为什么我建议使用一个队列之类的数据结构来记住在当前分支上访问了哪些节点。所以,为什么是-1?我的答案是错误的还是格式不正确?我无法改进OP中的算法,使其不会两次遍历同一个循环。所以,我给出了一个不同的算法,它不会两次遍历同一个循环。我也不认为这离题。