Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
理解最大流问题的python代码_Python_Algorithm_Graph Theory - Fatal编程技术网

理解最大流问题的python代码

理解最大流问题的python代码,python,algorithm,graph-theory,Python,Algorithm,Graph Theory,我试图在博客文章中研究google foobar的一个问题。(问题如下所述。) 作者在博客上发布了自己的代码,并声称该代码已被解决 我在相关的维基百科页面上阅读了Dinic的算法,并观看了YouTube。我发现代码(附在下面)的文档记录得很糟糕,我找不到算法在代码中是如何实现的线索。特别是,我看不到“水平图”和“阻塞流”是在哪里构建的 有人能看到大while循环在函数bfs()中做了什么吗 根据各组兔子的起始房间号、逃生舱的房间号,以及在两条走廊之间的每个方向上一次可以容纳多少只兔子,计算出在

我试图在博客文章中研究google foobar的一个问题。(问题如下所述。)

作者在博客上发布了自己的代码,并声称该代码已被解决

我在相关的维基百科页面上阅读了Dinic的算法,并观看了YouTube。我发现代码(附在下面)的文档记录得很糟糕,我找不到算法在代码中是如何实现的线索。特别是,我看不到“水平图”和“阻塞流”是在哪里构建的

有人能看到大while循环在函数
bfs()
中做了什么吗


根据各组兔子的起始房间号、逃生舱的房间号,以及在两条走廊之间的每个方向上一次可以容纳多少只兔子,计算出在高峰期一次有多少只兔子可以安全到达逃生舱

编写一个函数答案(入口、出口、路径),其中包含一个整数数组,表示聚集的兔子群在哪里,一个整数数组表示逃生舱在哪里,以及一个走廊整数数组,以整数形式返回每个时间步可以通过的兔子总数。入口和出口是不相交的,因此永远不会重叠。路径元素path[A][B]=C描述了从A到B的走廊在每个时间步都可以容纳C个兔子。走廊连接的房间最多有50间,一次最多可容纳200万只兔子

例如,如果您有:

entrances = [0, 1] 
exits = [4, 5] 
path = [   [0, 0, 4, 6, 0, 0],  # Room 0: Bunnies   
           [0, 0, 5, 2, 0, 0],  # Room 1: Bunnies   
           [0, 0, 0, 0, 4, 4],  # Room 2: Intermediate room   
           [0, 0, 0, 0, 6, 6],  # Room 3: Intermediate room   
           [0, 0, 0, 0, 0, 0],  # Room 4: Escape pods   
           [0, 0, 0, 0, 0, 0],  # Room 5: Escape pods ]
然后,在每个时间步骤中,可能会发生以下情况:

0 sends 4/4 bunnies to 2 and 6/6 bunnies to 3 
1 sends 4/5 bunnies to 2 and 2/2 bunnies to 3 
2 sends 4/4 bunnies to 4 and 4/4 bunnies to 5 
3 sends 4/6 bunnies to 4 and 4/6 bunnies to 5
因此,总共有16只兔子可以在每一个时间步的4和5点到达逃生舱。(请注意,在本例中,房间3可以将8只兔子的任何变化发送到4和5,例如2/6和6/6,但最终答案保持不变。)

def bfs(矩阵、源、目标): 已访问=[-1表示范围内的i(len(矩阵))] 已访问[源]=源 队列=[源] 当len(队列)>0时: top=queue.pop(0) 对于范围内的i(len(矩阵)): if(矩阵[top][i][1]-矩阵[top][i][0])!=0并访问了[i]==-1: 如果i==目的地: #获得路线 到访[目的地]=顶部 路径=[目的地] 温度=目的地 当临时工!=资料来源: temp=访问过的[temp] 路径追加(临时) path.reverse() #获取流值并更新扩充图 温度=1 总计=浮动(“inf”) cur=源 当临时工!=len(路径): 条目=矩阵[cur][path[temp]] 差异=abs(条目[1])-条目[0] 总计=最小值(总计,差异) cur=路径[temp] 温度+=1 温度=1 cur=源 当临时工!=len(路径): 条目=矩阵[cur][path[temp]] 如果条目[1]<0:#已扩充需要翻转 分录[1]+=总计 其他: 条目[0]+=总计 条目=矩阵[path[temp]][cur]
如果条目[1]作者错了。这段代码实现了(专门针对Ford–Fulkerson,因此turtle的评论是正确的),它反复增加剩余网络中的最短路径。

代码中实现的算法看起来更像Ford Fulkerson非常感谢,David!难怪它一点也不喜欢Dinic的算法。我不认识爱德蒙·卡普。
def bfs(matrix, source, destination):
    visited = [-1 for i in range(len(matrix))]
    visited[source] = source
    queue = [source]
    while len(queue) > 0:
        top = queue.pop(0)
        for i in range(len(matrix)):
            if (matrix[top][i][1] - matrix[top][i][0]) != 0 and visited[i] == -1:
                if i == destination:
                    # Get route
                    visited[destination] = top
                    path = [destination]
                    temp = destination
                    while temp != source:
                        temp = visited[temp]
                        path.append(temp)
                    path.reverse()
                    # Get flow value and update augmented graph
                    temp = 1
                    total = float("inf")
                    cur = source
                    while temp != len(path):
                        entry = matrix[cur][path[temp]]
                        diff = abs(entry[1]) - entry[0]
                        total = min(total, diff)
                        cur = path[temp]
                        temp += 1
                    temp = 1
                    cur = source
                    while temp != len(path):
                        entry = matrix[cur][path[temp]]
                        if entry[1] < 0: # Already augmented need to flip
                            entry[1] += total
                        else:
                            entry[0] += total
                        entry = matrix[path[temp]][cur]
                        if entry[1] <= 0: # Already augmented need to flip
                            entry[1] -= total
                        else:
                            entry[0] += total
                        cur = path[temp]
                        temp += 1
                    return True
                else:
                    visited[i] = top
                    queue.append(i)
    return False

def answer(entrances, exits, path):
    max_val = sum(list(map(sum, path)))
    aug = []
    for i in range(len(path)):
        aug.append([])
        for j in range(len(path[i])):
            aug[i].append([0, path[i][j]])
        aug[i].append([0, 0])
        if i in exits:
            aug[i].append([0, max_val])
        else:
            aug[i].append([0, 0])
    aug.append([])
    aug.append([])
    for i in range(len(path[0]) + 2):
        if i in entrances:
            aug[-2].append([0, max_val])
        else:
            aug[-2].append([0, 0])
        aug[-1].append([0, 0])
    while bfs(aug, len(aug)-2, len(aug)-1):
        pass
    total = 0
    for i in range(len(aug)):
        total += aug[-2][i][0]
    return total