遺傳算法解決TSP問題(原理與主函數)

2021-02-07 基山督

原理:


傳算法解決TSP問題知識點

 

1.介紹:

摘自百度百科:遺傳算法(Genetic Algorithm)是模擬達爾文生物進化論的自然選擇和遺傳學機理的生物進化過程的計算模型,是一種通過模擬自然進化過程搜索最優解的方法。

 

2.名詞解析: 

基因:用來表示個體的特徵,算法中簡化為城市的編號,例如1,2,3,10,9….

 

染色體:又叫做基因型個體,一定數量的個體組成種群(population)

(程序中我的初始設置是100,一般偶數對出現)

 適應度:個體對環境的適應程度。程序中用該條染色體對應路線的距離作為適應度值。

自然選擇;採用輪盤賭的方式,適應度值越大那麼它在所佔的面積更大,越有可能被選擇後記錄下來。值越小則越有可能被淘汰。

簡單說來就是:好的個體被保留,壞的逐漸被淘汰,經過不斷的迭代逼近最好的結果。

(這裡另外有一個代溝的概念,子代的數量會變少)

交叉互換:基因的重組,把父代個體的部分結構加以替換重組,類似於生個小寶寶。

 

變異:對某些基因做變動,隨機互換路線中的兩個城市。

 

進化逆轉:隨機逆轉基因中的一段基因,如果距離更短該路線會被保留。

 

重新插入父代優秀個體到子代:因為子代會少一些,重新插入優秀個體保證下次迭代數目穩定。

3.算法流程:

1. 開始

2.建立種群(或者更新種群)

3.記錄上次迭代最優值、適應度值

4. 自然選擇

5. 交叉互換產生子代

6. 基因的變異

7. 進化逆轉

8. 重新插入優秀父代個體到子代

9. 動態路線展示(迭代次數未達到轉到第三步)

10. 結束

主函數:

----

 

%% GA遺傳算法用來解決TSP問題測試文件

clc;

clear    %清屏清除工作區

close all;

%% 取得要處理的城市的坐標,作出初始圖

%position=load('景區經緯度.txt');

%這句可以讀入所需要處理的數據,以下採用的是隨機產生的坐標信息

t0=clock;

citys=[

1304 2312;

3639 1315;

4177 2244;

3712 1399;

3488 1535;

3326 1556;

3238 1229;

4196 1004;

4312 790;

4386 570;

3007 1970;

2562 1756;

2788 1491;

2381 1676;

1332 695;

3715 1678;

3918 2179;

4061 2370;

3780 2212;

3676 2578;

4029 2838;

4263 2931;

3429 1908;

3507 2367;

3394 2643;

3439 3201;

2935 3240;

3140 3550;

2545 2357;

2778 2826;

2370 2975

]; 

x = citys(:,1);

y = citys(:,2);

xlabel('經度');       %橫坐標

ylabel('緯度');       %縱坐標

title('TSP問題遺傳算法(GA)優化');    %圖片標題

grid on

%% 計算各個城市之間的距離

n = size(citys,1);

for i = 1:n

    for j = 1:n    

            D(i,j) = sqrt((x(i)-x(j))^2 + (y(i)-y(j))^2);  %距離公式

    end    

end

%% 算法的初始設置

POP_num = 100;    %種群的數量

MAXiter = 300;     %最大的迭代次數

pc = 0.8;    %交叉概率

pm = 0.06;      %變異概率

GAP = 0.9; %代溝(也就是選擇概率)

route_evo = zeros(MAXiter,n+1);  %記錄每次迭代之後的最優路線進化

best_value = zeros(MAXiter,1);

Length_ave = zeros(MAXiter,1);

Route_long = zeros(POP_num,1);

%% 種群的初始化

global Chrom

Chrom = zeros(POP_num,n); 

for i=1:POP_num

    Chrom(i,:) = randperm(n);   %隨機產生初始的種群

end

%% 記錄一個初始的隨機解後開始優化

%suijishu = unidrnd(n);

iter = 0;

times = 0;

