单源最短路径问题.doc
《单源最短路径问题.doc》由会员分享,可在线阅读,更多相关《单源最短路径问题.doc(4页珍藏版)》请在冰点文库上搜索。
实验四单源最短路径问题
一、实验目的:
1、理解分支限界法的剪枝搜索策略;
2、掌握分支限界法的算法柜架;
3、掌握分支限界法的算法步骤;
4、通过应用范例学习动态规划算法的设计技巧与策略;
二、实验内容及要求:
1、使用分支限界法解决单源最短路径问题。
2、通过上机实验进行算法实现。
3、保存和打印出程序的运行结果,并结合程序进行分析,上交实验报告。
三、实验原理:
分支限界法的基本思想:
1、分支限界法与回溯法的不同:
1)求解目标:
回溯法的求解目标是找出解空间树中满足约束条件的所有解,而分支限界法的求解目标则是找出满足约束条件的一个解,或是在满足约束条件的解中找出在某种意义下的最优解。
2)搜索方式的不同:
回溯法以深度优先的方式搜索解空间树,而分支限界法则以广度优先或以最小耗费优先的方式搜索解空间树。
2、分支限界法基本思想:
分支限界法常以广度优先或以最小耗费(最大效益)优先的方式搜索问题的解空间树。
在分支限界法中,每一个活结点只有一次机会成为扩展结点。
活结点一旦成为扩展结点,就一次性产生其所有儿子结点。
在这些儿子结点中,导致不可行解或导致非最优解的儿子结点被舍弃,其余儿子结点被加入活结点表中。
此后,从活结点表中取下一结点成为当前扩展结点,并重复上述结点扩展过程。
这个过程一直持续到找到所需的解或活结点表为空时为止。
3、常见的两种分支限界法:
1)队列式(FIFO)分支限界法
按照队列先进先出(FIFO)原则选取下一个节点为扩展节点。
2)优先队列式分支限界法
按照优先队列中规定的优先级选取优先级最高的节点成为当前扩展节点。
四、程序代码
#include
usingnamespacestd;
intmatrix[100][100];//邻接矩阵
boolvisited[100];//标记数组
intdist[100];//源点到顶点i的最短距离
intpath[100];//记录最短路的路径
intsource;//源点
intvertex_num;//顶点数
intedge_num;//边数
intdestination; //终结点
voidDijkstra(intsource)
{
memset(visited,0,sizeof(visited));//初始化标记数组
visited[source]=true;
for(inti=0;i {
dist[i]=matrix[source][i];
path[i]=source;
}
intmin_cost;//权值最小
intmin_cost_index;//权值最小的下标
for(inti=1;i {
min_cost=INT_MAX;
for(intj=0;j {
if(visited[j]==false&&dist[j] {
min_cost=dist[j];
min_cost_index=j;
}
}
visited[min_cost_index]=true;//该点已找到,进行标记
for(intj=0;j {
if(visited[j]==false&&
matrix[min_cost_index][j]!
=INT_MAX&&//确保两点之间有边
matrix[min_cost_index][j]+min_cost {
dist[j]=matrix[min_cost_index][j]+min_cost;
path[j]=min_cost_index;
}
}
}
}
intmain()
{
cout<<"请输入图的顶点数(<100):
";
cin>>vertex_num;
cout<<"请输入图的边数:
";
cin>>edge_num;
for(inti=0;i for(intj=0;j matrix[i][j]=(i!
=j)?
INT_MAX:
0;//初始化matrix数组
cout<<"请输入边的信息:
\n";
intu,v,w;
for(inti=0;i {
cout<<"请输入第"<
";
cin>>u>>v>>w;
matrix[u][v]=matrix[v][u]=w;
}
cout<<"请输入源点(<"<";
cin>>source;
Dijkstra(source);
cout<<"请输入终结点(<"<";
cin>>destination;
cout<