生活随笔
收集整理的这篇文章主要介绍了
汉密尔顿回路问题
小编觉得挺不错的,现在分享给大家,帮大家做个参考.
概述
这是自己这学期算法课的实验作业。下面给出汉密尔顿图的定义。定义如下:对于连通图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;
}
运行结果如下:
总结
以上是生活随笔为你收集整理的汉密尔顿回路问题的全部内容,希望文章能够帮你解决所遇到的问题。
如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。