while iter < MAXiter

    

    for i = 1:POP_num

        Route_long(i) = Routelength(D,Chrom(i,:));  %計算路線總長度

    end

    

    [route_best,best_index] = min(Route_long);

    

    Length_ave(iter+1) = mean(Route_long);     %每次迭代路線距離的平均值

    best_value(iter+1) = route_best;

    route_evo(iter+1,:) = [Chrom(best_index,:) Chrom(best_index,1)];  %記錄下這次的最優路線

    

    Fit = 1./Route_long; %適應度值

    

    %%選擇操作(個體的適應度值越大越有可能被選中)

    

    select_num = max(floor(POP_num*GAP+0.6),2);   %被選中的染色體數目

    

    NEWChrom1 = Select(Fit,select_num); 

    

    %%交叉操作

    NEWChrom2 = Cross(NEWChrom1, pc);

    

    %%變異操作

    NEWChrom2 = Mutate(NEWChrom2, pm);

    

    %%進化逆轉操作

    NEWChrom2 = Reverse(NEWChrom2, D);

    

    %%重插入幾條優秀的父代基因到子代裡形成新種群

    Chrom = Rein(Chrom, NEWChrom2,Route_long);

    

   %%做一個動態的效果   

    if times >= 10

        cla;     

        Route_all = route_evo(iter+1,:);

        plot(citys(Route_all,1), citys(Route_all,2), 'bo-'); 

        text(citys(Route_all(1),1),citys(Route_all(1),2),'     起點');

        text(citys(Route_all(end-1),1),citys(Route_all(end-1),2),'    終點');

        pause(0.1);

        times = 0;

    end

    

    iter = iter + 1;

    times = times + 1;

  

end

%% 命令窗口的結果顯示

Time_Cost=etime(clock,t0);   %調用windows系統的時鐘進行時間差計算

disp(['環遊城市的最短距離:' num2str(best_value(end))]);

arrow = '%d ----> %d\n';

disp('最短路線如下所示:');

Route_print = route_evo(end,:);

for i=1:n

  fprintf(arrow,Route_print(i),Route_print(i+1));

end

disp(['程序執行時間:' num2str(Time_Cost) '秒']);

%% 畫出最終結果圖

figure()

for i = 1 : n                            

   scatter(x(i),y(i),'b');            %畫出散點圖

   hold on

   text(x(i)+1,y(i)+1,num2str(i))     %用text做好標記,

end

plot(citys(Route_print,1), citys(Route_print,2), 'bo-'); 

text(citys(Route_print(1),1),citys(Route_print(1),2),'     起點');

text(citys(Route_print(end-1),1),citys(Route_print(end-1),2),'    終點');

xlabel('經度');       %橫坐標

ylabel('緯度');       %縱坐標

title('最終結果圖');    %圖片標題

grid on

%% 畫出迭代過程曲線

figure()

subplot(1,2,1)

plot(best_value)

xlabel('迭代次數')

ylabel('最短距離收斂軌跡')

subplot(1,2,2)

plot(Length_ave)

xlabel('迭代次數')

ylabel('平均距離收斂軌跡')

%% 程序可以改進的地方還有很多,留個小疑問給大家

%如何再加一個跳出循環的條件:我的結果被保持了n次(具體數字根據迭代次數設置)提前跳出?

%我之前的視頻裡有答案,可以翻翻。當你會往程序裡加這個條件,那說明基本都弄懂了哦

----

