生活随笔
收集整理的這篇文章主要介紹了
汉密尔顿回路问题
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
概述
這是自己這學(xué)期算法課的實(shí)驗(yàn)作業(yè)。下面給出漢密爾頓圖的定義。定義如下:對(duì)于連通圖G=(V,E),V1,V2,…,Vn是G 的一條通路,且圖中任意兩個(gè)頂點(diǎn)都可達(dá),若 中每個(gè)頂點(diǎn)在該通路中出現(xiàn)且僅出現(xiàn)一次,則稱(chēng)該通路為漢密爾頓通路。若 V1=Vn,則稱(chēng)該通路為漢密爾頓回路。
算法描述
1)初始化最佳路徑數(shù)組best_path,同時(shí)初始化臨時(shí)路徑數(shù)組path與訪問(wèn)數(shù)組isvisited,設(shè)置最小長(zhǎng)度min,設(shè)置長(zhǎng)度變量length = 0
2)開(kāi)始對(duì)每個(gè)頂點(diǎn)進(jìn)行遍歷尋找最佳路徑,首先堆訪問(wèn)數(shù)組中對(duì)應(yīng)頂點(diǎn)進(jìn)行置1,并把當(dāng)前頂點(diǎn)追加到path,同時(shí)利用cur_vertex這個(gè)臨時(shí)變量保存當(dāng)前結(jié)點(diǎn),并開(kāi)始進(jìn)行循環(huán)。
3)找到出cur_vertex之外與之相鄰且并未訪問(wèn)的一個(gè)頂點(diǎn)k,利用tmp保存這兩點(diǎn)之間的權(quán)重,之后檢查是否存在比tmp更小且與cur_vertex相鄰的頂點(diǎn),如有則更新tmp與訪問(wèn)的頂點(diǎn)k,之后更新length += tmp,以及更新cur_vertex = k,如果length大于min,則說(shuō)明改路徑無(wú)效,跳出循環(huán)。
4)重復(fù)步驟3遍歷每一個(gè)結(jié)點(diǎn)。循環(huán)結(jié)束后,對(duì)length更新,加上最后一個(gè)結(jié)點(diǎn)到cur_vertex結(jié)點(diǎn)的距離。這是如果min大于legnth,則對(duì)min更新,并把path數(shù)組復(fù)制到best_path中去。
5)重復(fù)步驟2)直至遍歷完每個(gè)結(jié)點(diǎn)。返回最小長(zhǎng)度。
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;
}
例子
下面的例子是基于如下圖結(jié)構(gòu):
全部代碼如下:
#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<<
"請(qǐng)輸入邊與邊長(zhǎng):"<<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<<
"請(qǐng)輸入頂點(diǎn)數(shù)與邊數(shù):"<<endl;
int nv,ne;
cin>>nv>>ne;Graph graph(nv,ne);
cout<<
"鄰接矩陣為:"<<endl;graph.Print();
cout<<
"該圖的漢密爾頓回路長(zhǎng)度為:"<<endl;
int length =
0;length = graph.Hanmilton();
cout<<length<<endl;
cout<<
"漢密爾頓回路路徑為:"<<endl;graph.Print_Best_Path();
return 0;
}
運(yùn)行結(jié)果如下:
總結(jié)
以上是生活随笔為你收集整理的汉密尔顿回路问题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。