1. 程式人生 > >貪心演算法:旅行商問題(TSP)

貪心演算法:旅行商問題(TSP)

TSP問題(Traveling Salesman Problem,旅行商問題),由威廉哈密頓爵士和英國數學家剋剋曼T.P.Kirkman於19世紀初提出。問題描述如下:
有若干個城市,任何兩個城市之間的距離都是確定的,現要求一旅行商從某城市出發必須經過每一個城市且只在一個城市逗留一次,最後回到出發的城市,問如何事先確定一條最短的線路已保證其旅行的費用最少?

另一個類似的問題為:一個郵遞員從郵局出發,到所轄街道投郵件,最後返回郵局,如果他必須走遍所轄的每條街道至少一次,那麼他應該如何選擇投遞路線,使所走的路程最短?這個描述之所以稱為中國郵遞員問題(Chinese Postman Problem CPP)

為簡化該問題,假設只有A、B、C、D四個城市,各城市的關係如圖所示,權值表示兩個城市之間的的距離。
這裡寫圖片描述
為了將圖中關係資料化,可用如下規則來描述:

城市對映為編號:A——0,B——1,C——2,D——3;
城市之間的距離用二維陣列來表示,記為D[i][j],如:D[0][1]表示城市A與城市B之間的距離,於是D[0][1]=2;
用一維陣列S[i]來儲存訪問過的路徑。

該問題的基本解法為遞迴遍歷,但是會產生組合爆炸問題(時間複雜度為n!),此處不做介紹,而引入一種更為高效的解法:貪心演算法。該演算法描述如下:

貪心演算法:又稱貪婪演算法(greedy algorithm),該演算法是指:在對問題求解時,總是做出當前情況下的最好選擇,否則將來可能會後悔,故名“貪心”。這是一種演算法策略,每次選擇得到的都是區域性最優解

。選擇的策略必須具備無後效性,即某個狀態以前的過程不會影響以後的狀態,只與當前狀態有關。
針對TSP問題,使用貪心演算法的求解的過程為:
1.從某一個城市開始,每次選擇一個城市,直到所有的城市被走完。
2.每次在選擇下一個城市的時候,只考慮當前情況,保證迄今為止經過的路徑總距離最小。

使用貪心演算法求解TSP問題的步驟描述如圖所示:
這裡寫圖片描述這裡寫圖片描述這裡寫圖片描述

具體程式碼如下:

