Python 使用BFS的蛇梯

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,

给定一个蛇梯板,我们必须找到最后一个顶点到第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, 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))