分支限界法(优先队列)求旅行商问题

本文介绍了如何利用分支限界法中的优先队列策略解决旅行商问题。首先解释了旅行商问题的背景和要求,然后详细阐述了分支限界法的工作原理,特别提到了队列式和优先队列式两种方式。接着,展示了C语言实现的优先队列式分支限界法代码,包括最小堆节点结构、插入和删除节点的函数,以及整个求解过程。最后讨论了在实现过程中遇到的边界条件处理和输入处理等问题。

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

1、问题描述:

旅行商问题(Traveling Salesman Problem,TSP)又译为旅行推销员问题、货郎担问题,简称为TSP问题,是最基本的路线问题,该问题是在寻求单一旅行者由起点出发,通过所有给定的需求点之后,最后再回到原点的最小路径成本。最早的旅行商问题的数学规划是由Dantzig等人提出。

要求:随机生成顶点数为n的图,利用优先队列式分支限界法完成旅行商问题求解。

2、分支限界法:

分支限界法常以广度优先或以最小耗费(最大效益)优先的方式搜索问题的解空间树。在分支限界法中,每一个活结点只有一次机会成为扩展结点。活结点一旦成为扩展结点,就一次性产生其所有儿子结点。在这些儿子结点中,导致不可行解或导致非最优解的儿子结点被舍弃,其余儿子结点被加入活结点表中。此后,从活结点表中取下一结点成为当前扩展结点,并重复上述结点扩展过程。这个过程一直持续到找到所需的解或活结点表为空时为止。 

解题模型:

(1)队列式(FIFO):  分支限界法按照队列先进先出(FIFO)原则选取下一个节点为扩展节点。

(2)优先队列式分支限界: 按照优先队列中规定的优先级选取优先级最高的节点成为当前扩展节点。

3、代码:

#include <stdio.h>

#include <malloc.h>//malloc.h,动态存储分配函数头文件,当对内存区进行操作时,调用相关函数.。

#define NoEdge 10000//图G的无边标记

struct MinHeapNode//最小堆,用于表示活结点优先队列;

{

     int lcost; //子树的下界

     int cc; //当前距离

     int rcost; //当前顶点最小出边加上剩余所有顶点的最小出边和

     int s; //根节点到当前节点的路径为x[0:s]

     int *x; //需要进一步搜索的顶点是//x[s+1:n-1]

     struct MinHeapNode *next;

};

int n; //图G的顶点数

int **a; //图G的邻接矩阵

int cc; //当前距离

int bestc; //当前最小距离

MinHeapNode* head = 0; /*堆头*/

MinHeapNode* lq = 0; /*堆第一个元素*/

MinHeapNode* fq = 0; /*堆最后一个元素*/

int DeleteMin(MinHeapNode*&E)//逐层推进

{

     MinHeapNode* tmp = NULL;//MinHeapNode类型tmp的指针,初始为空

     tmp = fq;

     E = fq;

     if(E == NULL)//如果E比那个孩子小的话就不能保证堆序的性质了,新建结点的位置

          return 0;

     head->next = fq->next; /*链表头*/

     fq = fq->next;

     return 0;

}

int Insert(MinHeapNode* hn)//首先建立一个空穴,然后比较和空穴的父亲的大小,把“大的父亲”换下来,以此推进,最后把X放到合适的位置

{

     if(head->next == NULL)

     {

          head->next = hn; //将元素放入链表中

          fq = lq = head->next; //一定要使元素放到链中

     }

     else

     {

          MinHeapNode *tmp = NULL;

          tmp = fq;

          if(tmp->cc > hn->cc)

          {

                hn->next = tmp;

                head->next = hn;

                fq = head->next; /*链表只有一个元素的情况*/

          }

          else

          {

                for(; tmp != NULL;)

                {

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值