我不确定该怎么称呼此问题,但我确定它有一个名字。否则找到答案会更简单。
给出"地图"细胞如:
O - - -
- X - -
- X X -
- - - -
其中O =起始位置,X =障碍物, - =未访问。我想遍历这张地图(我已经存储为2D数组)并访问尽可能多的单元格,而不会触及访问过的单元格。
我的算法如下:
所以有两个问题:
所以我的问题是:有没有更好的方法来实现这个,或者我如何调整我当前的算法来解决这个问题?
答案 0 :(得分:1)
有一个名称:最长路径问题:https://en.wikipedia.org/wiki/Longest_path_problem
以图表的形式,使从自由单元格到被阻挡单元格的边缘具有无限权重,并且所有其他边缘的权重均为1(或其他常数)。没有“有效”(在算法复杂性方面)解决这个问题(如果你找到一个你会出名!)
解决您的两个问题:
你是对的,根据障碍,你将无法访问某些方格,但它也取决于起点。很可能很多广场都无法到达;例如,完全围绕起点可能存在障碍物,然后所有障碍物都无法到达。
对于您当前的算法,您可以在回溯到起始方块后停止,然后再移动。否则您的算法看起来正确。步骤1-4的顺序最终不会有任何区别。为了知道哪条路径最长,你仍然需要全部尝试(使用这种方法)。
编辑:当我早些读到它时,我不确定我是否理解第5步;即使你被卡住了(如果你在那个广场然后你去过它),当前的广场也不应该被标记为无法到达,但周围的广场是(除了你来自的广场)。只要您不将当前方块标记为不可访问,回溯算法应该正确找到最长路径。
答案 1 :(得分:1)
由于以下情况,您的算法不起作用:
O - - -
X - - X
因为你的算法将首先完全正确
O 1 2 3
X - - X
并标记最后一个单元格在回溯时被阻止,因此它永远不会找到最佳
O 1 4 5
X 2 3 X
你可以通过将其视为一个图形问题并简单地应用任何最长路径算法(通常是NP-hard)来以通用方式解决这个问题但我不确定你是否熟悉这种方法
可能更简单的方法是:
一个例子可能有帮助。让我们再次考虑相同的例子。我使用C表示当前位置,使用#表示访问单元格。我们会跟踪移动的堆栈以及回溯的最后一步。
C - - - Stack: []
X - - X Backtracked move: -
向右走
# C - - Stack: [R]
X - - X Backtracked move: -
向右走
# # C - Stack: [R, R]
X - - X Backtracked move: -
向右走
# # # C Stack: [R, R, R]
X - - X Backtracked move: -
尝试向右,向下,向左和向上,注意你被卡住并回溯,即向右反转(左)
# # C - Stack: [R, R]
X - - X Backtracked move: R
最后一次回撤是正确的,所以现在尝试下一步,即下台
# # # - Stack: [R, R, D]
X - C X Backtracked move: -
尝试向右,尝试向下,向左走
# # # - Stack: [R, R, D, L]
X C # X Backtracked move: -
再次陷入困境,所以回溯
# # # - Stack: [R, R, D]
X - C X Backtracked move: L
最后一次退回的动作仍然存在,所以现在尝试下一步,即试试。请注意,我们陷入困境并进一步回溯。
快速转发到第一个有趣的下一步:
# C - - Stack: [R]
X - - X Backtracked move: R
最后一个是正确的,所以继续下去。
# # - - Stack: [R, D]
X C - X Backtracked move: -
你现在可能已经明白了,所以我只是一直快进:
# # # C Stack: [R, D, R, U, R]
X # # X Backtracked move: -
一路回溯:
C - - - Stack: []
X - - X Backtracked move: R
最后一步是正确的,所以请尝试向下,向左和向上。你已经完成了。
在此过程中,您将跟踪您所见过的最长路径,这就是您的答案。