实验四 分支限界法实现单源最短路径
单元最短路径问题 分支限界法

单元最短路径问题分支限界法【序】单元最短路径问题:分支限界法解析【引】在计算机科学中,图论问题一直是研究的热点之一。
而图的最短路径问题更是其中一个经典的困难问题。
在图中,单元最短路径问题就是要找到两个顶点之间的最短路径。
而在解决这个问题的过程中,我们可以借助分支限界法,来帮助我们找到最优的解。
本文将深度分析单元最短路径问题及分支限界法,以帮助读者全面理解并掌握这一问题解决方法。
【1】什么是单元最短路径问题?单元最短路径问题是图论中常见的一个问题,它要求在一个加权有向图或无向图中,找到两个给定顶点之间的最短路径。
该问题的解决方法包括了广度优先搜索、迪杰斯特拉算法等多种方法,其中分支限界法是一种常用的解决方法之一。
【2】分支限界法的基本思想分支限界法是一种通过搜索解空间来找到最优解的方法。
它通过将问题空间划分为一系列子问题,并不断搜索当前最优解的子空间,从而逐渐缩小问题空间,最终找到最优解。
【3】分支限界法在单元最短路径问题中的应用在解决单元最短路径问题时,分支限界法可以通过以下步骤来实施:1. 确定初始解和问题空间:选择一个顶点作为起始点,并设置一个初始解,例如将起始点的路径长度设置为0,其他顶点的路径长度设置为无穷大。
2. 扩展节点:从初始解开始,按照一定的扩展策略选择下一个节点进行扩展。
在单元最短路径问题中,我们可以选择将当前节点的邻接节点添加到解空间中。
3. 更新当前解:根据当前解空间中的节点,更新各节点的路径长度。
4. 剪枝:根据一定的条件,判断是否要剪去一些节点,从而缩小问题空间。
5. 重复上述步骤:不断迭代地重复上述步骤,直到找到最优解或者问题空间为空。
【4】为什么分支限界法适用于单元最短路径问题?分支限界法适用于单元最短路径问题的原因有以下几点:1. 分支限界法能够保证找到最优解。
通过不断地缩小问题空间,分支限界法能够找到最小的路径长度。
2. 分支限界法具有较高的搜索效率。
在每一步中,分支限界法都能够通过剪枝操作,排除一部分不可能达到最优解的节点,从而减少了搜索空间。
用分支限界法求解单源最短路径问题

•
从队列中取出距离起始节点最近的节点作为当前节点。
•
对当前节点进行扩展操作,生成其可达的所有邻居节点。
•
对于每个邻居节点,计算通过当前节点到达该节点的距离,并更新
其距离值。
•
如果更新后的距离小于该节点当前的最短距离,则更新节点的最短
距离,并将其添加到队列中。
当队列为空时,所有节点的最短路径已经确定。 根据计算得到的最短距离,可以重构最短路径。从目标节点开始,按照每个 节点的最短路径前驱逐步回溯,直到回溯到起始节点,即可得到最短路径。
分支限界法 优化搜索过程。它通过限制搜索空间,避免了对所有可能路径进行穷举搜索,从 而提高了算法的效率。
需要注意的是,分支限界法的实现可能涉及具体的数据结构和算法细节,包 括如何表示图、选择优先队列的实现方式等。具体的实现方法可以根据实际情况 进行调整和优化。
分支限界法(Branch and Bound)是一种常用的算法策略,可用于解决单 源最短路径问题。下面是使用分支限界法求解单源最短路径问题的基本步骤:
初始化:将起始节点设置为当前节点,并将其到起始节点的距离设为 0。将
其他节点到起始节点的距离设为无穷大。 创建一个优先队列(通常使用最小堆)用于存储待扩展的节点。将起始节点
实验四 分支限界法实现单源最短路径

