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