#include<iostream>
using namespace std;
#define n 4
int main()
{
    int i,j,k,l;
    int S[n];//用於儲存已訪問過的城市
int D[n][n];//用於儲存兩個城市之間的距離 int sum = 0;//用於記算已訪問過的城市的最小路徑長度 int Dtemp;//保證Dtemp比任意兩個城市之間的距離都大(其實在演算法描述中更準確的應為無窮大) int flag;////最為訪問的標誌,若被訪問過則為1,從未被訪問過則為0 /*初始化*/ i = 1;//i是至今已訪問過的城市 S[0] = 0; D[0][1] = 2;D[0][2] = 6;D[0][3] = 5;D[1][0] = 2;D[1][2] = 4; D[1][3] = 4;D[2][0] = 6;D[2][1] = 4;D[2][3] = 2;D[3][0] = 5; D[3][1] = 4;D[3][2] = 2; do{ k = 1;Dtemp = 10000; do{ l = 0;flag = 0; do{ if(S[l] == k){//判斷該城市是否已被訪問過,若被訪問過, flag = 1;//則flag為1 break;//跳出迴圈,不參與距離的比較 }else l++; }while(l < i); if(flag == 0&&D[k][S[i - 1]] < Dtemp){/*D[k][S[i - 1]]表示當前未被訪問的城市k與上一個已訪問過的城市i-1之間的距離*/ j = k;//j用於儲存已訪問過的城市k Dtemp = D[k][S[i - 1]];//Dtemp用於暫時儲存當前最小路徑的值 } k++; }while(k < n); S[i] = j;//將已訪問過的城市j存入到S[i]中 i++; sum += Dtemp;//求出各城市之間的最短距離,注意:在結束迴圈時,該旅行商尚未回到原出發的城市 }while(i < n); sum += D[0][j];//D[0][j]為旅行商所在的最後一個城市與原出發的城市之間的距離 for(j = 0; j < n; j++){ //輸出經過的城市的路徑 cout<<j<<" "; } cout<<"\n"<<sum;//求出最短路徑的值 }

執行結果如下圖所示:
這裡寫圖片描述

參考資料:《計算機導論》第7講-演算法-程式與計算系統之靈魂

相關推薦

【機器學習】利用蟻群演算法求解行商TSP問題

如果喜歡這裡的內容,你能夠給我最大的幫助就是轉發,告訴你的朋友,鼓勵他們一起來學習。 If you like the content here, you can give me the greatest help is forwarding, tell you

遺傳演算法求解行商TSP問題

1. TSP問題概述 TSP問題即旅行商問題,是數學領域的著名問題之一。假設有一個旅行商人要拜訪n個城市,他必須選擇所要走的路徑,路徑的限制是每個城市只能拜訪一次,而且最後要回到原來出發的城市。路徑的選擇目標是要使求得的路徑路程為所有路徑之中的最小值。 2. 基於遺傳演算法

模擬退火演算法行商TSP問題

該帖子的程式碼主要轉自模擬退火演算法1. 該文對模擬退火演算法作了較好的分析,不過該文中舉例的TSP的程式碼有一些問題,我對此作了修正,並在文中最後做出解釋。 程式碼如下: #include <iostream> #include <

貪心演算法行商問題TSP

TSP問題(Traveling Salesman Problem,旅行商問題),由威廉哈密頓爵士和英國數學家剋剋曼T.P.Kirkman於19世紀初提出。問題描述如下: 有若干個城市,任何兩個城市之間的距離都是確定的,現要求一旅行商從某城市出發必須經

HDU 5067 動態規劃---行商tsp問題

動態規劃的狀態有時不易表示,需要用一些編碼技術把狀態用簡單的方式表示。一般資料n<16或者n<32很可能就是狀態壓縮dp法的標誌,要注意好這些資料規模的提示作用。我們以TSP問題為例用狀態壓縮dp法解決。TSP問題(Traveling Salesman Pro

粒子群演算法求解行商問題TSP JAVA實現

粒子群演算法求解旅行商問題TSP 寫在開頭: 最近師妹的結課作業問我,關於使用粒子群求解TSP問題的思路。我想了想,自己去年的作業用的是遺傳演算法,貌似有些關聯,索性給看了看程式碼。重新學習了一遍粒子群演算法,在這裡記錄一下,算是對知識的總結,鞏固一下。

機器學習演算法交叉驗證——監督學習器效能評估方法 [ sklearn.model_selection.cross_val_score()官方翻譯 ]

交叉驗證——(監督)學習器效能評估方法 一、思考:交叉驗證有什麼好值得我們使用的? 每個演算法模型都需要經過兩個階段:訓練和驗證。 1) 一般情況下的,我們用的方法是:將原始資料集分為 訓練資料集 & 測試資料集。 優點:是,但僅僅是思路正確。 缺點:思

貪心演算法之——噴水裝置

描述 現有一塊草坪,長為20米,寬為2米,要在橫中心線上放置半徑為Ri的噴水裝置,每個噴水裝置的效果都會讓以它為中心的半徑為實數Ri(0<Ri<15)的圓被溼潤,這有充足的噴水裝置i(1

AI產品經理必懂演算法k-近鄰KNN演算法

我們之所以要了解演算法,不僅僅有利於和演算法同學的溝通,更能深入的理解人工智慧為產品賦能的過程,只有將這個過程瞭解透徹,才能清晰明確的把握產品的方向,挖掘產品的亮點。 那麼,今天我們就從一個最為簡單、易懂的“k-近鄰(KNN)演算法”聊起,KNN屬於監督學習演算法,即可以用於分類,也可以用於迴歸,後續還會逐

行商問題TSP蟻群演算法Java

旅行商問題,即TSP問題(Traveling Salesman Problem)是數學領域中著名問題之一。假設有一個旅行商人要拜訪N個城市,他必須選擇所要走的路徑,路徑的限制是每個城市只能拜訪一次,而且最後要 回到原來出發的城市。路徑的選擇目標是要求得的路徑路程為所有路徑之中

【原】總tucao粒子群演算法(PSO)解決行商問題(TSP)

粒子群演算法(PSO)是一套比較經典的演算法, 旅行商問題(TSP)同樣是一個經典的問題。如果想用PSO去解決TSP問題的話,那麼應該如何去解決呢? 初看之下一陣欣喜,因為我發現,如果按照論文中的方法能夠成功的話,那麼包括布穀鳥,螢火蟲都可以通過類似的辦法

PSO解決TSP問題粒子群演算法解決行商問題--python實現

歡迎私戳關注這位大神! 有任何問題歡迎私戳我->給我寫信 首先來看一下什麼是TSP: The travelling salesman problem (TSP) asks the following question: "Given a list

演算法課堂實驗報告——python回溯法與分支限界法行商TSP問題

python實現回溯法與分支限界 一、開發環境 開發工具:jupyter notebook 並使用vscode,cmd命令列工具協助程式設計測試演算法,並使用codeblocks輔助編寫C++程式 程式語言:python3.6 二、實驗目標 1. 請用回溯法求對稱的旅

基於分支限界法的行商問題TSP

//分支限界法 #include<iostream> #include<algorithm> #include<cstdio> #include<queue> const int INF = 100000; const int MAX_N = 22; usin

容器開啟數據服務之系列Kubernetes如何助力Spark大數據分析

容器 控制臺 摘要: 容器開啟數據服務之旅系列(二):Kubernetes如何助力Spark大數據分析 (二):Kubernetes如何助力Spark大數據分析 概述 本文為大家介紹一種容器化的數據服務Spark + OSS on ACK,允許Spark分布式計算節點對阿裏雲OSS對象存儲的直接訪問。

[python]My Unique JsonDiff演算法——如何計算2個json串之間的差距並Diff出來編輯距離Levenshtein演算法

    啊啊,年底忙著簽證什麼的,好久沒寫日誌啦。。。。新年到來,整點乾貨出來給大家~~順便為自己考試和申請學校攢點人品~~     之前實習的時候,因為實習公司的業務需求,需要一個比對json字串差異的演算法,然而我在網上查了很久的資料,發現竟然沒有現成

Java常用的八種排序演算法與程式碼實現桶排序、計數排序、基數排序

三種線性排序演算法:桶排序、計數排序、基數排序 線性排序演算法(Linear Sort):這些排序演算法的時間複雜度是線性的O(n),是非比較的排序演算法 桶排序(Bucket Sort)   將要排序的資料分到幾個有序的桶裡,每個桶裡的資料再單獨進行排序,桶內排完序之後,再把桶裡的

Java常用的八種排序演算法與程式碼實現歸併排序法、快速排序法

注:這裡給出的程式碼方案都是通過遞迴完成的 --- 歸併排序(Merge Sort):   分而治之,遞迴實現   如果需要排序一個數組,我們先把陣列從中間分成前後兩部分,然後對前後兩部分進行分別排序,再將排好序的數組合並在一起,這樣整個陣列就有序了   歸併排序是穩定的排序演算法,時間

優化演算法牛頓法Newton法

學習深度學習時遇到二階優化演算法牛頓法,查閱了相關書籍進行記錄。 :函式的梯度向量 :函式的Hessian矩陣,其第i行第j列的元素為. 假設是二階連續可微函式,。最速下降法因為迭代路線呈鋸齒形,固收斂速度慢,僅是線性的。最速下降法本質使用線性函式去近似目標函式。要得到快速的演算法,

演算法 - 06 | 連結串列如何實現LRU快取淘汰演算法?

連結串列的一個景點應用場景 --- LRU快取淘汰演算法 1. 快取 什麼是快取 快取是一種提高資料讀取效能的技術,在硬體設計、軟體開發中都有著非常廣泛的應用,比如常見的CPU快取、資料庫快取、瀏覽器快取等等。 快取淘汰策略 快取大小有限,當快取被用滿是,那些資料應該被清理出去,那些資料被