电子说
哈密顿通路(回路)与哈密顿图(Hamilton图)通过图G的每个结点一次,且仅一次的通路(回路),就是哈密顿通路(回路)。存在哈密顿回路的图就是哈密顿图。
设G=《V,E》为一图(无向图或有向图).G中经过每个顶点一次且仅一次的通路称作哈密顿通路
G中经过每个顶点一次且仅一次的回路称作哈密顿回路
若G中存在哈密顿回路,则称它是哈密顿图
(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)若能通过观察找出图G中的一条哈密顿回路,则G当然是哈密顿图。
(2)若一个无向图G满足上述(2)中的条件,一个有向图D满足上述(3)的推论的条件,则G、D都是哈密顿图。
设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;
}
全部0条评论
快来发表一下你的评论吧 !