❶ 基於DEAP庫的python進化演算法從入門到入土--(六)多目標遺傳演算法 NSGA-II
在很多實際工程問題中,我們的優化目標不止一個,而是對多個目標函數求一個綜合最優解。例如在物流配送問題中,不僅要求配送路徑最短,還可能需要參與運輸車輛最少等。
多目標優化問題的數學模型可以表達為:
多目標優化問題通常具有如下特點:
對於多目標優化問題,傳統方法是將原問題通過加權方式變換為單目標優化問題,進而求得最優解。該方法具有兩大問題:
遺傳演算法具有多點多方向搜索的特徵,在一次搜索中可以得到多個Pareto最優解,因此更適合求解多目標優化問題。
而當前用於求解多目標優化問題的遺傳演算法一般有兩種思路:
NSGA-II(nondominated sorting genetic algorithm II)是2002年Deb教授提出的NSGA的改進型,這個演算法主要解決了第一版NSGA的三個痛點:
針對這三個問題,在NSGA-II中,Deb提出了快速非支配排序運算元,引入了保存精英策略,並用「擁擠距離」(crowding distance)替代了共享(sharing)。
在介紹NSGA-II的整體流程之前,我們需要先了解快速非支配排序和擁擠距離的定義。
解的支配關系與Pareto最優解
下圖表示了解之間的支配和強支配關系:
下圖表示了一個最小化問題解集中的Pareto最優解和Pareto弱最優解:
快速非支配排序步驟
快速非支配排序就是將解集分解為不同次序的Pareto前沿的過程。
它可以描述為:
DEAP實現
DEAP內置了實現快速非支配排序操作的函數 tools.emo.sortNondominated
tools.emo.sortNondominated(indivials, k, first_front_only=False)
參數:
返回:
擁擠距離的定義
在NSGA II中,為了衡量在同一個前沿中各個解質量的優劣,作者為每個解分配了一個擁擠距離。其背後的思想是 讓求得的Pareto最優解在objective space中盡量分散 。也就有更大可能讓解在Pareto最優前沿上均勻分布。
DEAP實現
DEAP中內置了計算擁擠距離的函數 tools.emo.assignCrowdingDist
tools.emo.assignCrowdingDist(indivials)
參數:
返回:
比較操作
根據快速非支配排序和擁擠距離計算的結果,對族群中的個體進行排序:
對兩個解 ,
在每個迭代步的最後,將父代與子代合為一個族群,依照比較操作對合並後族群中的個體進行排序,然後從中選取數量等同於父代規模的優秀子代,這就是NSGA-II演算法中的精英保存策略。
DEAP實現
DEAP內置了實現NSGA-II中的基於擁擠度的選擇函數 tools.selNSGA2 用來實現精英保存策略:
tools.selNSGA2(indivials, k, nd='standard')
參數:
返回:
這里選用ZDT3函數作為測試函數,函數可表達為:
其Pareto最優解集為
這里為了方便可視化取 。
下圖給出了該函數在Decision Space和Objective Space中的對應:
其pareto最優解在Objective Space中如下圖紅點所示:
將結果可視化:
得到:
可以看到NSGA-II演算法得到的Pareto最優前沿質量很高:最優解均勻分布在不連續前沿的各個線段上;同時在最優前沿以外沒有個體存在。
❷ 利用遺傳演算法求解TSP問題 從北京出發 四個城市
作為一種模擬生物自然遺傳與進化過程的優化方法,遺傳演算法(GA)因其具有隱並行性、不需目標函數可微等特點,常被用於解決一些傳統優化方法難以解決的問題。旅行商問題(TSP)是典型的NP難題組合優化問題之一,且被廣泛應用於許多領域,所以研究遺傳演算法求解TSP具有重要的理論意義和應用價值。具有量子計算諸多特點的量子遺傳演算法(OGA)作為—新的概率進化演算法,在解決實際問題時,其高度並行性能極大地提高計算效率,因而研究OGA求解TSP同樣有重要的價值;而將具有遍歷性和隨機性的「混沌」概念引入量子遺傳演算法求解較復雜的組合優化問題又為求解優化問題開拓了一個新的思路。
❸ 遺傳演算法解決旅行商問題(TSP)一:初始化和適應值
旅行商問題(Travelling salesman problem, TSP)是這樣一個問題:給定一系列城市和每對城市之間的距離,求解訪問每一座城市一次並回到起始城市的最短迴路。
設有n個城市,城市i和城市j之間的距離是 。設
那麼TSP問題使下面的目標最小:
首先,設置一下參數:
這里假設有10個城市,其坐標定義於pos變數,第一行是各個城市的x坐標,第二行是各個城市的y坐標,比如第一個城市的坐標為(1,1),第三個城市的坐標為(2,2)。之後計算處各個城市之間的距離。
種群中每個個體,都表示著一個訪問城市的路徑,這意味著每個個體都要覆蓋所有城市,但是只能經過一個城市一次。
根據種群中每個個體中城市的順序,可以求出這個個體所代表的距離,距離越大,適應度越小,因此用距離的倒數作為個體的適應度值。
❹ Python實現基於遺傳演算法的排課優化
排課問題的本質是將課程、教師和學生在合適的時間段內分配到合適的教室中,涉及到的因素較多,是一個多目標的調度問題,在運籌學中被稱為時間表問題(Timetable Problem,TTP)。設一個星期有n個時段可排課,有m位教師需要參與排課,平均每位教師一個星期上k節課,在不考慮其他限制的情況下,能夠推出的可能組合就有 種,如此高的復雜度是目前計算機所無法承受的。因此眾多研究者提出了多種其他排課演算法,如模擬退火,列表尋優搜索和約束滿意等。
Github : https://github.com/xiaochus/GeneticClassSchele
遺傳演算法(Genetic Algorithm)是模擬達爾文生物進化論的自然選擇和遺傳學機理的生物進化過程的計算模型,是一種通過模擬自然進化過程搜索最優解的方法。遺傳演算法的流程如下所示:
遺傳演算法首先針對待解決問題隨機生成一組解,我們稱之為種群(Population)。種群中的每個個體都是問題的解,在優化的過程中,演算法會計算整個種群的成本函數,從而得到一個與種群相關的適應度的序列。如下圖所示:
為了得到新的下一代種群,首先根據適應度對種群進行排序,從中挑選出最優的幾個個體加入下一代種群,這一個過程也被稱為精英選拔。新種群餘下的部分通過對選拔出來的精英個體進行修改得到。
對種群進行修改的方法參考了生物DAN進化的方法,一般使用兩種方法: 變異 和 交叉 。 變異 的做法是對種群做一個微小的、隨機的改變。如果解的編碼方式是二進制,那麼就隨機選取一個位置進行0和1的互相突變;如果解的編碼方式是十進制,那麼就隨機選取一個位置進行隨機加減。 交叉 的做法是隨機從最優種群中選取兩個個體,以某個位置為交叉點合成一個新的個體。
經過突變和交叉後我們得到新的種群(大小與上一代種群一致),對新種群重復重復上述過程,直到達到迭代次數(失敗)或者解的適應性達到我們的要求(成功),GA演算法就結束了。
演算法實現
首先定義一個課程類,這個類包含了課程、班級、教師、教室、星期、時間幾個屬性,其中前三個是我們自定義的,後面三個是需要演算法來優化的。
接下來定義cost函數,這個函數用來計算課表種群的沖突。當被測試課表沖突為0的時候,這個課表就是個符合規定的課表。沖突檢測遵循下面幾條規則:
使用遺傳演算法進行優化的過程如下,與上一節的流程圖過程相同。
init_population :隨機初始化不同的種群。
mutate :變異操作,隨機對 Schele 對象中的某個可改變屬性在允許范圍內進行隨機加減。
crossover :交叉操作,隨機對兩個對象交換不同位置的屬性。
evolution :啟動GA演算法進行優化。
實驗結果
下面定義了3個班,6種課程、教師和3個教室來對排課效果進行測試。
優化結果如下,迭代到第68次時,課程安排不存在任何沖突。
選擇1203班的課表進行可視化,如下所示,演算法合理的安排了對應的課程。
❺ unityilruntime支持webgl嗎
索"ILRuntime"
1.1存在:
直接 「install」
1.2不存在
首先需要在項目的Packages/manifest.json中,添加ILRuntime的源信息,在這個文件的dependencies節點前增加以下代碼
如圖:
在這里插入圖片描述
然後通過Unity的Window->Package Manager菜單,打開Package Manager,將上部標簽頁選項選擇為殲啟All Packages,Advanced里勾上Show Preview Packages,等待Unity載入完包信息,應該就能在左側列表中找到ILRuntime,點擊安裝即可
1.3還是無法安裝:
部分Unity版本可以無法直接在列表中刷出ILRuntime,如果左邊列表找不著,那就在項目的manifest.json中的dependencies段的開頭,增加如下代碼手動將ILRuntime添加進項目
「com.ourpalm.ilruntime」氏纖如: 「1.6.0」,
如圖:
在這里插入圖片描述
1.4可以導入Demo
ILRuntime包安裝完畢後,在Package Manager中選中ILRuntime, 右邊詳細頁面中有Samples,點擊右方的Import to project可以將ILRuntime的示例Demo直接導入當前工程。
1.5導入Demo報錯
示例導入工程後有可能因為沒開啟unsafe導致編譯報錯,可以在PlayerSettings中勾選Allow unsafe code解決編譯問題。
1.6打開熱更DLL工程
在Assets\Samples\ILRuntime\1.6\Demo\HotFix_Project~目錄中打開熱更DLL的vs工程,直接編譯,然後就可以正常運行ILRuntime的豎豎Demo示例了
1.7 最終解決方案
如果在進行以上配置後依然無法找到ILRuntime,可以按照下面Unity3D的示例工程的步驟手動安裝ILRuntime
1.8 安裝成功
在這里插入圖片描述
打開CSDN APP,看更多技術內容
Unity安裝 ILRuntime插件_zhanqq2012的博客
"com.unity.moles.imageconversion":"1.0.0", "com.unity.moles.imgui":"1.0.0", "com.unity.moles.jsonserialize":"1.0.0", "com.unity.moles.particlesystem":"1.0.0", "com.unity.moles.physics":"1.0.0", "...
繼續訪問
Unity接入ILRuntime問題記錄_Dream_TP的博客_unity...
{ [MenuItem("ILRuntime/生成跨域繼承適配器")] staticvoid GenerateCrossbindAdapter() { //由於跨域繼承特殊性太多,自動生成無法實現完全無副作用生成,所以這里提供的代碼自動生成主要是給大家生成個初...
繼續訪問
Centos下的yum安裝包.zip
Centos下的yum安裝包
Python實現用遺傳演算法解決旅行家問題源碼,Python解決TSP問題源碼
Python實現用遺傳演算法解決旅行家問題源碼 旅行商問題,即 TSP 問題(Traveling Salesman Problem)是數學領域中著名問題之一。 假設有一個旅行商人要拜訪 n 個城市,他必須選擇所要走的路徑,路經的限制是每個城市只 能拜訪一次,而且最後要回到原來出發的城市。路徑的選擇目標是要求得的路徑路程為所有 路徑之中的最小值。TSP 問題是一個組合優化問題。該問題可以被證明具有 NPC 計算復雜 性。因此,任何能使該問題的求解得以簡化的方法,都將受到高度的評價和關注
最新發布 node2node2node2
我喜歡你PPT模板.pptx
我喜歡你PPT模板.pptx
物流快遞PPT模板.pptx
物流快遞PPT模板.pptx
41-數碼管循環右移(51單片機C語言實例Proteus模擬和代碼).rar
免責聲明:資料部分來源於合法的互聯網渠道收集和整理,部分自己學習積累成果,供大家學習參考與交流。收取的費用僅用於收集和整理資料耗費時間的酬勞。 本人尊重原創作者或出版方,資料版權歸原作者或出版方所有,本人不對所涉及的版權問題或內容負法律責任。如有侵權,請舉報或通知本人刪除。
SolidEdgeToGLTF工具軟體
一套將Solidworks模型導出為gltf格式的數據轉換工具,glTF僅包含裝配結構和幾何信息,不包含屬性、參數、注釋等信息。湃睿科技掌握模型輕量化與簡化的核心技術,能幫助您實現設計數據在產品全生命周期各個環節中的應用,滿足工藝、製造、銷售、培訓、交付、運維等應用場是對設計數據的轉換需求。
10-LED循環左移(51單片機C語言實例Proteus模擬和代碼).rar
免責聲明:資料部分來源於合法的互聯網渠道收集和整理,部分自己學習積累成果,供大家學習參考與交流。收取的費用僅用於收集和整理資料耗費時間的酬勞。 本人尊重原創作者或出版方,資料版權歸原作者或出版方所有,本人不對所涉及的版權問題或內容負法律責任。如有侵權,請舉報或通知本人刪除。
126-溫度可調上下限1602顯示(51單片機C語言實例Proteus模擬和代碼).rar
免責聲明:資料部分來源於合法的互聯網渠道收集和整理,部分自己學習積累成果,供大家學習參考與交流。收取的費用僅用於收集和整理資料耗費時間的酬勞。 本人尊重原創作者或出版方,資料版權歸原作者或出版方所有,本人不對所涉及的版權問題或內容負法律責任。如有侵權,請舉報或通知本人刪除。
mapgis和shp數據的相互轉換方法與技巧等等,一系列問的的解決方法.zip
mapgis和shp數據的相互轉換方法與技巧等等,一系列問的的解決方法
07、常用分類器及應用場景:貝葉斯,隨機森林,SGD,SVM
29.第二十九套:機器學習平台mahout,推薦系統演算法與架構剖析視頻教程
Python 079.lambda表達式和匿名函數.mp4
Python 079.lambda表達式和匿名函數.mp4
047.Python字典_復雜表格數據存儲_列表和字典綜合嵌套.mp4
047.Python字典_復雜表格數據存儲_列表和字典綜合嵌套.mp4
房產短視頻60天搭建起號課程-視頻教程網盤鏈接提取碼下載 .txt
課程來自泉哥的短視頻賬號60天起號課程,價值2980元。學完收獲:能夠進行個人房產只是賬號搭建、已有賬號博主針對性改善做號方法、幫助做號期間避免有流量沒方法的情況、房產經紀人使用賬號進行線上穩定增長。5大體系,9大流程。流量只是手段,不是目的。個人IP將是你事業中最大的無形資產與有形資源。 視頻大小:4.4G
296-用P0 、P1口顯示整型函數返回值(51單片機C語言實例Proteus模擬和代碼).rar
免責聲明:資料部分來源於合法的互聯網渠道收集和整理,部分自己學習積累成果,供大家學習參考與交流。收取的費用僅用於收集和整理資料耗費時間的酬勞。 本人尊重原創作者或出版方,資料版權歸原作者或出版方所有,本人不對所涉及的版權問題或內容負法律責任。如有侵權,請舉報或通知本人刪除。
CLShanYanSDKDataList.sqlite
CLShanYanSDKDataList.sqlite
Fundamentals of Power Electronics第二版
Fundamentals of Power Electronics第二版原著,正版書籍電子版,第二版和第三版不存在內容的差別,只是順序不同
190-步進電機(51單片機C語言實例Proteus模擬和代碼).rar
免責聲明:資料部分來源於合法的互聯網渠道收集和整理,部分自己學習積累成果,供大家學習參考與交流。收取的費用僅用於收集和整理資料耗費時間的酬勞。 本人尊重原創作者或出版方,資料版權歸原作者或出版方所有,本人不對所涉及的版權問題或內容負法律責任。如有侵權,請舉報或通知本人刪除。
武漢大學開題報告畢業答辯通用PPT模板.pptx
武漢大學開題報告畢業答辯通用PPT模板.pptx
directshow旋轉90度演算法.zip
directshow旋轉90度演算法
unity 找不到ilruntime
❻ python 遺傳演算法問題
遺傳演算法(GA)是最早由美國Holland教授提出的一種基於自然界的「適者生存,優勝劣汰」基本法則的智能搜索演算法。
遺傳演算法也是借鑒該基本法則,通過基於種群的思想,將問題的解通過編碼的方式轉化為種群中的個體,並讓這些個體不斷地通過選擇、交叉和變異運算元模擬生物的進化過程,然後利用「優勝劣汰」法則選擇種群中適應性較強的個體構成子種群,然後讓子種群重復類似的進化過程,直到找到問題的最優解或者到達一定的進化(運算)時間。
❼ tSp Concorder演算法原理
tsp問題遺傳演算法將多目標按照線性加權的方式轉化為單目標,然後應用傳統遺傳演算法求解
其中w_i表示第i個目標的權重,f_k表示歸一化之後的第i個目標值。我們很容易知道,這類方法的關鍵是怎麼設計權重。比如,Random Weight Genetic Algorithm (RWGA) 採用隨機權重的方式,每次計算適應度都對所有個體隨機地產生不同目標的權重,然後進行選擇操作。Vector-Evaluated Genetic Algorithm (VEGA) 也是基於線性加權的多目標遺傳演算法。如果有K個目標,VEGA 會隨機地將種群分為K個同等大小子種群,在不同的子種群按照不同的目標函數設定目標值,然後再進行選擇操作。VEGA 實質上是基於線性加權的多目標遺傳演算法。VEGA 是第一個多目標遺傳演算法,開啟了十幾年的研究潮流。
1.TSP問題是指假設有一個旅行商人要拜訪n個城市,他必須選擇所要走的路徑,路徑的限制是每個城市只能拜訪一次,而且最後要回到原來出發的城市。路徑的選擇目標是要求得的路徑路程為所有路徑之中的最小值。本文使用遺傳演算法解決att30問題,即30個城市的旅行商問題。旅行商問題是一個經典的組合優化問題。一個經典的旅行商問題可以描述為:一個商品推銷員要去若干個城市推銷商品,該推銷員從一個城市出發,需要經過所有城市後,回到出發地。應如何選擇行進路線,以使總的行程最短。從圖論的角度來看,該問題實質是在一個帶權完全無向圖中,找一個權值最小的Hamilton迴路。由於該問題的可行解是所有頂點的全排列,隨著頂點數的增加,會產生組合爆炸,它是一個NP完全問題。TSP問題可以分為對稱和不對稱。在對稱TSP問題中,兩座城市之間來回的距離是相等的,形成一個無向圖,而不對稱TSP則形成有向圖。對稱性TSP問題可以將解的數量減少了一半。所以本次實驗的TSP問題使用att48數據,可在tsplib中下載數據包。演化演算法是一類模擬自然界遺傳進化規律的仿生學演算法,它不是一個具體的演算法,而是一個演算法簇。遺傳演算法是演化演算法的一個分支,由於遺傳演算法的整體搜索策略和優化計算是不依賴梯度信息,所以它的應用比較廣泛。我們本次實驗同樣用到了遺傳演算法(用MATLAB編寫)來解決TSP問題。
❽ 使用流行的遺傳演算法python庫是哪個
建議使用由華南農業大學、暨南大學、華南理工大學高校碩博學生聯合團隊推出的Python高性能遺傳和進化演算法工具箱:Geatpy。它是目前進化計算領域與platemo、matlab遺傳演算法工具箱等有相當的權威和影響力的高性能實用型進化演算法工具箱,而其效率和易用性居於領先地位。
目前已得到多所高校研究生實驗室以及企業採用,為相關領域的研究和應用注入了全新的活力。
它支持GA、DE、ES等進化演算法,支持單目標、多目標進化優化、復雜約束優化等問題的求解,提供豐富的遺傳演算法和多目標進化優化演算法模板,採用高性能的C內核和mkl矩陣運算,提供功能強大的開源進化演算法框架,尤其適合數學建模和研究進化演算法的研究生們。
官網:Geatpy
多目標優化求解案例:
使用方法:
第一步:實例化一個問題類把待優化的問題寫在裡面。
第二步:編寫執行腳本調用遺傳或其他進化演算法模板,完成問題的求解。
官網教程:Geatpy教程
❾ 遺傳演算法tsp問題求解~80高分求解還會繼續加分
遺傳演算法GA
遺傳演算法:
旅行商問題(traveling saleman problem,簡稱tsp):
已知n個城市之間的相互距離,現有一個推銷員必須遍訪這n個城市,並且每個城市只能訪問一次,最後又必須返回出發城市。如何安排他對這些城市的訪問次序,可使其旅行路線的總長度最短?
用圖論的術語來說,假設有一個圖 g=(v,e),其中v是頂點集,e是邊集,設d=(dij)是由頂點i和頂點j之間的距離所組成的距離矩陣,旅行商問題就是求出一條通過所有頂點且每個頂點只通過一次的具有最短距離的迴路。
這個問題可分為對稱旅行商問題(dij=dji,,任意i,j=1,2,3,…,n)和非對稱旅行商問題(dij≠dji,,任意i,j=1,2,3,…,n)。
若對於城市v={v1,v2,v3,…,vn}的一個訪問順序為t=(t1,t2,t3,…,ti,…,tn),其中ti∈v(i=1,2,3,…,n),且記tn+1= t1,則旅行商問題的數學模型為:
min l=σd(t(i),t(i+1)) (i=1,…,n)
旅行商問題是一個典型的組合優化問題,並且是一個np難問題,其可能的路徑數目與城市數目n是成指數型增長的,所以一般很難精確地求出其最優解,本文採用遺傳演算法求其近似解。
遺傳演算法:
初始化過程:用v1,v2,v3,…,vn代表所選n個城市。定義整數pop-size作為染色體的個數,並且隨機產生pop-size個初始染色體,每個染色體為1到18的整數組成的隨機序列。
適應度f的計算:對種群中的每個染色體vi,計算其適應度,f=σd(t(i),t(i+1)).
評價函數eval(vi):用來對種群中的每個染色體vi設定一個概率,以使該染色體被選中的可能性與其種群中其它染色體的適應性成比例,既通過輪盤賭,適應性強的染色體被選擇產生後台的機會要大,設alpha∈(0,1),本文定義基於序的評價函數為eval(vi)=alpha*(1-alpha).^(i-1) 。[隨機規劃與模糊規劃]
選擇過程:選擇過程是以旋轉賭輪pop-size次為基礎,每次旋轉都為新的種群選擇一個染色體。賭輪是按每個染色體的適應度進行選擇染色體的。
step1 、對每個染色體vi,計算累計概率qi,q0=0;qi=σeval(vj) j=1,…,i;i=1,…pop-size.
step2、從區間(0,pop-size)中產生一個隨機數r;
step3、若qi-1<r<qi,則選擇第i個染色體 ;
step4、重復step2和step3共pop-size次,這樣可以得到pop-size個復制的染色體。
grefenstette編碼:由於常規的交叉運算和變異運算會使種群中產生一些無實際意義的染色體,本文採用grefenstette編碼《遺傳演算法原理及應用》可以避免這種情況的出現。所謂的grefenstette編碼就是用所選隊員在未選(不含淘汰)隊員中的位置,如:
8 15 2 16 10 7 4 3 11 14 6 12 9 5 18 13 17 1
對應:
8 14 2 13 8 6 3 2 5 7 3 4 3 2 4 2 2 1。
交叉過程:本文採用常規單點交叉。為確定交叉操作的父代,從 到pop-size重復以下過程:從[0,1]中產生一個隨機數r,如果r<pc ,則選擇vi作為一個父代。
將所選的父代兩兩組隊,隨機產生一個位置進行交叉,如:
8 14 2 13 8 6 3 2 5 7 3 4 3 2 4 2 2 1
6 12 3 5 6 8 5 6 3 1 8 5 6 3 3 2 1 1
交叉後為:
8 14 2 13 8 6 3 2 5 1 8 5 6 3 3 2 1 1
6 12 3 5 6 8 5 6 3 7 3 4 3 2 4 2 2 1
變異過程:本文採用均勻多點變異。類似交叉操作中選擇父代的過程,在r<pm 的標准下選擇多個染色體vi作為父代。對每一個選擇的父代,隨機選擇多個位置,使其在每位置按均勻變異(該變異點xk的取值范圍為[ukmin,ukmax],產生一個[0,1]中隨機數r,該點變異為x'k=ukmin+r(ukmax-ukmin))操作。如:
8 14 2 13 8 6 3 2 5 7 3 4 3 2 4 2 2 1
變異後:
8 14 2 13 10 6 3 2 2 7 3 4 5 2 4 1 2 1
反grefenstette編碼:交叉和變異都是在grefenstette編碼之後進行的,為了循環操作和返回最終結果,必須逆grefenstette編碼過程,將編碼恢復到自然編碼。
循環操作:判斷是否滿足設定的帶數xzome,否,則跳入適應度f的計算;是,結束遺傳操作,跳出。
//c++的程序
#include<iostream.h>
#include<stdlib.h>
template<class T>
class Graph
{
public:
Graph(int vertices=10)
{
n=vertices;
e=0;
}
~Graph(){}
virtual bool Add(int u,int v,const T& w)=0;
virtual bool Delete(int u,int v)=0;
virtual bool Exist(int u,int v)const=0;
int Vertices()const{return n;}
int Edges()const{return e;}
protected:
int n;
int e;
};
template<class T>
class MGraph:public Graph<T>
{
public:
MGraph(int Vertices=10,T noEdge=0);
~MGraph();
bool Add(int u,int v,const T& w);
bool Delete(int u,int v);
bool Exist(int u,int v)const;
void Floyd(T**& d,int**& path);
void print(int Vertices);
private:
T NoEdge;
T** a;
};
template<class T>
MGraph<T>::MGraph(int Vertices,T noEdge)
{
n=Vertices;
NoEdge=noEdge;
a=new T* [n];
for(int i=0;i<n;i++){
a[i]=new T[n];
a[i][i]=0;
for(int j=0;j<n;j++)if(i!=j)a[i][j]=NoEdge;
}
}
template<class T>
MGraph<T>::~MGraph()
{
for(int i=0;i<n;i++)delete[]a[i];
delete[]a;
}
template<class T>
bool MGraph<T>::Exist(int u,int v)const
{
if(u<0||v<0||u>n-1||v>n-1||u==v||a[u][v]==NoEdge)return false;
return true;
}
template<class T>
bool MGraph<T>::Add(int u,int v,const T& w)
{
if(u<0||v<0||u>n-1||v>n-1||u==v||a[u][v]!=NoEdge){
cerr<<"BadInput!"<<endl;
return false;
}
a[u][v]=w;
e++;
return true;
}
template<class T>
bool MGraph<T>:delete(int u,int v)
{
if(u<0||v<0||u>n-1||v>n-1||u==v||a[u][v]==NoEdge){
cerr<<"BadInput!"<<endl;
return false;
}
a[u][v]=NoEdge;
e--;
return true;
}
template<class T>
void MGraph<T>::Floyd(T**& d,int**& path)
{
d=new T* [n];
path=new int* [n];
for(int i=0;i<n;i++){
d[i]=new T[n];
path[i]=new int[n];
for(int j=0;j<n;j++){
d[i][j]=a[i][j];
if(i!=j&&a[i][j]<NoEdge)path[i][j]=i;
else path[i][j]=-1;
}
}
for(int k=0;k<n;k++){
for(i=0;i<n;i++)
for(int j=0;j<n;j++)
if(d[i][k]+d[k][j]<d[i][j]){
d[i][j]=d[i][k]+d[k][j];
path[i][j]=path[k][j];
}
}
}
template<class T>
void MGraph<T>::print(int Vertices)
{
for(int i=0;i<Vertices;i++)
for(int j=0;j<Vertices;j++)
{
cout<<a[i][j]<<' ';if(j==Vertices-1)cout<<endl;
}
}
#define noEdge 10000
#include<iostream.h>
void main()
{
cout<<"請輸入該圖的節點數:"<<endl;
int vertices;
cin>>vertices;
MGraph<float> b(vertices,noEdge);
cout<<"請輸入u,v,w:"<<endl;
int u,v;
float w;
cin>>u>>v>>w;
while(w!=noEdge){
//u=u-1;
b.Add(u-1,v-1,w);
b.Add(v-1,u-1,w);
cout<<"請輸入u,v,w:"<<endl;
cin>>u>>v>>w;
}
b.print(vertices);
int** Path;
int**& path=Path;
float** D;
float**& d=D;
b.Floyd(d,path);
for(int i=0;i<vertices;i++){
for(int j=0;j<vertices;j++){
cout<<Path[i][j]<<' ';
if(j==vertices-1)cout<<endl;
}
}
int *V;
V=new int[vertices+1];
cout<<"請輸入任意一個初始H-圈:"<<endl;
for(int n=0;n<=vertices;n++){
cin>>V[n];
}
for(n=0;n<55;n++){
for(i=0;i<n-1;i++){
for(int j=0;j<n-1;j++)
{
if(i+1>0&&j>i+1&&j<n-1){
if(D[V[i]][V[j]]+D[V[i+1]][V[j+1]]<D[V[i]][V[i+1]]+D[V[j]][V[j+1]]){
int l;
l=V[i+1];V[i+1]=V[j];V[j]=l;
}
}
}
}
}
float total=0;
cout<<"最小迴路:"<<endl;
for(i=0;i<=vertices;i++){
cout<<V[i]+1<<' ';
}
cout<<endl;
for(i=0;i<vertices;i++)
total+=D[V[i]][V[i+1]];
cout<<"最短路徑長度:"<<endl;
cout<<total;
}
這個你 看得懂么?
❿ 最短路徑
// dijsktra.cpp : 定橡跡義控制台應用程序的入口點。
//
#include "stdafx.h"
#define N 12
#include <iostream>
using namespace std;
const static int soure[N][N] =
{
/*
這填鄰接矩陣
*/
};
int min(int arr[N],bool bj[])
{
int tmp = 999;
int temp = 0;
for(int i=0; i<N; i++)
{
if((arr[i]<tmp)&&(bj[i]==true))
{
tmp = arr[i];
temp = i;
}
}
return temp;
}
class dijsktra
{
private:
int dist[N][N];
int path[N][N];
int final[N][N];
bool flag[N];
public:
void Doing()
{
for(int i=0; i<N; i++)
{
int temp = 0;
for(int j=0; j<N; j++)
{
flag[j] = true;
}
for(int j=0; j<N; j++)
{
dist[i][j] = soure[i][j];
path[i][j] = i;
}
flag[i] = false;
temp = min(dist[i],flag);
flag[temp] = false;
for(int j=1; j<N; j++)
{
for(int k=0; k<N; k++)
{
if((flag[k] == true)&&((soure[temp][k]+dist[i][temp])<dist[i][k]))
{
dist[i][k] = soure[temp][k]+dist[i][temp];
path[i][k] = temp;
}
}
temp = min(dist[i],flag);
flag[temp] = false;
}
}
}
void print()
{
for(int i=0; i<N; i++)
{
for(int j=0; j<N; j++)
{
cout<<dist[i][j]<<","<<譽如升path[i][j]<<" ";
}
cout<<endl;
}
}
void l_print()
{
int i,j;
cout<<"請輸入i,j的慶老值:";
cin>>i>>j;
cout<<"最短路徑長度為:"<<dist[i][j]<<endl;
cout<<"路徑為";
int temp = j;
while(path[i][temp]!=i)
{
cout<<temp<<"<-";
temp = path[i][temp];
}
cout<<temp<<"<-";
cout<<i<<endl;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
dijsktra test;
test.Doing();
test.print();
test.l_print();
system("pause");
return 0;
}