最小骑士从一个方格移动到另一个方格

时间:2013-10-21 01:43:33

标签: math min shortest-path

是否有一个数学公式可用于计算无限2D网格中两点之间的最小骑士移动次数?我可以使用广度优先搜索来解决它,但是我们可以使用一个封闭形式的表达式吗?

谢谢!

1 个答案:

答案 0 :(得分:3)

我不认为有一个公式可以为所有点对产生最小的干扰。

但是对于某些特殊点而言。 设A,B为2D网格上的点,A = (0,0)B = (x,y)以及dist(x,y)最小骑士移动次数。

首先,距离是对称的:

dist(x,y) = dist(-x,y) = dist(x,-y) = dist(-x,-y) = dist(y,x)

  1. 案例:2x=y - > dist(x,2x) = x
  2. 案例:x = 0
    • 子案例1:y = 4k(k是自然数)
      - > dist(x,y) = 2k
    • 子案例2:y = 4k+1y = 4k+3
      - > dist(x,y) = 2k + 3
    • 子案例3:y = 4k+2
      - > dist(x,y) = 2k + 2
  3. 案例:x = y
    • 子案例1:x = 3k(k是自然数)
      - > dist(x,y) = 2k
    • 子案例2:x = 3k+1
      - > dist(x,y) = 2k + 2
    • 子案例3:y = 3k+2
      - > dist(x,y) = 2k + 4
  4. 如果B(0 <= x <= y)在任何情况下都不适合,那么至少你知道 dist(x,y) <= dist(x-k,y-2k) + dist(k,2k) = dist(0,y-2k) + k

    dist(x,y) <= dist(x-z,y-z) + dist(z,z) = dist(0,y-z) + dist(z,z)

    修改 我已经考虑了一点。我认为以下算法计算最小移动量(Maple Code):

    dist := proc(x,y)
      global d;
      local temp;
    
      if x < 0 then x:= -x; fi;
      if y < 0 then y:= -y; fi;
      if x > y then temp := x; x:= y; y:= temp; fi;
    
      if y = 2*x then return x; fi;
      if x = y then 
        if x mod 3 = 0 then return 2*(x/3); fi;
        if x mod 3 = 1 then return 2+2*(x-1)/3 fi;
        if x mod 3 = 1 then return 4+2*(x-2)/3 fi;
      fi;
      if x = 0 then
        if y mod 4 = 0 then return y/2; fi;
        if y mod 4 = 1 or y mod 4 = 3 then return 3+(y - (y mod 4))/2; fi;
        if y mod 4 = 2 then return 2+(y-2)/2; fi;
      fi;
      if y > 2*x then
        return dist(0,y-2*x) + dist(x,2*x);        
      else
        return dist(2*x-y,2*x-y) + dist(y-x,2*(y-x));
      fi;
    end proc:
    

    注意:这仅适用于无限的2D网格。

    EDIT2:此(递归)算法在O(1)(时间和空间)中运行,因为它具有恒定数量的O(1)操作并且最多自调用一个时间。

    EDIT3:如果AB距离至少1行/列,我认为这对于有限的2D网格也是一个小问题来自至少一个边界。