1. 程式人生 > 實用技巧 >Python筆試——畢業旅行問題

Python筆試——畢業旅行問題

畢業旅行問題

小明目前在做一份畢業旅行的規劃。打算從北京出發,分別去若干個城市,然後再回到北京,每個城市之間均乘坐高鐵,且每個城市只去一次。由於經費有限,希望能夠通過合理的路線安排儘可能的省一些路上的花銷。給定一組城市和每對城市之間的火車票的價錢,找到每個城市只訪問一次並返回起點的最小車費花銷。

輸入描述:

城市個數n(1<n≤20,包括北京)

城市間的車票價錢 n行n列的矩陣 m[n][n]

輸出描述:

最小花銷 s

輸入例子1:

4

0 2 6 5

2 0 4 4

6 4 0 2

5 4 2 0

輸出例子1:

13

例子說明1:

共 4 個城市,城市 1 和城市 1 的車費為0,城市 1 和城市 2 之間的車費為 2, 城市 1 和城市 3 之間的車費為 6,城市 1 和城市 4 之間的車費為 5。 依次類推。假設任意兩個城市之間均有單程票可購買,且票價在1000元以內,無需考慮極端情況。

思路:

1、permutations模組

這裡我的第一想法就是遍歷所有的情況計算路費進而去最小值。

那麼這裡如果要遍歷所有路線的話,可以用到permutations模組來獲取所有的排列結果。

下面用一個列表來說明permutations模組的用法:

from itertools import permutations
li = [1,2,3]
print(permutations(li))
for i in permutations(li):
    print(i)

程式碼執行結果如下:

<itertools.permutations object at 0x000001A15C7B17C8>
(
1, 2, 3) (1, 3, 2) (2, 1, 3) (2, 3, 1) (3, 1, 2) (3, 2, 1)

可看到permutations函式返回的是一個可迭代物件,而不是列表型別, 所以列印的時候不會列印列表。

另外要格外注意的是,permutations函式得出的所有排列情況是元組型別而非列表。

permutations()可加第二個引數,代表排列的長度:

from itertools import permutations
li = [1,2,3]
print(permutations(li))
for i in permutations(li,2):
    print(i)

程式碼執行結果如下:

<itertools.permutations object at 0x0000022604F827C8>
(1, 2)
(1, 3)
(2, 1)
(2, 3)
(3, 1)
(3, 2)

2、程式碼實現

import itertools
n = int(input()) #城市個數n(1<n≤20,包括北京)
L = [] #城市間的車票價錢 n行n列的矩陣 [n][n]
for i in range(n):
    L.append(list(map(int, input().split(' '))))
 
def treaval(L, n):
    # 除起點之外的不同路線組合,假設起點為0號節點
    com = list(itertools.permutations(list(range(1, n)), n - 1))  #range函式返回的是一個可迭代物件,而不是列表型別, 所以列印的時候不會列印列表。
    spend = 9999  # 假設一開始花銷很大
    for j in range(len(com)): #len(com)是可選擇的路線種類數
        road = list(com.pop(0))# 獲取其中一種路線組合road列表之後就釋放,com是一個元組序列
        # 補全起點和終點(注意起點也是終點,形成閉環)此時road長度為n+1
        road.append(0)#在列表末尾新增新的物件
        road.insert(0, 0)#將物件插入列表
        x = 0 # 當前路線的花銷
        for i in range(n):
            x = x + L[road[i]][road[i + 1]]
        if x < spend:
            spend = x #更新最小花銷
    return spend
 
print(treaval(L, n))

今天的第二個筆試題啦!

出去跑個步,回來繼續加油~