简体   繁体   English

计算有向图中长度为 n 的循环数

[英]count number of cycles with length n in a directed graph

I have searched for a while and found multiple algorithms to detect cycle in directed graphs, but I am interested to determine the length of cycle.我搜索了一段时间,发现了多种算法来检测有向图中的循环,但我有兴趣确定循环的长度。

on the other hand there is also algorithm that works only for undirected graphs here .另一方面,这里也有仅适用于无向图算法。

def DFS(V, graph, marked, n, vert, start, count):
    """
    Python Program to count cycles of length n in a given graph.
    """

    # mark the vertex vert as visited
    marked[vert] = True

    # if the path of length (n-1) is found
    if n == 0:

        # mark vert as un-visited to make it usable again.
        marked[vert] = False

        # Check if vertex vert can end with vertex start
        if graph[vert][start] == 1:
            count = count + 1
            return count
        else:
            return count

    # For searching every possible path of length (n-1)
    for i in range(V):
        if marked[i] == False and graph[vert][i] == 1:

            # DFS for searching path by decreasing length by 1
            count = DFS(V, graph, marked, n-1, i, start, count)

    # marking vert as unvisited to make it usable again.
    marked[vert] = False
    return count


def countCycles(graph, n, V):
    '''Counts cycles of length N in an undirected
    and connected graph.
    '''

    # all vertex are marked un-visited initially.
    marked = [False] * V

    # Searching for cycle by using v-n+1 vertices
    count = 0
    for i in range(V-(n-1)):
        count = DFS(V, graph, marked, n-1, i, i, count)

        # ith vertex is marked as visited and
        # will not be visited again.
        marked[i] = True

    return int(count/2)

V = 5 # number of vertex
adj0 = np.array([[0, 1, 0, 1, 1],
                 [1, 0, 1, 1, 0],
                 [0, 1, 0, 1, 0],
                 [1, 1, 1, 0, 1],
                 [1, 0, 0, 1, 0]])

for i in [3, 4]:
    print(f"number of cycle with length {i} is" , helpers.countCycles(adj0.tolist(), i, V))

# number of cycle with length 3 is 3
# number of cycle with length 4 is 2

How to combine these to have an algorithm to look for a cycle with determined length?如何将这些结合起来有一个算法来寻找一个确定长度的循环?

在此处输入图像描述

Start with an adjacency matrix M such that there is a 1 at row j, column i if there is an arc from vertex i to vertex j, and 0 otherwise.从邻接矩阵M开始,如果从顶点 i 到顶点 j 有一条弧,则在 j 行和第 i 列有 1,否则为 0。 Note the ordering -- each vertex's arcs are represented by a column in this matrix, so it's the transpose of the more common row-major order for adjacency matrices.注意排序——每个顶点的弧由这个矩阵中的一表示,所以它是邻接矩阵更常见的行主顺序的转置。

Now, If we define a vertex vector V i to be a column vector that has a 1 in row i and 0 everywhere else, then the product MV i gives the number of ways that you can get from vertex i to every other vertex in one step .现在,如果我们将顶点向量V i定义为在第 i 行中具有 1 并且在其他所有位置具有 0 的列向量,那么乘积MV i给出了您可以从顶点 i 到每个其他顶点的方式 The sum of the diagonal elements is the number of length-1 cycles .对角线元素的总和是长度为 1 的循环数

Using matrix exponentiation-by-squaring , you can calculate M n in O(|V| 3 log n) time†.使用矩阵乘方求幂,您可以在 O(|V| 3 log n) 时间内计算M n †。 For every vertex vector, then M n V i gives the number of ways you can get from vertex i to every other vertex in n steps , and the sum of the diagonal elements of M n is the total number of length-n cycles .对于每个顶点向量,然后M n V i给出了您可以在n 步中从顶点 i 到达每个其他顶点的方式数,并且M n的对角线元素的总和是长度-n 个循环的总数

† - caveat: the O(|V| 3 log n) time assumes constant times for mathematical operations, which is not necessarily true, since the numbers involved can get very large. † - 警告:O(|V| 3 log n) 时间假定数学运算的时间是恒定的,这不一定是真的,因为所涉及的数字可能会变得非常大。

Performance note.性能说明。 Set n to be the size of the graph, and you have the Hamiltonian Cycle problem .n设置为图形的大小,您就有了哈密顿循环问题 This is well-known to be NP-complete.众所周知,这是 NP 完全的。 Conversely this means that, even if you were told the n points that contain the cycle, verifying that there is a cycle of length n in those points is still hard.相反,这意味着,即使你被告知包含循环的n个点,验证这些点中是否存在长度为n的循环仍然很困难。

Therefore while producing a correct algorithm isn't that hard, producing an efficient one is a different story.因此,虽然产生一个正确的算法并不难,但产生一个有效的算法是另一回事。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM