哈密顿回路与旅行商问题的求解
哈密頓圖:圖G的一個回路,若它通過圖的每一個節點一次,且僅一次,就是哈密頓回路.存在哈密頓回路的圖就是哈密頓圖.哈密頓圖就是從一點出發,經過所有的必須且只能一次,最終回到起點的路徑.圖中有的邊可以不經過,但是不會有邊被經過兩次.
哈密頓回路之中的圖并不要求是完全圖,而當這個圖的完全圖也就是每個頂點之間都存在路徑,并且是加權圖的時候,哈密頓回路的問題就演變成了旅行商問題,因此上述兩個問題的求解方法十分相似。
首先來求哈密頓回路問題
1.我們很容易想到用蠻力法,即對于給定的無向圖(V,E) 依次考察圖中所有頂點的全排列,而當滿足相鄰頂點之間存在邊并且最后一個頂點與第一個頂點之間也存在邊時就符合條件。
2.采用dfs,并且適當減枝。 下面我們采用這種方法求解
input:
5
0 1 1 1 0
1 0 1 0 1
0 1 0 1 1
1 0 1 0 1
0 1 1 1 0
?
//哈密頓回路問題 #include<stdio.h> int x[100]; int visit[100]; int arc[6 ][6]; int n; void dfs(int step) {int i,j;if(step==n&&arc[x[step-1]][0]==1) //最后一步到達的頂點與起點之間存在路徑 {printf("路徑:");for(i=0;i<n;i++)printf("%d ",x[i]+1);printf("\n");return ;}else{for(j=0;j<n;j++){if(visit[j]==0&&arc[x[step-1]][j]==1) //j未訪問并且當前頂點與j頂點之間存在路徑 {visit[j]=1;x[step]=j; //下一個訪問的頂點為j dfs(step+1);visit[j]=0;x[step]=0; }}}} int main(void) {int i,j;scanf("%d",&n);for(i=0;i<n;i++)for(j=0;j<n;j++)scanf("%d",&arc[i][j]);visit[0]=1; //起點置為已經訪問x[0]=0;dfs(1);return 0;}?
旅行商問題的求解?:有若干個城市,任何兩個城市之間的距離都是確定的,現要求一旅行商從某城市出發必須經過每一個城市且只在一個城市逗留一次,最后回到出發的城市,問如何事先確定一條最短的線路已保證其旅行的費用最少?
旅行商問題與哈密頓回路問題十分相似,都是經過每一個頂點一次最后回到出發的城市,不同的是旅行商問題對應的是完全圖,即每個頂點之間都存在路徑,并且路徑長度已知。
?
input:
4
0 2 5 7
2 0 8 3
5 8 0 1
7 3 1 0
output:
11
//旅行商問題,對應完全圖 //哈密頓回路問題 對應非完全圖 #include<stdio.h> int x[100]; int visit[100]; int arc[6][6]; int n,count,bestCount=9999999; void dfs(int step,int count) {int i,j; if(bestCount<count) //減枝,當然所經過的路徑長度大于最小長度 return;if(step==n) //已經走過n個頂點 {count+=arc[x[step-1]][0];bestCount=count; return ;}else{for(j=0;j<n;j++){if(visit[j]==0) //j未訪問{visit[j]=1;//置為已經訪問 x[step]=j; //訪問該頂點 dfs(step+1,count+arc[x[step-1]][j]); visit[j]=0;x[step]=0; }}}} int main(void) {int i,j;scanf("%d",&n);for(i=0;i<n;i++)for(j=0;j<n;j++)scanf("%d",&arc[i][j]);visit[0]=1;x[0]=0;dfs(1,0);printf("%d ",bestCount); return 0;}?
總結
以上是生活随笔為你收集整理的哈密顿回路与旅行商问题的求解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Paradigm 介绍 Goldfish
- 下一篇: 防窜货PDA扫描程序 APP 出入库扫描