我需要生成最短的路线。符合我要求的第一个解决方案是Dijkstra的算法,因此我实现了相同的(Java)。后来,我不得不修改实现以生成最短路径"转动次数最少"。经过一番头疼之后,我想出了一个解决方案,尽管在现有的Dijkstra算法实现中添加了很多条件。现在我的问题是,是否有更好的方法解决这个问题(比如,任何现有的算法已经做到了这一点)?我的解决方案包括在路线计算迭代中的每个节点中存储额外的转弯信息,并在回溯路线时使用相同的转弯信息。
答案 0 :(得分:2)
你不应该对Dijkstra进行任何回溯或实质性的调整。对于每个节点,只需跟踪(就像您一样)当前到该节点的最短路径上的最少圈数。无论何时放松边缘,如果生成的路径与当前最短路径相同,则选择转弯最少的路径。
编辑:正如评论中所指出的,这种方法忽略了所选路线的进入边缘的方向影响后续路径的转弯数的事实。这将通过在每个节点中存储最短距离+为每个入射边缘或为每个唯一入射角度存储来修复(无论如何测量)。或者,为了减少对Dijkstra的修改,您可以预先修改图形:将每个节点拆分为每个传入边缘的一个节点,以便每个节点只有一个传入边缘,但复制所有传出边缘,以便每个节点都具有所有原始传出边缘。原始图形中的最佳路径仍将存在于新图形中(并且不会引入更好的路径),并且每个节点中只有一个入射角度。
答案 1 :(得分:1)
最终,路径寻找算法旨在找到成本最低的路径。成本的定义取决于方案。在一种情况下,成本可能是距离,但在其他情况下,它可能包括地形,坡度,通行费等。在您的情况下,模拟“最短路线的最短路线”的最简单方法是从距离和转弯数量中获得成本。换句话说,包括转弯成本。
例如,如果您使用A*算法,则两个节点之间的成本计算可能包括距离成本以及此移动需要更改方向的额外成本。如果不同的路径不需要改变方向,那么它将是更低的成本,算法将选择该路径。
这里唯一棘手的事情是保持先前动作的上下文来检测转弯。在A *中,您通常会将引用保留回上一个节点,因此确定下一步是否需要转弯应该相当简单。
答案 2 :(得分:0)
我不知道,为什么没有人这么说,为什么会有一个可以接受的答案。
您要解决的问题(即生成转弯次数最少的最短路径)是受重量限制的最短路径问题的一个示例。 因此,它是NP完全的,无法有效解决。
您可以找到讨论解决此问题的论文,例如http://web.stanford.edu/~shushman/math15_report.pdf
答案 3 :(得分:0)
这是一个简单的启发式方法。就像其他人指出的那样,启发式是 AStar 中的游戏。
if (Cost > CanMaxMove) Heuristic += 1000;
// for cost per grid pt typically 10 to 30
// Cost = PtCost + CostSoFar
// higher is worse (more costly)
您只需像往常一样在 AStar 中找到最佳路径,但大幅折价会不合时宜。正如所指出的,这是一个非常困难的问题,但在以下条件下很容易解决:
<块引用>无论如何,每转一圈都会搜索到一条新路径:这很容易 可信,因为直到下一轮情况很容易改变。如果 不,这些并不是我们所知道的真正的转弯。
如果这种情况对您没问题,请执行上面的代码段。对于所有“本回合外”移动且不平滑(例如Heuristic += (Cost - CanMove) * 100
),启发式必须以相同的值打折扣,即“本回合”和“非本回合”之间必须存在很大差异。