简体   繁体   English

有向图的最大简单循环

[英]Maximum Simple Cycle in Directed Graph

Maximum Simple Cycle (product) in a graph 图中的最大简单周期(乘积)

Hello, 你好,

I have constructed a directed graph G=(v,e) and I would like to find the maximum simple cycle in this graph, where edge weights are multiplied instead of added. 我构造了一个有向图G =(v,e),我想在此图中找到最大的简单循环,在该循环中,边权重被相乘而不是相加。 My initial method for doing so is to construct a new graph, G=(v,e'), where e'(i,j) = 1/e(i,j)/min(e'), and then to apply Floyd-Warshall on this graph to find all shortest paths. 我这样做的最初方法是构造一个新图G =(v,e'),其中e'(i,j)= 1 / e(i,j)/ min(e'),然后应用Floyd-Warshall在此图上查找所有最短路径。 My thoughts were that after inverting the graph, the maximum path would then become the minimum, and if we divide by the minimum value, all edge weights will be "positive" (>= 1, since we are multiplying instead of adding). 我的想法是,在反转图形之后,最大路径将变为最小,并且如果我们将其除以最小值,则所有边缘权重都将为“正”(> = 1,因为我们是相乘而不是相加)。 However, when I run the algorithm (my Python code is below) it seems to not work, and I'm wondering if it's because my algorithm won't work at all or if it's because of an error in my code. 但是,当我运行算法时(下面是我的Python代码),它似乎不起作用,我想知道这是因为我的算法根本不起作用,还是因为我的代码错误。

#construct G' = (V,dist) for our modified Floyd-Warshall algorithm
# edge weights are initially the inverse of w(u,v). They are then all divided
# by the minimum value to ensure all are >= 1
dist = {}
nxt = {}
minimum = float("inf")
for i in e:
    dist[i] = {}
    nxt[i] = {}
    for j in e[i]:
        dist[i][j] = 1/e[i][j]
        nxt[i][j] = j
        if dist[i][j] < minimum:
            minimum = dist[i][j]

for i in dist:
    for j in dist[i]:
        dist[i][j] /= minimum

# Perform Floyd-Warshall
for k in v:
    for i in v:
        for j in v:
            try:
                one = dist[i][j]
                two = dist[i][k]
                three = dist[k][j]
            except KeyError:
                continue

            if one > two * three:
                dist[i][j] = two * three
                nxt[i][j] = nxt[i][k]

# Find the shortest cycle using shortest paths
minimum = float("inf")
for i in v:
    for j in v:
        if i == j:
            continue
        try:
            one = dist[i][j]
            two = dist[j][i]
        except KeyError:
            continue

        if one * two < minimum:
            minimum = one * two
            pair = [i,j]

def Path(u,v):
    if nxt[u][v] == None:
        return []
    path = [u]
    while u != v:
        u = nxt[u][v]
        path.append(u)
    return path

# Format the cycle for output
p1 = Path(pair[0],pair[1])
p2 = Path(pair[1],pair[0])
p = p1 + p2[1:]
print(p)

# Find the total value of the cycle
value = 1
for i in range(len(p)-1):
    value *= e[p[i]][p[i+1]]

print('The above cycle has a %f%% weight.'  % ((value-1)*100))

I tested the above example with a graph G=(V,E), where 我用图形G =(V,E)测试了上面的示例,其中

V = {a,b,c,d}, and 
E = {
    (a,b): 1/0.00005718 * 0.9975, 
    (a,c): 1/0.03708270 * 0.9975,
    (a,d): 18590.00000016 * 0.9975, 
    (b,a): 0.00010711 * 0.9975,
    (b,c): 0.00386491 * 0.9975, 
    (c,a): 0.03700994 * 0.9975,
    (c,b): 1/18590.00000017 * 0.9975,
    (c,d): 688.30000000 * 0.9975,
    (d,a): 1/18590.00000017 * 0.9975,
    (d,c): 1/688.30000000 * 0.9975
}

The output with the above graph is that the cycle [a,d,a] is the best, with a 86.385309% weight. 上图的输出是周期[a,d,a]最好,权重为86.385309%。 However, as we can see, the cycle [a,b,c,a] has a 148.286055% weight, which is much better, which leads me to believe that either my algorithm is wrong or I have an error somewhere. 但是,正如我们所看到的,周期[a,b,c,a]权重为148.286055%,这要好得多,这使我相信算法错误或在某处出错。

Any advice is much appreciated!! 任何建议深表感谢!

I think that the problem is not the implementation but the algorithm. 我认为问题不是实现,而是算法。 Indeed take the following exemple with four vertices a, b, c and d, and the following edges: 确实采用以下具有四个顶点a,b,c和d以及以下边的示例:

w(a,b)=10/3 W(A,B)= 10/3

w(b,c)=10 瓦特(B,C)= 10

w(c,d)=5 瓦特(C,d)= 5

w(d,a)=10/3 瓦特(d,A)= 10/3

w(d,b)=5 瓦特(d,B)= 5

Then, your algorithm will return directed cycle (b,c,d,b) whereas the optimal solution is (a,b,c,d,a). 然后,您的算法将返回有向循环(b,c,d,b),而最佳解决方案是(a,b,c,d,a)。

Moreover, you should also know that your problem is probably NP-complete, since the Longest Path problem is NP-complete (even if the Shortest Path problem is polynomially solvable), so there is only a few hopes that there is a so simple algorithm for your problem. 此外,您还应该知道问题可能是NP完全的,因为最长路径问题是NP完全的(即使Shortest Path problem可以在多项式上解决),所以只有少数希望有一个如此简单的算法为您的问题。

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

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