找到两点之间的最小步数?

时间:2015-01-23 09:02:56

标签: java vb.net algorithm graph-algorithm

我有一个网格,网格有两个"材料" -

  • 地板

例如:

This is An Example Of a Grid 在这个网格中,我们有具有大小和位置的对象(对象的位置是左上角)。

在每个对象上,我们可以执行一些操作,例如 -

  • 上移
  • 下移
  • 向左移动
  • 向右移动
  • 转动对象(相对于左上角)

我需要创建一个函数来返回我需要对对象执行的最小操作量,以便将其从一个点移动到另一个点(我只需要操作量)。

我使用dijkstra's algorithm但没有转弯操作解决了这个问题。

所以任何人都可以帮我构建这个功能。

问题示例 -

  • 起点 - enter image description here

  • 结束点

enter image description here

我需要返回我需要对对象执行的最少量操作。

4 个答案:

答案 0 :(得分:5)

将问题视为在3D网格中找到最短路径,深度为2(每种可能的状态:水平和垂直)。你必须编码禁止一个人从一个深度移动到另一个深度的约束,例如,如果它不适合那样,就不能垂直。

现在你可以使用常规BFS来找到网格中的最短路径(即未加权的图形)。

答案 1 :(得分:2)

对于你的问题,我认为BFS仍然有效。

使用BFS解决传统的迷宫问题,从头开始,你必须:

1. Enqueue every point that is accessible (not a piece of wall, and not visited) and connected to the current point.
2. Dequeue current point and mark it as VISITED.

从上面,您可以看到BFS不会让任何点被访问两次,因此避免了循环。

您的问题

至于你的问题,BFS仍然有效,但我们会略微改变“可访问”的定义:

首先,我将介绍“迷宫”矩阵的样子。 以下是数字在以下图像中的含义。

(假设对象的大小是1 * 2,移动时,对象的左上角会停留在每个点上。)

00: The point can't be accessed, neither the object is horizontal nor vertical. 
10: The point can be accessed if the object is horizontal
01: The point can be accessed if the object is vertical
11: The point can be accessed if the object is either horizontal or vertical

您的图表可以转换为如下矩阵:

img1

用00填写那些无法访问的点,你就会得到

enter image description here

这更像是一个迷宫问题,但有点不同。

最后,让我们看看如何“访问”这些点:

connected的定义类似于传统的迷宫问题。以下是一些例子:

---------
| 01| 10|
|---|---|
| 10|   |
---------    (Not Connected from top-left to either top-right or bottom-left)


---------
| 11| 10|
|---|---|
| 01|   |
---------    (Connected from top-left to both top-right and bottom-left)


---------
| 10| 10|
|---|---|
| 01|   |
---------    (Connected from top-left to top-right, but not connected to bottom-left)

所以其余的可能很简单。遵循传统的BFS方法,并创建一个二维数组来存储每个点的最短路径的长度。出列以获取当前点,将当前点的connected个邻居添加到队列,并将此点标记为VISITED,然后一切都将与BFS相同。

在获得最短路径后,重新运行程序,在当前点保持对象是垂直还是水平的状态,并模拟您在图像上的移动。仅在必要时添加转弯,您将在添加转弯时获得结果。

enter image description here

答案 2 :(得分:0)

如果我理解你的要求,写出来会花费太长时间,但我能想到的最简单的方法就是首先找到路径,检查路径上的碰撞,旋转,然后添加动作相应

  • 使用基本路径算法查找到目的地的路径。
  • 将路径节点存储在某种可遍历的数组中(如果路径算法很好/简单,则应该总共4个)。
  • 尝试按照路径注释(i到数组计数)
  • 检查每次移动是否发生碰撞。
  • (do while)如果可移动物体与墙壁相交,请旋转90度再试一次。
  • (下一步)如果成功,保存到移动动作列表(移动x / y,旋转z)
  • 返回行动计数

使用更复杂的网格,这显然会变得更复杂,但您只需要进行90度转弯。它应该可以在~9个动作中使用。

答案 3 :(得分:-2)

使用Breadth-first search策略,根据是否必须转动对象为边缘指定权重。