哈密顿回路的应用

电子说

1.3w人已加入

描述

哈密顿图定义概念

哈密顿通路(回路)与哈密顿图(Hamilton图)通过图G的每个结点一次,且仅一次的通路(回路),就是哈密顿通路(回路)。存在哈密顿回路的图就是哈密顿图。

1.哈密顿通路

设G=《V,E》为一图(无向图或有向图).G中经过每个顶点一次且仅一次的通路称作哈密顿通路

2.哈密顿回路

G中经过每个顶点一次且仅一次的回路称作哈密顿回路

3.哈密顿图

若G中存在哈密顿回路,则称它是哈密顿图

4.定义详解:

(1)存在哈密顿通路(回路)的图一定是连通图;

(2)哈密顿通路是初级通路,哈密顿回路是初级回路;

(3)若G中存在哈密顿回路,则它一定存在哈密顿通路,反之不真

(4)只有哈密顿通路,无哈密顿回路的图不交哈密顿图;

哈密顿图

二、判定定理

注意:目前没有找到哈密顿图的简单的充要条件

(1)设无向图G=《V,E》为哈密顿图,V1是V的任意真子集,则(注:n阶xx图指的是n个顶点,不要迷!)

p(G-V1)《=|V1|

其中,p(G-V1)为G中删除V1后的所得图的连通分支数目,|V1|为V1集合中包含的顶点个数。【哈密顿图存在的必要条件】

推论:有割点的图一定不是哈密顿图

设v是图中的割点,则p(G-v)》=2,由上述定理知G不是哈密顿图

(2)设G是n(n》=3)阶无向简单图,若对于G中的每一对不相邻的顶点u,v,均有

d(u)+d(v)》=n-1

则G中存在哈密顿通路。又若

d(u)+d(v)》=n

则G中存在哈密顿回路,即G为哈密顿图。【哈密顿图存在的充分条件,不是必要条件】

其中d(u),d(v)分别代表顶点u,v的度数。

推论:设G是n(n》=3)阶无向简单图,若G的最小度》=n/2,则G是哈密顿图。

由推论知,对于完全图Kn,当n》=3时,是哈密顿图,完全二部图Kr,s当r==s》=2时是哈密顿图。

(3)在n(n》=2)阶有向图D=《V,E》中,如果略去所有有向边的方向,所得无向图中含生成子图Kn,则D中存在哈密顿通路。

推论:n(n》=3)阶有向完全图是哈密顿图。

1.常用方法判断是哈密顿图:

(1)若能通过观察找出图G中的一条哈密顿回路,则G当然是哈密顿图。

(2)若一个无向图G满足上述(2)中的条件,一个有向图D满足上述(3)的推论的条件,则G、D都是哈密顿图。

2.破坏哈密顿图存在的必要条件,判定不是哈密顿图:

设n阶图G是哈密顿图,则G应该满足以下诸条件:

(1)G必须是连通图;

(2)G中的边数m必须大于等于顶点数n;

(3)若G中存在2度顶点v,即d(v)=2,则与v关联的两条边ei,ej必须在G中的任何哈密顿回路上;

(4)若G中存在每条哈密顿回路中出现的边,不能构成边数小于n的初级回路(圈);

破坏以上诸条件中的一条,都不是哈密顿图。

哈密顿回路的应用

随机生成并哈密顿回路求解:

// Graph.cpp : 定义控制台应用程序的入口点。

//

#include “stdafx.h”

#include“Graph.h”

#include《iostream》

#include《fstream》

#include《stack》

#include《queue》

#include《limits》

using namespace std;

template《class T,class E》

int sb(int start,Graph《T,E》 &myGraph,ostream & fout)//simple backtracking 算法解决图的最小哈密顿回路问题 v为回路的起点和终点

