图表:计算包含节点的周期

时间:2014-06-17 17:04:12

标签: algorithm graph

我想计算非有向图中节点所属的周期数。

这些周期可以在它们之间共享节点。这两个都算得上:

A -> B -> A
A -> B -> C -> A

我已经尝试了一段时间了。我当前的实现计算两次循环:单向行走,然后是另一行。它可能有其他错误。

这是查找路径的递归函数(由countCycles包裹):

function countPaths(current, destination, visited: set) ->
    if visited.contains(current):
        if current is destination and visited.size > 2:
            return 1
        else
            return 0

    visited.add(current)
    count = 0

    for each neighbor of current:
        count += countPaths(neighbor, destination)

    visited.remove(current)
    return count

如果唯一的问题是周期被计算两次,我可以将结果减半,但我想每个周期只走一次。相同的算法可能对其他东西有好处。

2 个答案:

答案 0 :(得分:1)

这是一个含糊不清的问题。如果图形具有循环,则其中可以包含无限数量的路径。

一般来说,所有可能的路径问题都是NP难度,并且可能有非常多的路径,即使对于小图也是如此。

一般策略是将广度优先搜索结合使用队列或其他一些机制来存储仅当前分支的访问节点

有关详细信息,请参阅all possible paths problem

答案 1 :(得分:-1)

以下是我的O(VE^2)算法,其中V是顶点数,E是边数。它不是递归算法。

我将顶点从1编号为V。其中1将始终是问题中必须存在于计数周期中的顶点。

草图是: 我将计算所有顶点的较小子集内的循环,并逐渐添加更多顶点。 也就是说,从集合{1,2,3}

开始

您需要维护的事项:

  1. m[x][y]一个大小为V x V的布尔表,记住你是否 已经通过具有1的顶点x发现了简单路径y以及路径的终点。简单的路径我的意思是路径 没有重复顶点。
  2. 作为答案的周期计数
  3. 让我们开始算法。

    (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)