生活随笔
收集整理的這篇文章主要介紹了
汉密尔顿回路问题
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
概述
這是自己這學期算法課的實驗作業。下面給出漢密爾頓圖的定義。定義如下:對于連通圖G=(V,E),V1,V2,…,Vn是G 的一條通路,且圖中任意兩個頂點都可達,若 中每個頂點在該通路中出現且僅出現一次,則稱該通路為漢密爾頓通路。若 V1=Vn,則稱該通路為漢密爾頓回路。
算法描述
1)初始化最佳路徑數組best_path,同時初始化臨時路徑數組path與訪問數組isvisited,設置最小長度min,設置長度變量length = 0
2)開始對每個頂點進行遍歷尋找最佳路徑,首先堆訪問數組中對應頂點進行置1,并把當前頂點追加到path,同時利用cur_vertex這個臨時變量保存當前結點,并開始進行循環。
3)找到出cur_vertex之外與之相鄰且并未訪問的一個頂點k,利用tmp保存這兩點之間的權重,之后檢查是否存在比tmp更小且與cur_vertex相鄰的頂點,如有則更新tmp與訪問的頂點k,之后更新length += tmp,以及更新cur_vertex = k,如果length大于min,則說明改路徑無效,跳出循環。
4)重復步驟3遍歷每一個結點。循環結束后,對length更新,加上最后一個結點到cur_vertex結點的距離。這是如果min大于legnth,則對min更新,并把path數組復制到best_path中去。
5)重復步驟2)直至遍歷完每個結點。返回最小長度。
int Hanmilton(){
int path[
1000] = {
0};
int cur_vertex =
0;
int length =
0;
int min =
10000;
for(
int i =
1 ; i <
this->Nv+
1 ; i++){length =
0;
memset(
this->isvisited,
0,
sizeof(
this->isvisited[
0])*(
this->Nv+
1));
this->isvisited[i] =
1; path[
1] = i; cur_vertex = i;
for(
int j =
2 ; j <
this->Nv+
1 ; j++){
int k =
0;
for(k =
2 ; k <
this->Nv+
1 ; k++){
if(
this->isvisited[k] ==
0){
break;}}
int tmp =
this->data[cur_vertex][k];
for(
int m = k+
1 ; m <
this->Nv+
1 ; m++){
if((!
this->isvisited[m]) && (tmp >
this->data[cur_vertex][m])){tmp =
this->data[cur_vertex][m];k = m;}}path[j] = k;
this->isvisited[k] =
1; cur_vertex = k; length += tmp;
if(length > min){
break;}}length +=
this->data[cur_vertex][i];
if(min > length){ min = length;
for(
int m =
0 ; m <
this->Nv+
1 ; m++){
this->best_path[m] = path[m]; }}}
return min;
}
例子
下面的例子是基于如下圖結構:
全部代碼如下:
#include <iostream>
#include <cstring>
#include <vector>
#include <cstdio>
using namespace std;
class Graph{
private:
int** data;
int* isvisited;
int Nv;
int Ne;
vector<int> best_path;
public:Graph(
int nv,
int ne){
this->Nv = nv;
this->Ne = ne;
this->data =
new int*[nv+
1];best_path.reserve(nv+
1);
for(
int i =
0 ; i < nv+
1 ; i++){best_path[i] =
0;}
this->isvisited =
new int[nv+
1];
memset(
this->isvisited,
0,
sizeof(
this->isvisited[
0])*(nv+
1));
for(
int i =
0 ; i < nv+
1 ; i++){data[i] =
new int[nv+
1];
memset(data[i],
0,
sizeof(data[i][
0])*(nv+
1));}
cout<<
"請輸入邊與邊長:"<<endl;
for(
int i =
0 ; i < ne ; i++){
int v1,v2,weight;
cin>>v1>>v2>>weight;
this->data[v1][v2] =
this->data[v2][v1] = weight;} }
int Hanmilton(){
int path[
1000] = {
0};
int cur_vertex =
0;
int length =
0;
int min =
10000;
for(
int i =
1 ; i <
this->Nv+
1 ; i++){length =
0;
memset(
this->isvisited,
0,
sizeof(
this->isvisited[
0])*(
this->Nv+
1));
this->isvisited[i] =
1; path[
1] = i; cur_vertex = i;
for(
int j =
2 ; j <
this->Nv+
1 ; j++){
int k =
0;
for(k =
2 ; k <
this->Nv+
1 ; k++){
if(
this->isvisited[k] ==
0){
break;}}
int tmp =
this->data[cur_vertex][k];
for(
int m = k+
1 ; m <
this->Nv+
1 ; m++){
if((!
this->isvisited[m]) && (tmp >
this->data[cur_vertex][m])){tmp =
this->data[cur_vertex][m];k = m;}}path[j] = k;
this->isvisited[k] =
1; cur_vertex = k; length += tmp;
if(length > min){
break;}}length +=
this->data[cur_vertex][i];
if(min > length){ min = length;
for(
int m =
0 ; m <
this->Nv+
1 ; m++){
this->best_path[m] = path[m]; }}}
return min;}
void Print_Best_Path(){
cout<<
this->best_path[
1];
for(
int i =
2 ; i <
this->Nv+
1 ; i++){
cout<<
" -> "<<
this->best_path[i];}
cout<<
" -> "<<
this->best_path[
1];}
void Print(){
for(
int i =
1 ; i <
this->Nv+
1 ; i++){
for(
int j =
1 ; j <
this->Nv+
1 ; j++){
printf(
"%3d",
this->data[i][j]);}
cout<<endl;}}
};
int main()
{
cout<<
"請輸入頂點數與邊數:"<<endl;
int nv,ne;
cin>>nv>>ne;Graph graph(nv,ne);
cout<<
"鄰接矩陣為:"<<endl;graph.Print();
cout<<
"該圖的漢密爾頓回路長度為:"<<endl;
int length =
0;length = graph.Hanmilton();
cout<<length<<endl;
cout<<
"漢密爾頓回路路徑為:"<<endl;graph.Print_Best_Path();
return 0;
}
運行結果如下:
總結
以上是生活随笔為你收集整理的汉密尔顿回路问题的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。