【问题标题】:Why is my Shortest Hamiltonian Path algorithm suboptimal?为什么我的最短哈密顿路径算法不是最优的?
【发布时间】:2016-01-02 02:25:06
【问题描述】:

我试图在 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!) 算法?

【问题讨论】:

    标签: python algorithm greedy traveling-salesman


    【解决方案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 时考虑它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-03
      • 2012-10-26
      • 1970-01-01
      • 1970-01-01
      • 2016-06-18
      • 2011-11-12
      • 2021-04-18
      • 2023-04-09
      相关资源
      最近更新 更多