图论-python-TSP问题

1. 原问题及答案:

有一位商人,他想访问中国的某些城市,要求:所走路程最近;每个城市只能访问一次;从某城市出发,最后回到该城市(要求城市间都可达)。

#  源自:https://blog.csdn.net/weixin_48180029/article/details/120378048
import sys

city_distance = [[0, 3, 1, 5, 8],
                 [3, 0, 6, 7, 9],
                 [1, 6, 0, 4, 2],
                 [5, 7, 4, 0, 3],
                 [8, 9, 2, 3, 0]]
#city_distance[i][j] 表示顶点i到顶点j的距离

city = [i for i in range(1,len(city_distance))]     #除去出发点的城市序号
len = len(city)


bestCost = sys.maxsize  #最优路线的路程
def backtrack(first):
    if(first == len):

        sum = 0
        sum += city_distance[0][city[0]]
        for i in range(1,len):
            sum += city_distance[city[i-1]][city[i]]
        sum += city_distance[city[len-1]][0]
        print(city," ",sum)

        global bestCost
        bestCost =  min(bestCost,sum)
        return

    for i in range(first,len):
        city[i],city[first] = city[first],city[i]
        backtrack(first+1)
        city[i], city[first] = city[first], city[i]
if __name__ == '__main__':
    backtrack(0)

    print(bestCost)


'''
# 考虑两个顶点不可达的情况:
import sys

city_distance = [[0, 3, 1, 5, 8],
                 [3, 0, 6, 7, 9],
                 [1, 6, 0, 4, -1],
                 [5, 7, 4, 0, 3],
                 [8, 9, -1, 3, 0]]
#city_distance[i][j] 表示顶点i到顶点j的距离

city = [i for i in range(1,len(city_distance))]     #除去出发点的城市序号
len = len(city)


bestCost = sys.maxsize  #最优路线的路程
def backtrack(first,sum):
    if(first == len):
        t = city_distance[city[len-1]][0]

        if t == -1:     #表明该条路线走不通
            return
        sum += t
        print(city," ",sum)

        global bestCost
        bestCost =  min(bestCost,sum)
        return

    for i in range(first,len):
        city[i],city[first] = city[first],city[i]
        if (first == 0):
            t = city_distance[0][city[first]]
        else:
            t = city_distance[city[first - 1]][city[first]]

        if( t == -1):       #表明该条路线走不通
            continue

        backtrack(first+1,sum + t)
        city[i], city[first] = city[first], city[i]
if __name__ == '__main__':
    backtrack(0,0)

    print(bestCost)





'''
TSP问题解法

2. 新问题及答案:

一个蚂蚁从(0,0)坐标出发,遍历所有点的最短路径,蚂蚁走网格。

输入:[[0,5],[1,1]]

输出:7 (解释:0,0->1,1为2,1,1到0,5是5,总共7)

输入2:[[0,1],[0,2],[0,3]]

输出2:3

解法:构建各个点之间的距离矩阵,使用TSP解法求解。

import sys


# [[0,5],[1,1]]
# [[0,1],[0,2],[0,3]]
x = eval(input())
x = [[0, 0], ] + x
city_distance = []
for i in range(len(x)):
    temp = []
    for j in range(len(x)):
        temp.append(abs(x[i][0] - x[j][0]) + abs(x[i][1] - x[j][1]))
    city_distance.append(temp)

# city_distance = [[0, 2, 5],
#                  [2, 0, 5],
#                  [5, 5, 0]]

city = [i for i in range(1, len(city_distance))]     #除去出发点的城市序号
len = len(city)


bestCost = sys.maxsize  #最优路线的路程
def backtrack(first, sum):
    if(first == len):
        t = city_distance[city[len-1]][0]

        if t == -1:     #表明该条路线走不通
            return
        # sum += t
        # print(city," ",sum)

        global bestCost
        bestCost =  min(bestCost, sum)
        return

    for i in range(first,len):
        city[i],city[first] = city[first],city[i]
        if (first == 0):
            t = city_distance[0][city[first]]
        else:
            t = city_distance[city[first - 1]][city[first]]

        if( t == -1):       #表明该条路线走不通
            continue

        backtrack(first+1,sum + t)
        city[i], city[first] = city[first], city[i]


if __name__ == '__main__':
    backtrack(0, 0)
    # print(city)
    # print(bestCost - city_distance[0][city[-1]])
    print(bestCost)

 

posted @ 2022-09-16 09:27  落月_YU  阅读(172)  评论(0编辑  收藏  举报