最小哈密顿环问题,输入是一个无向连通图G=(V,E),每个节点都没有到自身的边,每对节点间都有一条非负加权边;输出一个权值代价和最小的哈密顿环。
使用分支限界算法,先令当前的界限定为(最大权值*路数),然后寻找路径依次判定是否有更小值存在。
#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#define MAX_SIZE 21
//查找回路函数
void getHamiltonPathBybranch(int graph[MAX_SIZE][MAX_SIZE],int visited[MAX_SIZE],
int path[MAX_SIZE],int bestpath[MAX_SIZE],
int len,int currentlen,int *mincost);
//计算当前路径的代价
int getPathcost(int path[MAX_SIZE],int graph[MAX_SIZE][MAX_SIZE],int currentlen);
void HamiltonBybranch()
{
int len,i,j,mincost;//len为点数
int graph[MAX_SIZE][MAX_SIZE];//邻接矩阵
int visited[MAX_SIZE],path[MAX_SIZE],bestpath[MAX_SIZE];//标记已读和路径
//double start,end;//时间变量
// CPU频率
LARGE_INTEGER li;
// 记录过程时间
LONGLONG start,end,fred;
// 获取CPU频率
QueryPerformanceFrequency(&li);
fred = li.QuadPart;
freopen("inputcomplete.txt","r",stdin);
freopen("outputbybranch.txt","w",stdout);
//
while(scanf("%d",&len)!=EOF)
{
//初始化
for(i=0; i<len; i++)
{
visited[i] = 0;
path[i] = -1;
bestpath[i] = -1;
for(j=0; j<len; j++)
scanf("%d",&graph[i][j]);
}
//start = GetTickCount();
QueryPerformanceCounter(&li);
start = li.QuadPart;
path[0] = 0;
visited[0] = 1;
mincost = 100*len;
getHamiltonPathBybranch(graph,visited,path,bestpath,len,1,&mincost);
printVertex(bestpath,len);
printf("最小代价为%d\n",mincost);
//end = GetTickCount();
QueryPerformanceCounter(&li);
end = li.QuadPart;
// 计算持续时间(us)
printf("经历时间为%dms\n\n",(int)1000 * (end-start) / fred);
//printf("经历时间为%.2f\n\n",end-start);
}
}
void getHamiltonPathBybranch(int graph[MAX_SIZE][MAX_SIZE],int visited[MAX_SIZE],
int path[MAX_SIZE],int bestpath[MAX_SIZE],
int len,int currentlen,int *mincost)
{
int i,costpath;
if(len == currentlen)
{
costpath = getPathcost(path,graph,currentlen) + graph[path[currentlen-1]][0];
if(costpath<*mincost)
{
*mincost = costpath;
for(i=0; i<len; i++)
bestpath[i] = path[i];
return;
}
}
for(i=1; i<len; i++)
{
if(!visited[i])
{
visited[i] = 1;
path[currentlen] = i;
if(getPathcost(path,graph,currentlen+1)<*mincost)
getHamiltonPathBybranch(graph,visited,path,bestpath,len,currentlen+1,mincost);
path[currentlen] = -1;
visited[i] = 0;
}
}
}
int getPathcost(int path[MAX_SIZE],int graph[MAX_SIZE][MAX_SIZE],int currentlen)
{
int i,cost;
cost = 0;
for(i=1; i<currentlen; i++)
cost = cost + graph[path[i-1]][path[i]];
return cost;
}