分枝限界法实验报告文档格式.docx
《分枝限界法实验报告文档格式.docx》由会员分享,可在线阅读,更多相关《分枝限界法实验报告文档格式.docx(10页珍藏版)》请在冰豆网上搜索。
#include"
init.h"
CirQueue.h"
MinPath.h"
output.h"
voidmain()
{
intk;
intq;
cout<
<
"
------------欢迎使用本系统---------------"
endl;
------------请选择单元路径的起点:
---------------"
------------提示:
输入"
1<
到"
n-1<
之间的整数---------------"
cin>
>
k;
------------请选择单元路径的终点:
q;
while(k<
1||k>
11)
{
cout<
之间的数,请重新输入---------------"
cin>
}
MinPath(k);
output(k,q);
}
init.h
constintsize=200;
constintinf=1000;
//两点距离上界置为1000
constintn=12;
//图顶点个数加1
intprev[n];
//图的前驱顶点
intdist[]={0,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf};
//最短距离数组
intc[n][n]={{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,2,3,4,inf,inf,inf,inf,inf,inf,inf},
{0,inf,0,3,inf,7,2,inf,inf,inf,inf,inf},
{0,inf,inf,0,inf,inf,9,2,inf,inf,inf,inf},
{0,inf,inf,inf,0,inf,inf,2,inf,inf,inf,inf},
{0,inf,inf,inf,inf,0,inf,inf,3,3,inf,inf},
{0,inf,inf,inf,inf,inf,0,1,inf,3,inf,inf},
{0,inf,inf,inf,inf,inf,inf,0,inf,5,1,inf},
{0,inf,inf,inf,inf,inf,inf,inf,0,inf,inf,3},
{0,inf,inf,inf,inf,inf,inf,inf,inf,0,inf,2},
{0,inf,inf,inf,inf,inf,inf,inf,inf,2,inf,2},
{0,inf,inf,inf,inf,inf,inf,inf,inf,inf,inf,0},};
//图的邻接矩阵
CirQueue.h
classMinHeapNode//创建极小堆用来存储活结点表
public:
inti;
//顶点编号
intlength;
//当前路长
};
classCirQueue//循环队列
private:
intfront,rear;
//头指针和尾指针
MinHeapNodedata[size];
public:
CirQueue()//初始化建空队列
front=rear=0;
voidqueryIn(MinHeapNodee)//元素入队操作
if((rear+1)%size!
=front)//队列未满
rear=(rear+1)%size;
//插入新的队尾元素
data[rear]=e;
//在队尾插入元素
voidqueryOut()//元素出队操作
if(rear!
=front)
front=(front+1)%size;
//删除队头元素
}
MinHeapNodegetQuery()//读取队头元素,但不出队
returndata[(front+1)%size];
returndata[1];
boolempty()//判断队列是否为空
returnfront==rear;
}
boolfull()//判断队列是否为满
return(rear+1)%size==front;
};
//CirQueue结束
MainPath.h
voidMinPath(intv)
CirQueues;
//定义源为初始扩展结点
MinHeapNodee;
e.i=v;
e.length=0;
dist[v]=0;
s.queryIn(e);
//将源节点加入队列
while(true){
for(intj=1;
j<
n;
j++){
if(j>
=n)
break;
MinHeapNodem=s.getQuery();
if((c[m.i][j]<
inf)&
&
(m.length+c[m.i][j]<
dist[j]))//顶点i到顶点j可达,且从源出发途经i到j的路径长度小于当前最优路径长度
dist[j]=m.length+c[m.i][j];
prev[j]=m.i;
MinHeapNodemi;
//加入活结点优先队列
mi.i=j;
mi.length=dist[j];
if(s.full())
break;
s.queryIn(mi);
//元素入队
}//for循环结束
if(s.empty())
s.queryOut();
//当该结点的孩子结点全部入队后,删除该结点
}//while循环结束
}//方法结束
output.h
voidoutput(intk,intq)
intq1=q;
if(dist[q1]==1000){
------------找不到此路径---------------"
return;
最短路径长为:
"
dist[q1]<
单源最短路径为:
;
inta[12]={0};
intt=q1;
ints=0;
for(inti=0;
t!
=k;
i++)
a[i]=prev[t];
t=prev[t];
s=s+1;
for(i=s-1;
i>
-1;
i--){
a[i]<
q1;
endl<
六、测试数据及其结果分析
1.选择起点:
1,终点:
11
1到11最短路径长为8,为1->
3->
7->
10->
11所获得。
2.选择起点:
2,终点:
9
2到9最短路径长为5,为2->
6->
9所获得。
3.选择起点8,终点2
8到2没有路径,输出“找不到此路径”。
4.选择起点11,终点1
11到1没有路径,输出“找不到此路径”。
七、调试过程中的问题
1.CirQueue.h中,函数getQuery()中在调试过程中出现warnig:
'
CirQueue:
:
getQuery'
:
notallcontrolpathsreturnavalue.
解决方案:
在if语句下面加上returndata[1];
使当rear=front时函数也返回一个值。
2.当两结点间没有路径时,程序执行时出现错误。
在输出函数output中加入下面代码
if(dist[q1]==1000){
即当两结点无路径时,输出提示“找不到此路径”,程序执行时不会崩溃。
3.输出过程中,如何使结点按顺序输出?
定义一个数组a[],应用递归对存储前驱结点的数组prev[]从后往前求解,将得到的值赋给数组a[],最后逆向输出对应的数组a[],即得到正确的路径顺序。
如下:
for(inti=0;
八、程序设计总结
本次实验回顾了用分枝限界法求解单源最短路径问题的思想,运用了优先权队列和堆的一些知识,对以前学过的东西有了进一步的认识,也认识到以前学习上的疏漏和不足,算法的时间复杂度是O(n^2)。
本来设计中没有考虑终点可变的情形,后来通过对output.h中输出函数的修改,加入一个变量k,对函数进行相应的修改不断地调试,最终得到正确的结果,本次实验对编程能力尤其是调试和改进程序的能力有了较大的提高。