图论与代数实验报告
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
图论与代数实验报告
旅行售货员问题(TSP)
某售货员要到若干城市去推销商品,一直各城市之间的路程,他要选定一条从驻地出发,经过每个城市一遍,最后回到住地的路线,使总的路程最短。
我用分支限界法解决问题。
1、分支限界法基本思想
分支限界法常以广度优先或以最小耗费(最大效益)优先的方式搜索问题的解空间树。
在分支限界法中,每一个活结点只有一次机会成为扩展结点。活结点一旦成为扩展结点,就一次性产生其所有儿子结点。在这些儿子结点中,导致不可行解或导致非最优解的儿子结点被舍弃,其余儿子结点被加入活结点表中。
此后,从活结点表中取下一结点成为当前扩展结点,并重复上述结点扩展过程。这个过程一直持续到找到所需的解或活结点表为空时为止。
2、常见的两种分支限界法
(1)队列式(FIFO)分支限界法
按照队列先进先出(FIFO)原则选取下一个节点为扩展节点。
(2)优先队列式分支限界法
按照优先队列中规定的优先级选取优先级最高的节点成为当前扩展节点。
最大优先队列:使用最大堆,体现最大效益优先。
最小优先队列:使用最小堆,体现最小费用优先。
该问题是一个NP完全问题,有(n-1)!条可选路线。
路线是一个带权图。图中各边的费用(权)为正数。图的一条周游路线是包括V中的每个顶点在内的一条回路。周游路线的费用是这条路线上所有边的费用之和。
旅行售货员问题的解空间可以组织成一棵树,从树的根结点到任一叶结点的路径定义了图的一条周游路线。旅行售货员问题要在图G 中找出费用最小的周游路线。
即:
设G(V,E)是一带权有向图,V={1,2,…n },其耗费矩阵C=(ci,j),当时, 记ci,j=无穷大且ci,j=无穷大.问如何选择周游路线使耗费最小?
算法思路:设周游路线从结点1开始,解为等长数组X=(1,x2,...xn)
则解空间树为排列树,在树中做广度优先搜索。
约束条件: xi 不等于xj ,i 不等于j;
目标函数:解向量对应的边权之和∑Cij
目标函数限界初值:U=无穷大
C=
算法描述:
①算法开始时创建一个最小堆,用于表示活结点优先队列
②堆中每个结点的子树费用的下界lcost 值是优先队列的优先级。 ③接着算法计算出图中每个顶点的最小费用出边并用minout 记录。 ④如果所给的有向图中某个顶点没有出边,则该图不可能有回路,算法即告结束。
⎥⎥⎥⎥⎦
⎤⎢⎢⎢⎢⎣⎡∞∞∞∞201042056105304630
⑤如果每个顶点都有出边,则根据计算出的minout作算法初始化。
1、float row_min(NODE *node,int row,float &second)
功能:返回由指针node所指向节点费用矩阵中第row行最小值,并把次小值回送与引用变量second中
2、float col_min(NODE *node,int col,float &second)
功能:返回由指针node所指向节点费用矩阵中第col列最小值,并把次小值回送与引用变量second中
3、float array_red(NODE *node)
功能:归约指针node指向的节点的费用矩阵返回值为归约常数4、float edge_sel (NODE *node,int &vk,int &vl)
功能:计算
d并且搜索分支的边返回dkl的值
kl
5、void del_rowcol(NODE *node,int vk,int vl)
功能:删除费用矩阵当前
V行第l V列的所有元素
k
6、void edge_byp(NODE *node,int vk, int vl)
功能:把vk vl表示的边登记到顶点邻接表并旁路矩阵中有关的边7、NODE *initial(float c[20][20],int n)
功能:初始化函数
8、void insert(HEAP *&heap,int &n_heap,HEAP z)
功能:向最小堆栈插入结点函数
9、HEAP delete_min(HEAP *&heap,int &n_heap)
功能:删除堆栈头结点函数
分支限界法求解TSP问题的程序
#include
#include
#include
#include
using namespace std;
//定义相关结构体
typedef struct node_data //结点数据结构
{
float c[20][20]; /*费用矩阵*/
int row_init[20]; /*费用矩阵的当前行映射为原始行*/ int col_init[20]; /*费用矩阵的当前列映射为原始列*/
int row_cur[20]; /*费用矩阵的原始行映射为当前行*/ int col_cur[20]; /*费用矩阵的原始列映射为当前列*/ int ad[20]; /*回路顶点邻接表*/
int k; /*当前费用矩阵的阶*/
float w; /*结点的下界*/
}NODE;
typedef struct /*堆结构数据*/
{
NODE *p; /*指向结点元素的指针*/
float w; /*所指向结点的下界,堆元素的关键字*/
}HEAP;
//主要函数申明部分
float row_min(NODE *node,int row,float &second);