{

E minDistance=std::numeric_limits《E》::max();

stack《int》 myStack;

myStack.push(start);

int numVertices=myGraph.NumberOfVertices();

bool *visited=new bool[numVertices];

memset(visited,false,numVertices);

int v;

int w=-1;

while(!myStack.empty()) //栈不为空

{

v=myStack.top();

visited[v]=true;

if(w==-1)

{

w=myGraph.getFirstNeighbor(v);

}

else

{

w=myGraph.getNextNeighbor(v,w);

}

for(;w!=-1&&visited[w]==true;w=myGraph.getNextNeighbor(v,w))

{

}

if(w==-1) //未找到可行的下一个顶点

{

myStack.pop(); //回溯

w=v;

visited[v]=false;

}

else //找到可行的下一个顶点

{

myStack.push(w); //放入栈中

if(myStack.size()==numVertices)//走过所有的顶点

{

if(myGraph.getWeight(start,w)==std::numeric_limits《E》::max()) //判断最后一个顶点有没有回到起点的边

{

myStack.pop();

visited[w]=false;

}

else //成功找到回路

{

//输出回路 并记录下回路的长度

stack《int》 temp;

while(!myStack.empty())

{

int n=myStack.top();

temp.push(n);

myStack.pop();

}

fout《《“哈密顿回路 : ”;

E distance=0;

int n=temp.top();

myStack.push(n);

temp.pop();

int last=n;

fout《《n《《“--”;

while(!temp.empty())

{

n=temp.top();

myStack.push(n);

temp.pop();

distance+=myGraph.getWeight(last,n);

last=n;

fout《《n《《“--”;

}

fout《《start《《“--”《《endl;

distance+=myGraph.getWeight(last,start);

fout《《“总长度为:”《《distance《《endl;

//记录最短长度

if(minDistance》distance)

{

minDistance=distance;

}

//

myStack.pop();

visited[w]=false;

}

}

else

{

w=-1;

}

}

}

fout《《“最短哈密顿回路的长度为:”《《minDistance《《endl;

return 1;

}

//分支限界法求解最短哈密顿回路问题

template《class E》

struct NODE

{

int dep; //表示该结点在搜索树的第几层

int *vertices; //该节点力包含的各个顶点

E length; //从根到当前结点已经走过的路径长度

NODE(int depth)

{

dep=depth;

vertices=new int[dep];

};

void cpy(int *&des)

{

for(int i=0;i《dep;i++)

{

des[i]=vertices[i];

}

}

bool find(int v)

{

for(int i=0;i《dep;i++)

{

if(vertices[i]==v)

return true;

}

return false;

}

};

template《class T,class E》

int bb(int start,Graph《T,E》 & myGraph,ostream & fout)

{

stack《NODE《E》》 myStack; //队列

E minDistance=std::numeric_limits《E》::max();

int s=myGraph.getFirstNeighbor(start);

for(s=myGraph.getNextNeighbor(start,s);s!=-1;s=myGraph.getNextNeighbor(start,s))

{

NODE《E》 n(2);

n.vertices[0]=start;n.vertices[1]=s;

n.length=myGraph.getWeight(start,s);

myStack.push(n);

}

while(!myStack.empty()) //队列不为空

{

NODE《E》 n=myStack.top();

myStack.pop();

int v=n.vertices[n.dep-1];

if(n.dep+1==myGraph.NumberOfVertices())//到了最后一层 判断是不是哈密顿回路

{

int w;

for( w=myGraph.getFirstNeighbor(v);w!=-1;w=myGraph.getNextNeighbor(v,w))

{

if( n.find(w)==false)

break;

}

if(w!=-1)

{

if(myGraph.getWeight(w,start)《std::numeric_limits《E》::max())

{

//形成回路

fout《《“哈密顿回路为:”;

for(int i=0;i《n.dep;i++)

{

fout《《n.vertices[i]《《“ ”;

}

fout《《w《《“ ”《《start《《endl;

E tempDistance=n.length+myGraph.getWeight(v,w)+myGraph.getWeight(w,start);

fout《《“总长度为: ”《《tempDistance《《endl;

if(minDistance》tempDistance)

{

minDistance=tempDistance;

}

}

}

}

for(int w=myGraph.getFirstNeighbor(v);w!=-1;w=myGraph.getNextNeighbor(v,w))

{

if(n.find(w)==false)

{

NODE《E》 ne(n.dep+1);

ne.length=n.length+myGraph.getWeight(v,w);

if(ne.length《minDistance)

{

n.cpy(ne.vertices);

ne.vertices[ne.dep-1]=w;

myStack.push(ne);

}

}

}

}

fout《《“最短长度为 ”《《minDistance《《endl;

return minDistance;

}

int _tmain(int argc, _TCHAR* argv[])

{

Graph《char,int》 myGraph(10);

//ifstream fin(“input.txt”);

//myGraph.Init(fin);

myGraph.RandInit();//随机初始化图

ofstream fout(“outputsb.txt”);

//sb(0,myGraph,fout);

ofstream fout1(“outputbb.txt”);

bb(0,myGraph,fout1);

system(“pause”);

return 0;

}

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分