【问题标题】:Knight walk backtracking solution issueKnight walk回溯解决问题
【发布时间】:2021-09-07 08:53:09
【问题描述】:

我对我为以下问题编写的回溯解决方案有疑问:

Given a square chessboard of N x N size, the position of Knight and the position of a target are given. We need to find out the minimum steps a Knight will take to reach the target position

我的回溯解决方案是:

    #knight walk problem
 #knight walk problem
#cx---crnt x value
#cy---crnt y value
#Dx---destintion X value
#Dy----destintion Y value
#count---count of steps


def kingnight(Cx,Cy,Dx,Dy,outboard,steps):
  if Cx==Dx and Cy==Dy:
    outboard[Cx][Cy]=1
    return steps
  if Cx<0 or Cy<0 or Cx>=len(outboard) or Cy>=len(outboard) or outboard[Cx][Cy]==1:
    return float('inf')
  outboard[Cx][Cy]=1
  min1=kingnight(Cx+2,Cy-1,Dx,Dy,outboard,steps+1)
  min2=kingnight(Cx+2,Cy+1,Dx,Dy,outboard,steps+1)
  min3=kingnight(Cx-2,Cy+1,Dx,Dy,outboard,steps+1)
  min4=kingnight(Cx-2,Cy-1,Dx,Dy,outboard,steps+1)
  min5=kingnight(Cx+1,Cy+2,Dx,Dy,outboard,steps+1)
  min6=kingnight(Cx+1,Cy-2,Dx,Dy,outboard,steps+1)
  min7=kingnight(Cx-1,Cy+2,Dx,Dy,outboard,steps+1)
  min8=kingnight(Cx-1,Cy-2,Dx,Dy,outboard,steps+1)
  crntmin=min(min1,min2,min3,min4,min5,min6,min7,min8)
  outboard[Cx][Cy]=0 #backtracking
  return crntmin

当我调用函数时:

n=4
board=[[0 for _ in range(n)] for i in range(n)]
kingnight(1,1,0,0,board,0)

它显示了预期的输出。但是当我用以下方式打电话时:

n=6
board=[[0 for _ in range(n)] for i in range(n)]
kingnight(2,3,5,5,board,0)

它应该返回 3,但它是一个无限循环。

我哪里错了?

【问题讨论】:

    标签: python algorithm recursion backtracking recursive-backtracking


    【解决方案1】:

    问题在于您的算法正在寻找骑士从起始位置可以采取的每一个可能的路径。在更大的电路板上,路径的数量呈指数增长。您的循环不是无限的;它只需要检查太多路径。

    如果我们稍微简化一下,假设 6x6 棋盘上的马平均可以走 4 步,并且路径平均有 20 步长,那么我们有 420 路径,即 1e +12 条路径。这是低估了。

    如何解决

    这种蛮力算法不够好。

    使用广度优先搜索而不是深度优先搜索,并在每个已访问的棋盘格上记录距源(也可用作已访问标记)的(最短)距离。未访问的字段应初始化为 -1。源将得到 0, ...等等。

    这将是您需要的主要改进。您还可以应用一些启发式方法,并将其转换为 A* 算法,其中估计到目标的步数应该被低估,例如出租车距离除以 3。

    实施

    我选择了一个实现,你不将板传递给函数,而只是 n,函数返回坐标路径。

    然后该函数将在本地创建它的棋盘,并在广度优先期间用代表马在其最佳路径(到那个方格)上的位置的值填充它。

    代码如下:

    def kingnight(cx,cy,dx,dy,n):
        board=[[0 for _ in range(n)] for i in range(n)]
        q = [(cx, cy)]
        board[cx][cy] = (-1, -1)
        while q:
            frontier = []
            for cx, cy in q:
                for mx, my in ((-2,-1),(-1,-2),(1,-2),(2,-1),(1,2),(2,1),(-2,1),(-1,2)):
                    tx = cx + mx
                    ty = cy + my
                    if 0 <= tx < n and 0 <= ty < n and not board[tx][ty]:
                        board[tx][ty] = (cx, cy)
                        if tx == dx and ty == dy:
                            # build path
                            path = []
                            while tx >= 0:
                                path.append((tx, ty))
                                tx, ty = board[tx][ty]
                            return path[::-1]
                        frontier.append((tx, ty))
            q = frontier
        return  # Not possible
    
    # Demo
    n=6
    print(kingnight(2,3,5,5,n))
    

    【讨论】:

      猜你喜欢
      • 2021-07-16
      • 1970-01-01
      • 2020-06-30
      • 1970-01-01
      • 2020-07-04
      • 1970-01-01
      • 2021-05-29
      • 2021-03-15
      • 2017-02-24
      相关资源
      最近更新 更多