相關焦點

  • 實驗三 遺傳算法解決TSP問題實驗
    一、實驗目的1.熟悉和掌握遺傳算法的原理、流程和編碼策略。
  • 遺傳算法概述
    屬於啟發式搜索算法一種,這個算法比較有趣,並且弄明白後很簡單,寫個100-200行代碼就可以實現。在某些場合下簡單有效。本文就花一些篇幅,儘量白話方式講解一下。 首先說一下問題。在我們學校數據結構這門功課的時候,時常會有一些比較經典的問題(而且比較複雜問題)作為學習素材,如八皇后,背包問題,染色問題等等。上面列出的幾個問題都可以通過遺傳算法去解決。
  • 遺傳算法簡述
    屬於啟發式搜索算法一種,這個算法比較有趣,並且弄明白後很簡單,寫個100-200行代碼就可以實現。在某些場合下簡單有效。本文就花一些篇幅,儘量白話方式講解一下。       首先說一下問題。在我們學校數據結構這門功課的時候,時常會有一些比較經典的問題(而且比較複雜問題)作為學習素材,如八皇后,背包問題,染色問題等等。上面列出的幾個問題都可以通過遺傳算法去解決。
  • 遺傳算法簡介、基本原理及算法實現
    遺傳算法算是一個比較複雜的算法,本文主要分為三個部分,第一部分遺傳算法的發展、功能、主要思想以及簡單的代碼命令;第二部分詳細介紹遺傳算法的機理,第三部分舉例並給出一個簡單地使用方法。雖然遺傳算法存在諸如陷入局部最優解,收斂速度緩慢等問題,人們也進行了很多的修改,但是鑑於遺傳算法本身就具有很高的性能,而且各種修正方案都存在一定的複雜性和非普適性,所以經典遺傳算法在應用領域還是幾乎絕對的主流。二、遺傳算法的原理遺傳的算法的背景是達爾文的進化論,沒錯!
  • 白話講解遺傳算法 (Genetic Algorithm)
    屬於啟發式搜索算法一種,這個算法比較有趣,並且弄明白後很簡單,寫個100-200行代碼就可以實現。在某些場合下簡單有效。本文就花一些篇幅,儘量白話方式講解一下。 首先說一下問題。在我們學校數據結構這門功課的時候,時常會有一些比較經典的問題(而且比較複雜問題)作為學習素材,如八皇后,背包問題,染色問題等等。上面列出的幾個問題都可以通過遺傳算法去解決。
  • 遺傳算法(Genetic Algorithm)概述
    屬於啟發式搜索算法一種,這個算法比較有趣,並且弄明白後很簡單,寫個100-200行代碼就可以實現。在某些場合下簡單有效。本文就花一些篇幅,儘量白話方式講解一下。  首先說一下問題。在我們學校數據結構這門功課的時候,時常會有一些比較經典的問題(而且比較複雜問題)作為學習素材,如八皇后,背包問題,染色問題等等。上面列出的幾個問題都可以通過遺傳算法去解決。
  • 蟻群算法求解TSP問題
    它由MarcoDorigo於1992年在他的博士論文中提出,其靈感來源於螞蟻在尋找食物過程中發現路徑的行為。蟻群算法是一種模擬進化算法,初步的研究表明該算法具有許多優良的性質。針對PID控制器參數優化設計問題,將蟻群算法設計的結果與遺傳算法設計的結果進行了比較,數值仿真結果表明,蟻群算法具有一種新的模擬進化優化方法的有效性和應用價值。
  • 遺傳算法原理與代碼解析
    我們都知道進化論的基本規則就是「自然選擇,適者生存」,每個個體通過交配繁衍出後代,後代在成長過程中經過自然法則的篩選而淘汰掉部分個體,而那些擁有優良性狀的個體得以存活並且通過繁衍使得優秀遺傳信息得以保留和擴散。遺傳算法(Genetic Algorithm, GA)正是借鑑了這種思想。
  • 一文讀懂遺傳算法工作原理(附Python實現)
    簡介幾天前,我著手解決一個實際問題——大型超市銷售問題。在使用了幾個簡單模型做了一些特徵工程之後,我在排行榜上名列第 219 名雖然結果不錯,但是我還是想做得更好。於是,我開始研究可以提高分數的優化方法。結果我果然找到了一個,它叫遺傳算法。
  • 論文速遞--上位效應對遺傳算法可靠性的影響
    ,並分析基於相互作用產生的上位效應對遺傳算法可靠性的影響。指出遺傳算法缺陷的根源;2. 基於測試樣本函數定義目標函數,以判斷遺傳算法的適用性。方法:1. 基於非上位效應函數(表1)和上位效應函數(表2),以及非上位效應函數F4和上位效應函數F6的結構圖來驗證遺傳算法可靠性;2. 通過計算樣本函數(公式(1))和遺傳算法流程(圖3)表達遺傳算法的工作原理。3.
  • 用python實現遺傳算法
    最近事情比較多,一個月沒有寫公眾號了,但也積累了些不錯的內容可以分享,今天就給大家介紹的是遺傳算法,並用python加以實現。在遺傳算法的學習過程中,在CSDN上看到一篇已有人分享的python代碼,因此直接借鑑過來,並結合《數學建模與數學實驗》進行補充。
  • Matlab算法系列-遺傳算法
    遺傳算法(Genetic Algorithm,GA)是20世紀70年代初興起的一門新興學科。遺傳算法的基本思想來源於達爾文的進化論和孟德爾的遺傳學說,它通過模擬生物進化的過程來求解問題。生物中的基因對應優化問題中的變量組合,一個解則代表了一個個體。通過生物基因的交叉與變異來改變種群的性狀(函數值)。通過進化過程中優勝劣汰的原則挑選出優秀的個體(函數值大或小),最終通過迭代的方式模擬生物的進化,得到一個適合生存於特定環境的種群,以此來求解出優化問題的全局最優解。      遺傳算法已經發展得很成熟,廣泛應用於優化問題的求解。
  • [算法系列]最優化問題綜述
    4.6、克隆選擇算法 根據克隆選擇原理設計的免疫算法。解決問題時,一般把問題定義為抗原,而問題的解就是抗體集合。在特定的形態空間中,隨機產生的抗體試圖與抗原發生匹配,即嘗試解決問題。匹配度高的抗體有可能產生更好的解,被賦予更大的克隆概率參與下一次匹配。
  • 從細胞生物學到遺傳算法(GA)
    遺傳算法簡介遺傳算法(Genetic Algorithm,GA)起源於1970年代,其基本思想來源於達爾文的進化論和孟德爾的遺傳學說(小學三年級知識警告!),通過模擬生物進化的過程來求解優化問題。1.1 細胞學背景DNA雙螺旋結構一個個基因片段(基因型)組成了生物的染色體,進而決定生物的表現型。
  • 啟發式算法在最優化問題求解中的應用與實踐
    模擬退火算法來源於固體退火的過程,用於求解組合優化類問題;遺傳算法模擬了達爾文生物進化論的自然選擇和遺傳學機理的生物進化過程,用於解決搜索類問題;蟻群算法模擬了螞蟻尋找食物過程中發現路徑的行為,用於解決路徑優化問題,也是一種比較有趣的算法。
  • 什麼是遺傳算法?怎樣繪製遺傳算法流程圖
    遺傳算法是一種通過模擬自然進化過程搜索最優解的操作方法,遺傳算法有三個基本算子選擇、交叉和變異。對於遺傳算法我們也可以使用流程圖對其整個過程進行總結歸納,那要怎樣繪製遺傳算法流程圖呢?下面是分享的簡單操作方法,希望可以幫助大家。
  • 利用遺傳算法優化GANs
    遺傳算法是根據大自然中生物體進化規律而設計提出的,是根據大自然中生物體進化規律而設計提出的。是模擬達爾文生物進化論的自然選擇和遺傳學機理的生物進化過程的計算模型,是一種通過模擬自然進化過程搜索最優解的方法。在本片文章中,我們嘗試使用遺傳算法來對訓練GANs進行優化,我們的訓練模型是生成手寫數字。
  • Pedro Domingos深度解析機器學習五大流派中主算法精髓
    每一個流派都有一種特定的主算法,這種算法可以解決出現的問題。例如,只有象徵主義者能夠解決的問題是學習那些可以用不同形式組構的知識,他們用逆向推理的方法學習這些知識。聯結主義者運用反向傳播算法來解決信用分配問題。進化論者解決學習結構問題。聯結主義者僅從一個固定的結構開始,進而調整權重值。進化論者知道如何運用遺傳程序提出一種學習結構。
  • 遺傳算法:組合優化算法,按照進化論的方式啟發搜索尋優解
    遺傳算法是由美國密西根大學的 Holland教授創立於20世紀六七十年代,受達爾文「進化論」思想的啟發而設計實現。遺傳算法不是通過暴力搜索解的方法,而是通過模擬種群的基因交叉和突變,經過種群一代一代的適者生存的方式尋找問題優解的方法,這在解決組合優化時解空間組合爆炸中應用廣泛。
  • EM算法原理總結
    EM算法也稱期望最大化(Expectation-Maximum,簡稱EM)算法,它是一個基礎算法,是很多機器學習領域算法的基礎,比如隱式馬爾科夫算法(HMM), LDA主題模型的變分推斷等等。本文就對EM算法的原理做一個總結。EM算法要解決的問題我們經常會從樣本觀察數據中,找出樣本的模型參數。