Python 使用BFS的蛇梯
给定一个蛇梯板,我们必须找到最后一个顶点到第0个顶点的最小距离。(在第0个顶点,我们掷骰子并向前移动) 在此处阅读有关问题的信息-> 我的代码:Python 使用BFS的蛇梯,python,python-3.x,algorithm,data-structures,graph,Python,Python 3.x,Algorithm,Data Structures,Graph,给定一个蛇梯板,我们必须找到最后一个顶点到第0个顶点的最小距离。(在第0个顶点,我们掷骰子并向前移动) 在此处阅读有关问题的信息-> 我的代码: from collections import defaultdict global INT_MAX INT_MAX = 3 ** 38 class Graph: def __init__(self): self.vertList = defaultdict(list) def addEdge(self, u,
from collections import defaultdict
global INT_MAX
INT_MAX = 3 ** 38
class Graph:
def __init__(self):
self.vertList = defaultdict(list)
def addEdge(self, u, v):
self.vertList[u].append(v)
def distanceBFS(self, src, target):
queue = []
queue.append(src)
distanceDict = {}
for v in self.vertList:
distanceDict[v] = INT_MAX
distanceDict[src] = 0
visited = set()
while (len(queue) > 0):
curr = queue.pop(0)
visited.add(curr)
for vertex in self.vertList[curr]:
if vertex not in visited:
queue.append(vertex)
distanceDict[vertex] = distanceDict[curr] + 1
print(distanceDict[target])
def solveSnakesLadder(self):
snakeLadderDict = {2: 13, 5: 2, 9: 18, 18: 11, 17: -13, 20: -14, 24: -8, 25: 10, 32: -2, 34: -22}
# we have 36 boxes --> i
# we can throw a dice at each of these 36 boxes and it can be from 1 to 6
# j is new position on the board after throwing a dice
for i in range(0, 37):
for dice in range(1, 7):
j = i + dice
if j in snakeLadderDict:
j += snakeLadderDict[j]
if j <= 36:
self.addEdge(i, j)
self.distanceBFS(0, 36)
g = Graph()
g.solveSnakesLadder()
10
4
正确输出:
from collections import defaultdict
global INT_MAX
INT_MAX = 3 ** 38
class Graph:
def __init__(self):
self.vertList = defaultdict(list)
def addEdge(self, u, v):
self.vertList[u].append(v)
def distanceBFS(self, src, target):
queue = []
queue.append(src)
distanceDict = {}
for v in self.vertList:
distanceDict[v] = INT_MAX
distanceDict[src] = 0
visited = set()
while (len(queue) > 0):
curr = queue.pop(0)
visited.add(curr)
for vertex in self.vertList[curr]:
if vertex not in visited:
queue.append(vertex)
distanceDict[vertex] = distanceDict[curr] + 1
print(distanceDict[target])
def solveSnakesLadder(self):
snakeLadderDict = {2: 13, 5: 2, 9: 18, 18: 11, 17: -13, 20: -14, 24: -8, 25: 10, 32: -2, 34: -22}
# we have 36 boxes --> i
# we can throw a dice at each of these 36 boxes and it can be from 1 to 6
# j is new position on the board after throwing a dice
for i in range(0, 37):
for dice in range(1, 7):
j = i + dice
if j in snakeLadderDict:
j += snakeLadderDict[j]
if j <= 36:
self.addEdge(i, j)
self.distanceBFS(0, 36)
g = Graph()
g.solveSnakesLadder()
10
4
我做错了什么?这和逻辑有关吗?在添加到队列中之前,我还可以检查distanceDict中的值,但是访问集也会做同样的事情 基本上,问题在于以下代码块:
queue.append(src)
distanceDict[src] = 0
visited = set()
while (len(queue) > 0):
curr = queue.pop(0)
visited.add(curr)
for vertex in self.vertList[curr]:
if vertex not in visited:
queue.append(vertex)
distanceDict[vertex] = distanceDict[curr] + 1
我将尝试用以下基本图表来解释这一点:
假设,您需要在下图中找到从顶点1
到顶点3
的最短路径。使用上述实现,您将有以下迭代:
1
添加到队列Q
并将其距离设置为0
while
循环中从Q
弹出1
,并将其标记为已访问Q
Q
中有顶点2
和3
,distance
字典将为distance[1]=0,distance[2]=1,distance[3]=1
这就是问题的开始,因为我们还没有将顶点2
和3
添加到访问的数组中,如果我们从其他邻居再次访问这些顶点,我们将在下一次迭代中再次开始更新这些顶点的距离
再次回到我们的算法,现在我们再次转到while
循环的开始,并从中选择pop
顶点2
,并将其标记为已访问
当我们下一步通过其未访问的邻居时,我们将再次访问我们已经访问过的3
,并将使用不正确的值更新distance
字典
访问顶点2
及其相邻对象后,不同对象的状态如下:
我们在队列中有顶点3
,距离字典将为distance[1]=0,distance[2]=1,distance[3]=2
<代码>距离[3]
被错误地更新,正如我们从迭代中看到的那样
然而,修复是非常直接的,在这里,我们需要在访问顶点之后将其标记为已访问,这样我们就不会通过其他邻居将其再次放入队列中
到目前为止,您已经猜到BFS函数的正确实现应该如下所示:
from collections import defaultdict
global INT_MAX
INT_MAX = 3 ** 38
class Graph:
def __init__(self):
self.vertList = defaultdict(list)
def addEdge(self, u, v):
self.vertList[u].append(v)
def distanceBFS(self, src, target):
queue = []
queue.append(src)
distanceDict = {}
for v in self.vertList:
distanceDict[v] = INT_MAX
distanceDict[src] = 0
visited = set()
visited.add(src)
while (len(queue) > 0):
curr = queue.pop(0)
for vertex in self.vertList[curr]:
if vertex not in visited:
queue.append(vertex)
visited.add(vertex)
distanceDict[vertex] = distanceDict[curr] + 1
print(distanceDict[target])
def solveSnakesLadder(self):
snakeLadderDict = {2: 13, 5: 2, 9: 18, 18: 11, 17: -13, 20: -14, 24: -8, 25: 10, 32: -2, 34: -22}
# we have 36 boxes --> i
# we can throw a dice at each of these 36 boxes and it can be from 1 to 6
# j is new position on the board after throwing a dice
for i in range(0, 37):
for dice in range(1, 7):
j = i + dice
if j in snakeLadderDict:
j += snakeLadderDict[j]
if j <= 36:
self.addEdge(i, j)
self.distanceBFS(0, 36)
g = Graph()
g.solveSnakesLadder()
从集合导入defaultdict
全局整数最大值
INT_MAX=3**38
类图:
定义初始化(自):
self.vertList=defaultdict(列表)
def附加值(自身、u、v):
self.vertList[u].append(v)
def距离BFS(自身、src、目标):
队列=[]
queue.append(src)
distanceDict={}
对于self.vertList中的v:
距离dict[v]=整数最大值
distanceDict[src]=0
访问=设置()
已访问。添加(src)
而(len(queue)>0):
curr=queue.pop(0)
对于self.vertList[curr]中的顶点:
如果未访问顶点:
queue.append(顶点)
已访问。添加(顶点)
distanceDict[顶点]=distanceDict[当前]+1
打印(距离记录[目标])
def solveSnakesLadder(自):
snakeLadderDict={2:13,5:2,9:18,18:11,17:-13,20:-14,24:-8,25:10,32:-2,34:-22}
#我们有36个盒子-->i
#我们可以在这36个盒子中的每个盒子上掷一个骰子,骰子的大小可以是1到6
#j是掷骰子后在棋盘上的新位置
对于范围(0,37)内的i:
对于范围(1,7)内的骰子:
j=i+骰子
如果蛇形图中的j:
j+=蛇形加法器[j]
如果j基本上,问题在于以下代码块:
queue.append(src)
distanceDict[src] = 0
visited = set()
while (len(queue) > 0):
curr = queue.pop(0)
visited.add(curr)
for vertex in self.vertList[curr]:
if vertex not in visited:
queue.append(vertex)
distanceDict[vertex] = distanceDict[curr] + 1
我将尝试用以下基本图表来解释这一点:
假设,您需要在下图中找到从顶点1
到顶点3
的最短路径。使用上述实现,您将有以下迭代:
将顶点1
添加到队列Q
并将其距离设置为0
接下来,在while
循环中从Q
弹出1
,并将其标记为已访问
接下来,访问它的所有邻居并将它们添加到队列Q
因此,此时,不同对象的状态如下所示:
我们在队列Q
中有顶点2
和3
,distance
字典将为distance[1]=0,distance[2]=1,distance[3]=1
这就是问题的开始,因为我们还没有将顶点2
和3
添加到访问的数组中,如果我们从其他邻居再次访问这些顶点,我们将在下一次迭代中再次开始更新这些顶点的距离
再次回到我们的算法,现在我们再次转到while
循环的开始,并从中选择pop
顶点2
,并将其标记为已访问
当我们下一步通过其未访问的邻居时,我们将再次访问我们已经访问过的3
,并将使用不正确的值更新distance
字典
访问顶点2
及其相邻对象后,不同对象的状态如下:
我们在队列中有顶点3
,距离字典将为distance[1]=0,distance[2]=1,distance[3]=2
<代码>距离[3]
被错误地更新,正如我们从迭代中看到的那样
金融机构
print(self.distanceBFS(0, 36))