加权二维阵列中围绕目标的最短路径

问题描述

我很难找到正确的编码方法

一个随机生成的2d数组,大约50x50,每个像元的值为1〜99。 从一个随机位置“绿色”开始,目标是以最少的操作量包围目标“红色”。
移至相邻的单元格需要1〜99个动作,具体取决于其值。
低值的小数组示例:

[

目前我最好的主意是,根据目标的对角线生成4组检查点,然后使用大量的Dijkstra查找通过所有检查点的路径以及起点。

我遇到的一个问题是,这很快就会变成大量的路径。
从“ northWest-1到NW-20”的任何起点到“ NE-1到NE-20”的任何终点,都有400种可能性。将第三个对角线和第四个对角线相加会变成400 * 20 * 20。

使用对角线检查点的另一个问题不是[绿色到对角线的最短路径(橙色路径)]

[

而是从“绿色到红色周围路径上的任何点”。

当前伪代码

take 2 sets of diagonals nearest to Green/start
find the shortest path that connects those diagonals while going through Green
(backtracking through the path is free)

draw a line starting from the target point,in-between the 2 connected diagonals,set those cells to value infinite to force going around them (and thus around the target)

find the shortest path connecting the Now-seperated diagonals

不幸的是,该伪代码已经包含了一些边缘情况,其中“墙”阻止了最有效的路径。

如果相关,将使用javascript编写。

编辑,作为一种极端情况,它可以在包围之前使目标旋转,尽管极为罕见

https://wiki.termux.com/wiki/Differences_from_Linux

Edit2; “环绕”是指将目标与视野的其余部分断开连接,而不管包围区域有多大,或者即使它包括起点(例如,所有边都为0)

这是另一个具有(可能)最佳路径的较大字段,并且以文本形式包含2个字段:

enter image description here


https://i.imgur.com/yMA14sS.png

解决方法

简而言之,让我们称呼围绕目标栅栏的路径。有效围栏是一组(连接的)节点,这些节点使目标与起点断开连接,但不包括目标。最小的栅栏是这样做的,同时成本最小。 可以是一个围栏,其中包括到起始节点的路径。目标是构建最低成本的套索。

一种简单的算法是使用目标的直接邻域作为围墙,并对所有围墙节点运行Dijkstra,以构建(可能是非最佳)套索。请注意,如果需要最佳答案,栅栏的选择实际上会影响从起点到栅栏的路径选择-反之亦然,从起点到栅栏的路径选择会影响栅栏本身的选择方式。问题不能被整齐地分为两部分。

我相信以下算法将产生最佳的围栏

  1. 使用Dijkstra从起点到目标(不包括终点)构建路径。让我们将其称为 yellow 路径。
  2. 构建2组节点,在此 yellow 路径的每一侧各设一个节点,并将其相邻。将这些集合称为 red blue 。请注意,对于与路径相邻的任何给定节点,它可以是路径的一部分,蓝色集合,红色集合或实际上是端点。
  3. 对于 red 集中的每个节点,运行Dijkstra在 blue 集中找到 not 不交叉的节点的最短路径黄色路径。
  4. 对于每个先前的路径,请查看添加(缺失的)黄色路径位以将蓝色和红色端连接在一起之后最短的路径。

费用为length(yellowPath) * cost_of_Dijkstra(redStart,anyBlue)

要制作一个好的套索,只要从头到任何栅栏节点运行Dijkstra就足够了。 但是,我不确定最终的套索是否最佳

,

您可能想考虑使用A *搜索算法,可以调整算法以一次搜索所有4个点。

https://en.wikipedia.org/wiki/A*_search_algorithm

基本上,A *通过将Dijkstra的搜索集中在距目的地“更近”的点进行搜索。

“另请参阅”部分还提供了许多其他搜索算法变体,它们可能对您的情况也更有用,尽管其中有些更适合视频游戏路径规划而非2D网格路径。 / p>

再次查看问题后进行编辑:

似乎每个位置都有重量。这使得距离计算不太直接。在这种情况下,我会将其视为优化。对于启发式成本函数,最好只使用目标的最直接路径(对角线)作为启发式成本,然后仅使用A *搜索来尝试找到更好的路径。


至于环绕声逻辑。我将其视为自己的逻辑和一个单独的步骤(可能是第二步)。首先找到到达目标的最少成本路径。然后找到环绕路径的最便宜的方法。老实说,最简单的包围点的方法可能值得自己问。

一旦您拥有了这两个部分,那么将两者合并起来应该很容易。在某些情况下,两个第一个重叠并且将它们合并在一起。