为什么我的最短哈密顿路径算法不是最理想的?

时间:2016-01-02 02:25:06

标签: python algorithm greedy traveling-salesman

我试图从头开始在Python中编写一个强力算法,解决加权完整图的最短哈密顿路径问题,如下所示:

def min_route(cities, distances):
    """Finds the Shortest Hamiltonian Path for a weighted complete graph.

    Args:
        cities (list of string):
            The vertices of the graph.

        distances (dict):
            The distances between any two cities. Maps each origin city to a
            dictionary that maps destination cities to distances, sort of like
            an adjacency matrix. Type: Dict<string, Dict<string, int>>.

    Returns:
        (list of string, int):
            The list of cities in the optimal route and its length.
    """
    if len(cities) < 2:
        return cities, 0

    best_route, min_dist = None, float('inf')
    for i in range(len(cities)):
        first, rest = cities[i], cities[:i] + cities[i+1:]
        sub_route, sub_dist = min_route(rest, distances)
        route = [first] + sub_route
        dist = sub_dist + distances[first][sub_route[0]]
        if dist < min_dist:
            best_route, min_dist = route, dist

    return best_route, min_dist

事实证明,该算法不起作用,并且它对初始城市列表的顺序很敏感。这让我很困惑,因为我认为它会枚举所有n!可能的城市排列,其中n是城市的数量。我似乎太早修剪了一些路线;相反,我应该做类似的事情:

def min_route_length(cities, distances):
    routes = get_a_list_of_all_permutations_of(cities)
    return min(compute_route_length(route, distances) for route in routes)
  

问题:什么是简单的反例,说明为什么我的算法不是最理想的?

     

跟进:我的次优算法至少是某种使用某种贪心启发式算法的近似算法吗?或者它真的只是一个可怕的O(n!)算法?

1 个答案:

答案 0 :(得分:1)

假设您的图表是定向的(从A到B以及从B到A可以有不同的权重),其中一个反例就是

   A  B  C
A  x  1  5
B 30  x 10
C 30  9  x

不是从A开始的路径的成本至少为30,所以我们不需要考虑它们。对于以A开头的路径,您的代码使用[B, C]进行递归调用。它们的最佳排列是C> B,成本为9,这是递归调用的返回值。然而,整个路径A> C> B具有成本14,而最佳路径A> B> C且成本为11。

你是O(n!)你是对的。你只需要向下传递一个额外的参数 - 起始点(第一次调用可能为None)并在计算dist时考虑它。