A *多目标搜索(Python)

时间:2015-02-17 20:00:26

标签: python search

我正在尝试编写一个完成具有多个目标的A *搜索的函数。基本上它正在搜索格式的网格结构:

%%%%%%%%%%%%%%%%%%%%
%.           ...P .%
%.%%.%%.%%.%%.%% %.%
% %% %.....      %.%
%%%%%%%%%%%%%%%%%%%%

来自P的路径经过所有点(基本上是Pacman)。

然而,我遇到了我的算法问题(我尝试从A *搜索单一目标进行调整),因为它返回的路径没有通过所有点。这是它为上述迷宫返回的路径:

路径= [(1,1),(1,2),(1,3),(1,4),(1,5),(1,6),(1,7),(1) ,8),(1,9),(1,10),(1,11),(1,12),(1,13),(1,14),(1,15),(1,16) )]

而print语句显示被访问变量的返回值为:

[(1,16),(1,15),(2,16),(1,17),(1,14),(3,16),(1,18),(1,13) ),(3,15),(2,18),(1,12),(2,13),(3,18),(3,14),(1,11),(3,13), (3,12),(1,10),(1,9),(3,11),(2,10),(1,8),(3,10),(1,7),(3) ,9),(1,6),(3,8),(2,7),(1,5),(3,7),(1,4),(3,6),(2,4) ),(1,3),(3,4),(1,2),(1,1),(2,1)]

我认为这个问题是我存储当前路径的方式(每个节点存储其父节点的位置,然后我返回结束节点并递归后退以获取路径)。有没有人对我应该改变什么有任何建议?我在下面附上了我当前的代码。谢谢!

1 个答案:

答案 0 :(得分:1)

您的算法目前正在尝试通过在起点周围扩展其区域并为其访问的每个节点找到最佳路径来尝试找到目标。

在单目标情况下,它运作良好,您可以获得此目标的路径。 但是,如何将其调整为多目标目的是只有停止条件发生变化(当所有目标都被访问过一次时),这意味着您找到了从起点到每个目标的最短路径,但没有找到访问所有目标的单一路径节点

在这种情况下,您只需要从起点到每个目标的路径,只需从每个目标点获取路径(通过父级)。

如果你真的想实现类似pacman的搜索,那就是NP-Hard问题(见this answer)。

正如评论中提出的那样,如果你有一个小目标列表,你可以找到一个蛮力的解决方案: 让我们说你有3个目标:A,B,C(点数):

%%%%%%%%%%%%%%%%%%%%
%A              P  %
% %% %% %% %%C%% % %
% %% %   B       % %
%%%%%%%%%%%%%%%%%%%%

使用您的算法,您可以找到从P到A的最短路径,然后是A到B,然后是B到C.对其他排列((P,A,C,B)(P,B,A,C) ...)执行相同的操作:见itertools.combinations(goals, len(goals))

然后,您可以使用算法查找从一个点到另一个点的路径:

def A_multiple_goals(maze, start, goals):
    paths = []
    for itinerary in itertools.combinations(goals, len(goals)):
        path = get_path(A_search_multiple(maze, start, itinerary[0])) # First go to first goal from start
        for i in range(1 , len(itinerary)): # Then from each goal, goto the next one
            path += get_path(A_search_multiple(maze, itinerary[i-1], itinerary[i]))
        paths.append(paths)
    return min(paths, key=len)

这是一种蛮力的方法,如果你有很多目标,你需要一个基于Traveling Salesman Problem的更好的算法。