实验四分支限界法实现单源最短路径09电信实验班I09660118 徐振飞一、实验名称实现书本P194页所描述的单源最短路径问题二、实验目的(1)掌握并运用分支限界法基本思想(2)运用分支限界法实现单源最短路径问题(3)区分分支限界算法与回溯算法的区别,加深对分支限界法理解三、实验内容和原理(1)实验原理解单源最短路径问题的优先队列式分支限界法用一极小堆(本次实验我采用java.util包中的优先队列类PriorityQueue来实现)来存储活结点表。
其优先级是结点所对应的当前路长。
算法从图G的源顶点s和空优先队列开始。
结点s被扩展后,它的儿子结点被依次插入堆中。
此后,算法从堆中取出具有最小当前路长的结点作为当前扩展结点,并依次检查与当前扩展结点相邻的所有顶点。
如果从当前扩展结点i到顶点j有边可达,且从源出发,途经顶点i再到顶点j的所相应的路径的长度小于当前最优路径长度,则将该顶点作为活结点插入到活结点优先队列中。
这个结点的扩展过程一直继续到活结点优先队列为空时为止。
(2)实验内容测试用例:123456 342761395四、源程序import java.util.*;public class ShortestPath{private int n;private double matrix[][] = null;private double minpath[];public ShortestPath(int n){this.n = n;matrix = new double[n+1][n+1];minpath = new double[n+1];for(int i=1;i<=n;i++){minpath[i] = Double.MAX_VALUE;}//初始化图getGraphMatrix();}public void getGraphMatrix(){//初始化为不能连通for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){matrix[i][j] = Double.MAX_VALUE;}}System.out.println("请输入边总数:");Scanner scan = new Scanner(System.in);int m = scan.nextInt();System.out.println("依次输入两个顶点号(1~"+n+")和边长:例如 1 2 3");for(int i=0;i<m;i++){int a,b;double d;a = scan.nextInt();b = scan.nextInt();d = scan.nextDouble();if(a<1 || b<1){i--;System.out.println("顶点号不能小于1");continue;}if(a>n||b>n){i--;System.out.println("顶点号不能大于"+n);continue;}matrix[a][b] = d;}}/***@param求以第i个节点为起点的单源最短路径*/public void shortpath(int i){minpath[i] = 0;double curlen = 0;PriorityQueue<Node> heap = new PriorityQueue();Node cur = new Node(i,0);heap.add(cur);while(!heap.isEmpty()){for(int j=1;j<=n;j++){if(matrix[cur.i][j]<Double.MAX_VALUE&& cur.len+matrix[cur.i][j]<minpath[j]){minpath[j] = cur.len+matrix[cur.i][j];heap.add(new Node(j,minpath[j]));}}cur = heap.poll();}//打印最短路径结果System.out.println("最短路径:");for(int j=1;j<=n;j++){if(minpath[j]<Double.MAX_VALUE && j!=i){System.out.println(i+"到"+j+":"+minpath[j]);}}}public static void main(String args []){System.out.println("请输入定点总数:");Scanner scan = new Scanner(System.in);int n = scan.nextInt();ShortestPath s = new ShortestPath(n); s.shortpath(1);}}class Node implements Comparable<Node>{int i;double len;public Node(int i,double l){this.i = i;len = l;}public int compareTo(Node o){double dif = len-o.len;if(dif>0){return 1;}else if(dif==0){return 0;}else{return -1;}}}五、实验结果输出结果分析:测试为上述测试用途,输出结果:1到2的最短路径为3,1到3的最短路径为2,1到4的最短路径为3,1到5的最短路径为7,1到6的最短路径为6。
分支限界法实现单源最短路径

算法分析与设计实验报告分支限界法实现单源最短路径班级:11计算机1学号:110104200109姓名:金李扬日期: 5.221.问题描述以分支限界法实现单源最短路径1.以分支限界实现优先队列2.再以分支限界法的优先队列实现单元最短路径以该图为算法测试数据,获得链接矩阵如下:以-1代表无法到达的点-1 2 3 4 -1 -1 -1 -1 -1 -1 -1-1 -1 3 -1 7 2 -1 -1 -1 -1 -1-1 -1 -1 -1 -1 9 2 -1 -1 -1 -1-1 -1 -1 -1 -1 -1 2 -1 -1 -1 -1-1 -1 -1 -1 -1 -1 -1 3 3 -1 -1-1 -1 -1 -1 -1 -1 1 -1 3 -1 -1-1 -1 -1 -1 -1 -1 -1 -1 5 1 -1-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 3-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 3-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 2-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -12.算法思想分支限界法基本思想:分支限界法常以广度优先或以最小耗费(最大效益)优先的方式搜索问题的解空间树。
在分支限界法中,每一个活结点只有一次机会成为扩展结点。
活结点一旦成为扩展结点,就一次性产生其所有儿子结点。
在这些儿子结点中,导致不可行解或导致非最优解的儿子结点被舍弃,其余儿子结点被加入活结点表中。
此后,从活结点表中取下一结点成为当前扩展结点,并重复上述结点扩展过程。
这个过程一直持续到找到所需的解或活结点表为空时为止。
算法步骤1.用一极小堆来存储活结点表,其优先级是结点所对应的当前路长。
2.算法从图G的源顶点s和空优先队列开始。
结点s被扩展后,它的儿子结点被依次插入堆中。
此后,算法从堆中取出具有最小当前路长的结点作为当前扩展结点,并依次检查与当前扩展结点相邻的所有顶点。
最短路径问题的分支定界算法

最短路径问题的分支定界算法最短路径问题是图论中的重要问题之一,它在许多实际应用中具有广泛的意义。
为了解决最短路径问题,我将介绍一种有效的算法——分支定界算法。
一、问题描述最短路径问题是要找到图中两个顶点之间的最短路径。
给定一个带权有向图,其中顶点表示路径上的地点,边表示路径的长度。
我们需要找到从起点到终点的最短路径。
二、分支定界算法原理分支定界算法是一种穷举搜索算法,通过分解问题的解空间,并确定每个子问题的解上下界,以逐步缩小搜索空间。
以下是分治定界算法的基本步骤:1. 初始化a. 定义一个队列,用于存放候选路径;b. 设置初始最短路径长度为正无穷;c. 将起点加入队列。
2. 分支定界a. 从队列中取出当前路径,并计算路径长度;b. 如果当前路径长度大于等于当前最短路径长度,则剪枝,继续下一个路径;c. 如果当前路径的终点是目标终点,则更新最短路径长度和最短路径,继续下一个路径;d. 否则,扩展当前路径,将其邻节点添加到队列中。
3. 终止条件a. 当队列为空时,终止搜索,得到最短路径。
三、算法实现以下是使用分支定界算法解决最短路径问题的伪代码:```初始化队列;初始化最短路径长度为正无穷;将起点加入队列;while (队列非空) {取出当前路径,并计算路径长度;if (当前路径长度大于等于当前最短路径长度) {剪枝,继续下一个路径;}if (当前路径的终点是目标终点) {更新最短路径长度和最短路径;继续下一个路径;}扩展当前路径,将其邻节点添加到队列中;}返回最短路径;```四、案例分析为了更好地理解分支定界算法的应用,我们以一个简单的案例来说明。
假设有一个城市地图,其中包含多个地点,我们需要找到从起点到终点的最短路径。
首先,我们将起点添加到队列,并初始化最短路径长度为正无穷。
然后,通过不断从队列中取出路径,并计算路径长度,进行分支定界操作。
在每一步分支定界操作中,我们根据当前路径长度与最短路径长度的比较,以及当前路径终点是否为目标终点,来进行剪枝或更新最短路径。
分支限界法实验(单源最短路径)

算法分析与设计实验报告第七次实验姓名学号班级时间12.26上午地点工训楼309实验名称分支限界法实验(单源最短路径)实验目的1.掌握并运用分支限界法的基本思想2.运用分支限界法实现单源最短路径问题实验原理问题描述:在下图所给的有向图G中,每一边都有一个非负边权。
要求图G的从源顶点s 到目标顶点t之间的最短路径。
基本思想:下图是用优先队列式分支限界法解有向图G的单源最短路径问题产生的解空间树。
其中,每一个结点旁边的数字表示该结点所对应的当前路长。
为了加速搜索的进程,应采用有效地方式选择活结点进行扩展。
按照优先队列中规定的优先级选取优先级最高的结点成为当前扩展结点。
catch (int){break;}if(H.currentsize==0) //优先队列空{break;}}}上述有向图的结果:测试结果附录:完整代码(分支限界法)Shorest_path.cpp//单源最短路径问题分支限界法求解#include<iostream>#include<time.h>#include<iomanip>#include"MinHeap2.h"using namespace std;template<class Type>class Graph //定义图类{friend int main();public:void shortest_path(int); private:int n, //图的顶点数*prev; //前驱顶点数组Type **c, //图的邻接矩阵*dist; //最短距离数组};template<class Type>class MinHeapNode //最小堆中的元素类型为MinHeapNode{friend Graph<Type>;public:operator int() const{return length;}private:int i; //顶点编号Type length; //当前路长};//单源最短路径问题的优先队列式分支限界法template<class Type>void Graph<Type>::shortest_path(int v){MinHeap<MinHeapNode<Type>> H(1000);//定义最小堆的容量为1000//定义源为初始扩展结点MinHeapNode<Type> E;//初始化源结点E.i=v;E.length=0;dist[v]=0;while(true)//搜索问题的解空间{for(int j=1;j<=n;j++)if((c[E.i][j]!=0)&&(E.length+c[E.i][j]<dist[j])){//顶点i到顶点j可达,且满足控制约束//顶点i和j之间有边,且此路径小于原先从源点i到j的路径长度dist[j]=E.length+c[E.i][j];//更新dist数组prev[j]=E.i;//加入活结点优先队列MinHeapNode<Type> N;N.i=j;N.length=dist[j];H.Insert(N);//插入到最小堆中}try{H.DeleteMin(E); // 取下一扩展结点}catch (int){break;}if(H.currentsize==0)//优先队列空{break;}}}int main(){int n=11;int prev[12]={0,0,0,0,0,0,0,0,0,0,0,0};//初始化前驱顶点数组intdist[12]={1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000 };//初始化最短距离数组cout<<"单源图的邻接矩阵如下:"<<endl;int **c=new int*[n+1];for(int i=1;i<=n;i++) //输入图的邻接矩阵{c[i]=new int[n+1];for(int j=1;j<=n;j++){cin>>c[i][j];}}int v=1; //源结点为1Graph<int> G;G.n=n;G.c=c;G.dist=dist;G.prev=prev;clock_t start,end,over; //计算程序运行时间的算法start=clock();end=clock();over=end-start;start=clock();G.shortest_path(v);//调用图的最短路径查找算法//输出从源结点到目的结点的最短路径cout<<"从S到T的最短路长是:"<<dist[11]<<endl;for(int i=2;i<=n;i++)//输出每个结点的前驱结点{cout<<"prev("<<i<<")="<<prev[i]<<" "<<endl;}for(int i=2;i<=n;i++) //输出从源结点到其他结点的最短路径长度{cout<<"从1到"<<i<<"的最短路长是:"<<dist[i]<<endl;}for(int i=1;i<=n;i++) //删除动态分配时的内存{delete[] c[i];}delete[] c;c=0;end=clock();printf("The time is %6.3f",(double)(end-start-over)/CLK_TCK); //显示运行时间cout<<endl;system("pause");return 0;}MinHeap.h#include<iostream>template<class Type>class Graph;template<class T>class MinHeap //最小堆类{template<class Type>friend class Graph;public:MinHeap(int maxheapsize=10); //构造函数,堆的大小是10~MinHeap(){delete[] heap;} //最小堆的析构函数int Size() const{return currentsize;} //Size()返回最小堆的个数T Max(){if(currentsize) return heap[1];} //第一个元素出堆MinHeap<T>& Insert(const T& x); //最小堆的插入函数MinHeap<T>& DeleteMin(T& x); //最小堆的删除函数void Initialize(T x[],int size,int ArraySize); //堆的初始化void Deactivate();void output(T a[],int n);private:int currentsize,maxsize;T *heap;};template<class T>void MinHeap<T>::output(T a[],int n) //输出函数,输出a[]数组的元素{for(int i=1;i<=n;i++)cout<<a[i]<<" ";cout<<endl;}template<class T>MinHeap<T>::MinHeap(int maxheapsize){maxsize=maxheapsize;heap=new T[maxsize+1]; //创建堆currentsize=0;}template<class T>MinHeap<T>& MinHeap<T>::Insert(const T& x){if(currentsize==maxsize) //如果堆中的元素已经等于堆的最大大小return *this; //那么不能在加入元素进入堆中int i= ++currentsize;while(i!=1 && x<heap[i/2]){heap[i]=heap[i/2];i/=2;}heap[i]=x;return *this;}template<class T>MinHeap<T>& MinHeap<T>::DeleteMin(T& x) //删除堆顶元素{if(currentsize==0){cout<<"Empty heap!"<<endl;return *this;}x=heap[1];T y=heap[currentsize--];int i=1,ci=2;while(ci<=currentsize){if(ci<currentsize && heap[ci]>heap[ci+1])ci++;if(y<=heap[ci])break;heap[i]=heap[ci];i=ci;ci*=2;}heap[i]=y;return *this;}template<class T>void MinHeap<T>::Initialize(T x[],int size,int ArraySize) //堆的初始化{delete[] heap;heap=x;currentsize=size;maxsize=ArraySize;for(int i=currentsize/2;i>=1;i--){T y=heap[i];int c=2*i;while(c<=currentsize){if(c<currentsize && heap[c]>heap[c+1])c++;if(y<=heap[c])break;heap[c/2]=heap[c];c*=2;}heap[c/2]=y;}}template<class T>void MinHeap<T>::Deactivate(){heap=0; }。
分支界限法求单元点最短路径

一.分支界限法的基本思想分支限界法常以广度优先或以最小耗费(最大效益)优先的方式搜索问题的解空间树。
对已处理的各结点根据限界函数估算目标函数的可能取值,从中选取使目标函数取得极值(极大/极小)的结点优先进行广度优先搜索 不断调整搜索方向,尽快找到解。
特点:限界函数常基于问题的目标函数,适用于求解最优化问题。
在分支限界法中,每一个活结点只有一次机会成为扩展结点。
活结点一旦成为扩展结点,就一次性产生其所有儿子结点。
在这些儿子结点中,导致不可行解或导致非最优解的儿子结点被舍弃,其余儿子结点被加入活结点表中。
此后,从活结点表中取下一结点成为当前扩展结点,并重复上述结点扩展过程。
这个过程一直持续到找到所需的解或活结点表为空时为止。
二.单源最短路径问题1.问题描述下面以一个例子来说明单源最短路径问题:在下图所给的有向图G 中,每一边都有一个非负边权。
要求图G的从源顶点s到目标顶点t 之间的最短路径。
下图是用优先队列式分支限界法解有向图G的单源最短路径问题产生的解空间树。
其中,每一个结点旁边的数字表示该结点所对应的当前路长。
2. 算法思想解单源最短路径问题的优先队列式分支限界法用一极小堆来存储活结点表。
其优先级是结点所对应的当前路长。
算法从图G的源顶点s和空优先队列开始。
结点s被扩展后,它的儿子结点被依次插入堆中。
此后,算法从堆中取出具有最小当前路长的结点作为当前扩展结点,并依次检查与当前扩展结点相邻的所有顶点。
如果从当前扩展结点i到顶点j有边可达,且从源出发,途经顶点i再到顶点j的所相应的路径的长度小于当前最优路径长度,则将该顶点作为活结点插入到活结点优先队列中。
这个结点的扩展过程一直继续到活结点优先队列为空时为止。
3. 剪枝策略在算法扩展结点的过程中,一旦发现一个结点的下界不小于当前找到的最短路长,则算法剪去以该结点为根的子树。
在算法中,利用结点间的控制关系进行剪枝。
从源顶点s出发,2条不同路径到达图G的同一顶点。
分支限界法求单源最短路径

分支限界法求单源最短路径分支限界法是一种求解最优化问题的算法,在图论中,可以用来求解单源最短路径。
本文将介绍分支限界法的基本原理和步骤,并通过一个具体的示例来说明其应用。
一、分支限界法简介分支限界法是一种穷举搜索算法,通过不断地将问题空间划分成更小的子问题,以寻找最优解。
它与传统的深度优先搜索算法相似,但在搜索过程中,通过引入上界(界限)来限制搜索范围,从而有效地剪枝和加速搜索过程。
分支限界法求解单源最短路径问题的基本思想是,首先将源点标记为已访问,然后以源点为根节点构建一棵搜索树,树中的每个节点表示当前访问的顶点,并记录到达该顶点的路径和权值。
通过遍历搜索树,逐步更新最短路径以及当前最优权值,从而找到最短路径。
二、分支限界法的步骤1. 创建搜索树:- 将源点标记为已访问,并将其作为根节点。
- 根据源点与其他顶点之间的边权值构建搜索树的第一层。
- 初始化当前最优路径和权值。
2. 遍历搜索树:- 从当前层中选择一个未访问的顶点作为扩展节点。
- 计算到达该扩展节点的路径和权值,并更新当前最优路径和权值。
- 根据已有的路径和权值,计算该扩展节点的上界,并与当前最优权值进行比较。
若上界小于当前最优权值,则进行剪枝操作,否则继续搜索。
- 将该扩展节点的子节点添加到搜索树中。
3. 更新最短路径:- 当搜索树的所有叶子节点都已遍历时,找到最短路径以及相应的权值。
三、示例分析为了更好地理解分支限界法的运行过程,我们将通过一个具体的示例来进行分析。
假设有一个有向带权图,其中包含5个顶点和6条边。
首先,我们需要构建初始搜索树,将源点A作为根节点。
根据源点与其他顶点之间的边权值,我们可以得到搜索树的第一层B(2)、C(3)、D(4)、E(5)。
接下来,我们从第一层选择一个未访问的顶点作为扩展节点。
假设选择节点B进行扩展。
此时,我们计算到达节点B的路径和权值,并更新当前最优路径和权值。
对于节点B,到达它的路径为AB,权值为2。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验四分支限界法实现单源最短路径
09电信实验班I09660118 徐振飞
一、实验名称
实现书本P194页所描述的单源最短路径问题
二、实验目的
(1)掌握并运用分支限界法基本思想
(2)运用分支限界法实现单源最短路径问题
(3)区分分支限界算法与回溯算法的区别,加深对分支限界法理解三、实验内容和原理
(1)实验原理
解单源最短路径问题的优先队列式分支限界法用一极小堆(本次实验我采用java.util包中的优先队列类PriorityQueue来实现)来存储活结点表。
其优先级是结点所对应的当前路长。
算法从图G的源顶点s和空优先队列开始。
结点s被扩展后,它的儿子结点被依次插入堆中。
此后,算法从堆中取出具有最小当前路长的结点作为当前扩展结点,并依次检查与当前扩展结点相邻的所有顶点。
如果从当前扩展结点i到顶点j有边可达,且从源出发,途经顶点i再到顶点j的所相应的路径的长度小于当前最优路径长度,则将该顶点作为活结点插入到活结点优先队列中。
这个结点的扩展过程一直继续到活结点优先队列为空时为止。
(2)实验内容测试用例:
1
2
3
4
5
6 3
4
2
7
6
13
9
5
四、源程序
import java.util.*;
public class ShortestPath
{
private int n;
private double matrix[][] = null;
private double minpath[];
public ShortestPath(int n)
{
this.n = n;
matrix = new double[n+1][n+1];
minpath = new double[n+1];
for(int i=1;i<=n;i++)
{
minpath[i] = Double.MAX_VALUE;
}
//初始化图
getGraphMatrix();
}
public void getGraphMatrix()
{
//初始化为不能连通
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
matrix[i][j] = Double.MAX_VALUE;
}
}
System.out.println("请输入边总数:");
Scanner scan = new Scanner(System.in);
int m = scan.nextInt();
System.out.println("依次输入两个顶点号(1~"+n+")和边长:例如 1 2 3");
for(int i=0;i<m;i++)
{
int a,b;
double d;
a = scan.nextInt();
b = scan.nextInt();
d = scan.nextDouble();
if(a<1 || b<1)
{
i--;
System.out.println("顶点号不能小于1");
continue;
}
if(a>n||b>n)
{
i--;
System.out.println("顶点号不能大于"+n);
continue;
}
matrix[a][b] = d;
}
}
/**
*@param求以第i个节点为起点的单源最短路径
*/
public void shortpath(int i)
{
minpath[i] = 0;
double curlen = 0;
PriorityQueue<Node> heap = new PriorityQueue();
Node cur = new Node(i,0);
heap.add(cur);
while(!heap.isEmpty())
{
for(int j=1;j<=n;j++)
{
if(matrix[cur.i][j]<Double.MAX_VALUE&& cur.len+matrix[cur.i][j]<minpath[j])
{
minpath[j] = cur.len+matrix[cur.i][j];
heap.add(new Node(j,minpath[j]));
}
}
cur = heap.poll();
}
//打印最短路径结果
System.out.println("最短路径:");
for(int j=1;j<=n;j++)
{
if(minpath[j]<Double.MAX_VALUE && j!=i)
{
System.out.println(i+"到"+j+":"+minpath[j]);
}
}
}
public static void main(String args [])
{
System.out.println("请输入定点总数:");
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
ShortestPath s = new ShortestPath(n); s.shortpath(1);
}
}
class Node implements Comparable<Node>
{
int i;
double len;
public Node(int i,double l)
{
this.i = i;
len = l;
}
public int compareTo(Node o)
{
double dif = len-o.len;
if(dif>0)
{
return 1;
}
else if(dif==0)
{
return 0;
}
else
{
return -1;
}
}
}
五、实验结果
输出结果分析:测试为上述测试用途,输出结果:1到2的最短路径为3,1到3的最短路径为2,1到4的最短路径为3,1到5的最短路径为7,1到6的最短路径为6。
输出结果正确。
六、实验心得和体会
通过实验,了解了分支限界法的基本思想。
知道了分支限界算法与回溯算法的区别。
由于本次实验利用java.util包下的PriorityQueue代替算法中最小堆,免去了编写实现最小堆的程序代码(但这并不表示我不会编写最小堆程序,在这次实验中,最小堆的实现并不是主要部分),所以本次实验实现的相对顺利。