Python 最短链路策略(ShortestLinkedHeuristic)解决TSP问题

15 篇文章 0 订阅
3 篇文章 0 订阅

ShortestLinkedHeuristic 最短链路策略算法

基于贪心思想,每次选择一条没有被选择过的权重最小的边,检查是否与已有的边构成循环或者引起某个顶点分叉,如果没有则加入H。重复这个过程直到所有的边都被检查过。

输入:无向连通图
输出:TSP路径

思路

首先给出关于无向图的所有边和权重,以及所有顶点,接着按照ShortestLinkedHeuristic算法思路,构造路线集合H,每次从边集合E中取出权重最小的边,如果这条边与H不会形成一个循环,并且不会导致路线分叉,则将这条边加入路线集合H;直到边集合E为空,从H中找到两个度为1的顶点,将它们相连,使路线连通(无向图可能需要满足完全图的条件

运行环境

  • Python3.6
  • Numpy 1.17.3

代码函数说明

  • ShortestLinkedHeuristic(G, visited, label)
  • 任选一个城市开始,到达离它最近的城市,然后从该城市出发,选择离它最近的未访问过的城市,重复该过程,直到所有城市都被访问过,再回到开始城市。

代码实现

from copy import deepcopy

def has_cycle(G):
    """
    判断无向图是否有环
    :param G: example {0: [1,2],1: [3], 2: []}
    :return:True无环,False有环
    """
    V = set()
    U = dict()
    cycle_set = []
    def dfs(u, v):
        V.add(u)
        for x in G.get(u, []):
            if x not in V:
                U[x] = u
                dfs(x, u)
            elif x != v:
                try:
                    path = []
                    _x = u
                    while _x != x:
                        path.insert(0, _x)
                        _x = U[_x]
                    path.insert(0, _x)
                except:
                    path = []
                cycle_set.append(path + [x])
    for x in G:
        if x not in V:
            dfs(x, x)
    return len(cycle_set) == 0


def ShortestLinkedHeuristic(G, visited, label):
    """
    最短链接策略
    :param G: [[u,v,w]]
    :param visited: 顶点
    :param label: 标签
    :return:路径
    """
    _G = {}
    H = []
    for v in visited:
        _G.update({v:[]})
    E = G.copy()
    while len(E)>0:
        min_u, min_v = -1, -1
        min_w = 10000003
        for u,v,w in E:
            if w < min_w:
                min_u,min_v,min_w = u,v,w
        E.remove([min_u,min_v,min_w])
        __G = deepcopy(_G)
        __G[min_u].append(min_v)
        if(has_cycle(__G)):
            _G = __G
            H.append((min_u, min_v))
    V = {}
    for v in visited:
        V.update({v:0})
    for u, v in H:
        V[u]+=1
        V[v]+=1

    _u, _v = -1, -1
    for u in V:
        if V[u] == 1:
            if _u == -1:
                _u = u
            else:
                _v = u
                break
    if _u != -1 and _v != -1:
        H.append((_u, _v))
    result = []
    for u, v in H:
        result.append((label[u], label[v]))
    return result


visited = [0,1,2,3]
G = [
    [0,1,20],
    [0,2,15],
    [0,3,35],
    [1,2,10],
    [1,3,25],
    [2,3,12]
]

label = ['a', 'b', 'c', 'd']
result = ShortestLinkedHeuristic(G, visited, label)
print(result)

无向完全图

在这里插入图片描述

运行结果

[('b', 'c'), ('c', 'd'), ('a', 'b'), ('a', 'd')]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值