哈密顿环之分支限界

本文介绍了最小哈密顿环问题的解决方法,使用分支限界算法在给定的无向连通图中寻找权值代价最小的哈密顿环。算法通过递归地构建路径并计算路径代价来优化搜索过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最小哈密顿环问题,输入是一个无向连通图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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值