我需要一个算法,它会给我一个从起始节点到结束节点的路径,但路径必须有一个确切数量的节点,否则路径查找应该失败。
要展开,我有一个瓷砖网格。移动只能是紧邻的上,下,左或右平铺(意思是没有对角线移动)。瓦片在路径中可以使用和不可以使用的规则有很多,但大多数情况下可以归结为简单的布尔来判断瓦片是否可以使用(这可以在开始算法之前计算出来)但是,给我带来麻烦的是,我有一条路径必须具有的距离,这意味着,从一个瓷砖到相邻瓷砖的每一次移动都是一个距离,整个路径应该有一个指定的距离,不多也不少。此外,一旦瓷砖被踩到(但算法开始时所有瓷砖都可用),它不能再次踩到,有点像玩老蛇游戏你我要注意不要自己吃。
我看过Dijkstra / A *并且我用google搜索算法进行寻路,但据我所知,所有这些算法都集中在最短的路径上,这对我没什么好处。我不关心它是哪条路径,只要它遵循上述规则。
我是否遗漏了某些内容,是否存在此类和算法,或者是否有一种简单的方法可以修改Dijkstra / A *来提供此结果? 由于我不是母语为英语的人,我可能使用了错误的术语,所以我欢迎这类算法的关键字建议。
这里有一个例子,当我说它必须是精确的距离并且不能使用相同的瓷砖两次时我的意思。
假设距离必须为7.现在让我们用O标记可以在路径中使用的图块,不能使用的图块和X,S的起点和E的目标。
X X X X X X X X O O E S O O X O O O O O O
如果没有距离限制,可以向左走,问题就解决了。 如果有距离限制,但没有“不能踩到相同的瓷砖”限制,可以下降一次,然后向左,然后向右,然后向左,然后向右,然后向左,然后向上并到达目标。 由于存在这两种限制,因此需要向右,向下,向左,向左,向上,向右然后才能到达目标。但是,如果情况是这样的话,就没有有效的路径。
X X X X X X X X O O E S O O X X O O O X O
如果它是相关的,我正在用C#开发这个棋盘游戏。
至于最大距离,这是距离的范围。 玩家将掷骰子并得到1-6号。如果玩家获得6,他会再次投掷骰子,如果他再次获得6,则一次又一次直到他没有得到6.距离是结果数加上玩家拾取的物品数量,理论上可以最多8,但通常是0-3,maaaybe 4。
另一方面,我刚接到新订单,游戏规则改为允许在相同的路径上两次踩到同一个位置,我相信这个过程很简单,但是我会留下这个问题就像我认为它有很好的答案,可以帮助那些情况下的人。
答案 0 :(得分:3)
正如Haile所指出的那样,由于它是NP完全的,所以这是一个启发式方法,以防你的问题足够小:
S
或E
的半岛(即仅由一个节点连接到其余部分的图形部分)并删除它们。P
到S
找到最短路径E
。如果n
小于len(P)
,则无法解决问题。S
到E
的深度优先搜索,使用以下启发式选择首先挖掘哪个节点。设A
为深度优先搜索中的当前切片。在欧几里德几何体中,将A
的位置投射到(SE)
行,并调用此点A'
。尽量保持比率len(current path) / n
接近len([SA']) / len([SE])
。或者更好,以某种方式“A
在路径P
上”A''
获取len(current path) / n
并保持比率len([SA''] along P) / len(P)
接近{{1}}。我们对您将要处理的确切案例知之甚少,当然还有更多的启发式方法可以放弃深度优先搜索树的部分内容。
答案 1 :(得分:3)
由于您遇到的问题是每个步骤的成本为1,因此名为depth-limited search的深度优先搜索的简单变体应该能够找到您想要的路径类型。 Python中的天真版本:
def dls(path, goal, depth):
last = path[-1]
if len(path) == depth:
if last == goal:
return path
else:
for n in neighbors(last):
if allowed(n) and n not in path:
path.append(n)
solution = dls(path, depth)
if solution:
return solution
path.pop()
# call as:
dls([start], goal, depth)
正如其他人所指出的那样,问题是NP完全的,所以不要指望奇迹会有更长的路径长度。
Russell & Norvig是这种算法的权威教科书。
答案 2 :(得分:2)
如果有一个快速算法,你可以插入number of nodes = n
,算法会很快告诉你是否有Hamiltonian Path。由于这个问题是NP完全的,你的问题也是如此。