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;)
{