贪心算法和分支限界法解决单源最短路径.docx
- 文档编号:3131676
- 上传时间:2022-11-17
- 格式:DOCX
- 页数:11
- 大小:19.52KB
贪心算法和分支限界法解决单源最短路径.docx
《贪心算法和分支限界法解决单源最短路径.docx》由会员分享,可在线阅读,更多相关《贪心算法和分支限界法解决单源最短路径.docx(11页珍藏版)》请在冰豆网上搜索。
贪心算法和分支限界法解决单源最短路径
单源最短路径
计科1班朱润华2012040732
方法1:
贪心算法
一、贪心算法解决单源最短路径问题描述:
单源最短路径描述:
给定带权有向图G=(V,E),其中每条边的权是非负实数。
另外,还给定V中的一个顶点,称之为源(origin)。
现在要计算从源到其他各顶点的最短路径的长度。
这里的路径长度指的是到达路径各边权值之和。
Dijkstra算法是解决单源最短路径问题的贪心算法。
Dijkstra算法的基本思想是:
设置顶点集合S并不断地做贪心选择来扩充集合。
一个顶点属于集合S当且仅当从源点到该顶点的最短路径长度已知。
贪心扩充就是不断在集合S中添加新的元素(顶点)。
初始时,集合S中仅含有源(origin)一个元素。
设curr是G的某个顶点,把从源到curr且中间只经过集合S中顶点的路称之为从源到顶点curr的特殊路径,并且使用数组distance记录当前每个顶点所对应的最短路径的长度。
Dijkstra算法每次从图G中的(V-S)的集合中选取具有最短路径的顶点curr,并将curr加入到集合S中,同时对数组distance进行必要的修改。
一旦S包含了所有的V中元素,distance数组就记录了从源(origin)到其他顶点的最短路径长度。
二、贪心算法思想步骤:
Dijkstra算法可描述如下,其中输入带权有向图是G=(V,E),V={1,2,…,n},顶点v是
源。
c是一个二维数组,c[i][j]表示边(i,j)的权。
当(i,j)不属于E时,c[i][j]是一个大数。
dist[i]表示当前从源到顶点i的最短特殊路径长度。
在Dijkstra算法中做贪心选择时,实际上是考虑当S添加u之后,可能出现一条到顶点的新的特殊路,如果这条新特殊路是先经过老的S
如果dist[u]+c[u][i] 步骤如下: 1、用带权的邻接矩阵c来表示带权有向图,c[i][j]表示弧 设S为已知最短路径的终点的集合,它的初始状态为空集。 从源点v经过S到图上其余各点vi的当前最短路径长度的初值为: dist[i]=c[v][i],vi属于V; 2、选择vu,使得dist[u]=Min{dist[i]|vi属于V-S},vj就是长度最短的最短路径的终点。 令S=SU{u}; 3、修改从v到集合V-S上任一顶点vi的当前最短路径长度: 如果dist[u]+c[u][j]< dist[j]则修改dist[j]=dist[u]+c[u][j]; 4、重复操作 (2),(3)共n-1次。 三、算法实现代码: #include #include #include #include usingnamespacestd; constintN=5; constintM=1000; ifstreamfin("4d5.txt"); template voidDijkstra(intn,intv,Typedist[],intprev[],Typec[][N+1]); voidTraceback(intv,inti,intprev[]);//输出最短路径v源点,i终点intmain() { intv=1;//源点为1 intdist[N+1],prev[N+1],c[N+1][N+1]; cout<<"有向图权的矩阵为: "< for(inti=1;i<=N;i++) { for(intj=1;j<=N;j++) { fin>>c[i][j]; cout< } cout< } Dijkstra(N,v,dist,prev,c); for(inti=2;i<=N;i++) { cout<<"源点1到点"< "< Traceback(1,i,prev); cout< } return0; } template voidDijkstra(intn,intv,Typedist[],intprev[],Typec[][N+1]) { bools[N+1]; for(inti=1;i<=n;i++) { dist[i]=c[v][i];//dist[i]表示当前从源到顶点i的最短特殊路径长度 s[i]=false; if(dist[i]==M) { prev[i]=0;//记录从源到顶点i的最短路径i的前一个顶点 else { prev[i]=v; } } dist[v]=0; s[v]=true; for(inti=1;i { inttemp=M; intu=v;//上一顶点 //取出V-S中具有最短特殊路径长度的顶点u for(intj=1;j<=n;j++) { if((! s[j])&&(dist[j] { u=j temp=dist[j]; } s[u]=true; //根据作出的贪心选择更新Dist值 for(intj=1;j<=n;j++) { if((! s[j])&&(c[u][j] { Typenewdist=dist[u]+c[u][j]; if(newdist { dist[j]=newdist; prev[j]=u; } } } } } //输出最短路径v源点,i终点voidTraceback(intv,inti,intprev[]) if(v==i) { cout< return; } Traceback(v,prev[i],prev); cout<<"->"< } 四、计算复杂性 对于一个具有n个顶点和e条边的带权有向图,如果用带权邻接矩阵表示这个图,那 么Dijkstra算法的主循环体需要O(n)时间。 这个循环需要执行n-1次,所以完成循环需要 0(nA2)时间。 算法的其余部分所需要的时间不超过0(n^2)。 五、运行结果: 间图权的矩阵为’ 1010S030100leaa 1B00 >4 - 为为为为苴八苴苴八苴八 0000 1536 为为为为丽庫<■度度0S8・ E0 0・ 1-日一一口里□兰口“一 00曰W-W-1-取续 10的的的暑2345^L至至至至化朋畫巔昴按原原冃 ・: 至至 11 1BB8 方法2: 分支限界法 一、分支限界法解决单源最短路径问题描述: 采用广度优先产生状态空间树的结点,并使用剪枝函数的方法称为分枝限界法。 所谓“分 支”是采用广度优先的策略,依次生成扩展结点的所有分支(即: 儿子结点)。 所谓“限界” 是在结点扩展过程中,计算结点的上界(或下界),边搜索边减掉搜索树的某些分支,从而 提高搜索效率 按照广度优先的原则,一个活结点一旦成为扩展结点(E-结点)R后,算法将依次生成 它的全部孩子结点,将那些导致不可行解或导致非最优解的儿子舍弃,其余儿子加入活结点 表中。 然后,从活结点表中取出一个结点作为当前扩展结点。 重复上述结点扩展过程,直至 找到问题的解或判定无解为止。 二、分支限界法算法思想描述: 算法从图G的源顶点s和空优先队列开始。 结点s被扩展后,它的儿子结点被依次插当前扩展结点相邻的所有顶点。 如果从当前扩展结点i到顶点j有边可达,且从源出发,途经顶点i再到顶点j的所相应的路径的长度小于当前最优路径长度,则将该顶点作为活结点插入到活结点优先队列中。 这个结点的扩展过程一直继续到活结点优先队列为空时为止。 在算法扩展结点的过程中,一旦发现一个结点的下界不小于当前找到的最短路长,则算法剪去以该结点为根的子树。 在算法中,利用结点间的控制关系进行剪枝。 从源顶点s出发,2条不同路径到达图G 的同一顶点。 由于两条路径的路长不同,因此可以将路长长的路径所对应的树中的结点为根的子树剪去。 三、算法实现代码: #include"stdafx.h" #include"MinHeap2.h" #include #include usingnamespacestd; ifstreamfin("6d2.txt"); template classGraph { friendintmain(); public: voidShortesPaths(int); private: int n, //图G的顶点数 *prev; //前驱顶点数组 Type **c, //图G的领接矩阵 *dist; //最短距离数组 }; template classMinHeapNode { friendGraph public: operatorint()const{returnlength;} private: inti;//顶点编号 Typelength;//当前路长 }; template voidGraph : ShortesPaths(intv)//单源最短路径问题的优先队列式分支限界法 MinHeap MinHeapNode //定义源为初始扩展节点 E.i=v; E.length=0; dist[v]=0; while(true)//搜索问题的解空间 { for(intj=1;j<=n;j++) if((c[E.i][j]! =0)&&(E.length+c[E.i][j] //顶点i到顶点j可达,且满足控制约束 dist[j]=E.length+c[E.i][j]; prev[j]=E.i; //加入活结点优先队列 MinHeapNode N.i=j; N.length=dist[j]; H.Insert(N); }' try { H.DeleteMin(E);//取下一扩展结点 } catch(int) { break; } if(H.currentsize==0)//优先队列空 { break; } } } intmain() { intn=11; intprev[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}; co
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 贪心 算法 分支 限界 解决 单源最短 路径