在网格中生成具有特定数量的单元格的路径的算法

时间:2017-09-28 18:02:21

标签: algorithm

我有一个随机大小的网格(例如随机生成的5 x 5或8 x 8)以及随机生成的起点和终点。是否有可能通过特定数量的单元格来了解从起点到终点可以采用的所有可能路径,而不是检查所有可能的移动(这将提高算法的复杂性)?
所以例如,这个网格(S和E是起点和终点,是的,实际上并不需要从一个点开始而不是另一个点,因此目标点可能是正确的单词): 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 E 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 S 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 例如,我需要使用总共10个单元格。所以一个解决方案是: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 E 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 | - | 0 0 0 0 0 S 0 | 0 0 0 0 0 | 0 | 0 0 0 0 0 - - | 最后一点是它必须检测是否根本无法生成路径。例如,在此网格中,由于某些原因,如果要使用的所需单元格为10,则无法生成解决方案: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 E 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 S 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 谢谢!

1 个答案:

答案 0 :(得分:1)

你能在同一个牢房多次去吗?如果是这样,检测是否存在路径很容易:找到最短路径。如果它与您正在寻找的路径具有相同的奇偶校验,则存在解决方案,否则不存在(假设没有对角线移动)。

当某条路径存在时,为了找到所有路径,回溯是我能想到的最佳选择。与剩余的移动相比,当距离末端太远时(即距您最近的路径),您可以修剪分支。有了这个,您应该接近最佳解决方案,因为只有在我们仍然可以获得解决方案时才继续移动(除了回溯之前的最后一步)。

找到最短路径的长度是微不足道的:它只是abs(x-xe)+ abs(y-ye)(假设没有对角线再次移动)。

修改

这是python中的一个实现,假设:   - Position类(存储xy坐标并提供相等比较)   - distance(返回最短路径长度)   - is_valid函数(如果某个点不在地图中,则返回false,也可能允许障碍物)   - 方法rightleftupdown(相应地返回修改后的Position对象)

def find_path_rec(pos, target, remaining, path):
  if not is_valid(pos) or pos in path or distance(pos, target) > remaining:
    return []
  if pos == target:
    if remaining == 0:
      return [path + [pos]]
    else:
      return []
  path.append(pos)
  result = []
  for new_pos in [right(pos), left(pos), up(pos), down(pos)]:
    result.extend(find_path_rec(new_pos, target, remaining-1, path))
  path.remove(pos)
  return result

它适用于您的示例,第一个案例返回1016个路径,第二个案例返回0。除了距离被认为是11而不是10,因为它计算移动的数量,包括离开E并到达S.你可以很容易地将它封装在另一个函数中以便更方便地使用:

def find_path(pos, target, length):
  find_path_rec(pos, target, length+1, [])