贪心算法和分支限界法解决单源最短路径Word格式.docx

上传人:b****4 文档编号:16042607 上传时间:2022-11-17 格式:DOCX 页数:11 大小:19.52KB
下载 相关 举报
贪心算法和分支限界法解决单源最短路径Word格式.docx_第1页
第1页 / 共11页
贪心算法和分支限界法解决单源最短路径Word格式.docx_第2页
第2页 / 共11页
贪心算法和分支限界法解决单源最短路径Word格式.docx_第3页
第3页 / 共11页
贪心算法和分支限界法解决单源最短路径Word格式.docx_第4页
第4页 / 共11页
贪心算法和分支限界法解决单源最短路径Word格式.docx_第5页
第5页 / 共11页
点击查看更多>>
下载资源
资源描述

贪心算法和分支限界法解决单源最短路径Word格式.docx

《贪心算法和分支限界法解决单源最短路径Word格式.docx》由会员分享,可在线阅读,更多相关《贪心算法和分支限界法解决单源最短路径Word格式.docx(11页珍藏版)》请在冰豆网上搜索。

贪心算法和分支限界法解决单源最短路径Word格式.docx

dist[i]表示当前从源到顶点i的最短特殊路径长度。

在Dijkstra算法中做贪心选择时,实际上是考虑当S添加u之后,可能出现一条到顶点的新的特殊路,如果这条新特殊路是先经过老的S

如果dist[u]+c[u][i]<

dist[i],则需要更新dist[i]的值。

步骤如下:

1、用带权的邻接矩阵c来表示带权有向图,c[i][j]表示弧<

vi,vj>

上的权值。

设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<

stdafx.h>

iostream>

fstream>

string>

usingnamespacestd;

constintN=5;

constintM=1000;

ifstreamfin("

4d5.txt"

);

template<

classType>

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<

<

"

有向图权的矩阵为:

"

endl;

for(inti=1;

i<

=N;

i++)

for(intj=1;

j<

j++)

fin>

>

c[i][j];

c[i][j]<

;

}

Dijkstra(N,v,dist,prev,c);

for(inti=2;

源点1到点"

i<

的最短路径长度为:

dist[i]<

,其路径为"

Traceback(1,i,prev);

return0;

voidDijkstra(intn,intv,Typedist[],intprev[],Typec[][N+1])

bools[N+1];

=n;

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;

n;

inttemp=M;

intu=v;

//上一顶点

//取出V-S中具有最短特殊路径长度的顶点u

if((!

s[j])&

&

(dist[j]<

temp))

u=j

temp=dist[j];

s[u]=true;

//根据作出的贪心选择更新Dist值

(c[u][j]<

M))

Typenewdist=dist[u]+c[u][j];

if(newdist<

dist[j])

dist[j]=newdist;

prev[j]=u;

//输出最短路径v源点,i终点voidTraceback(intv,inti,intprev[])

if(v==i)

i;

return;

Traceback(v,prev[i],prev);

->

I;

四、计算复杂性

对于一个具有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"

MinHeap2.h"

6d2.txt"

classGraph

friendintmain();

public:

voidShortesPaths(int);

private:

int

n,

//图G的顶点数

*prev;

//前驱顶点数组

Type

**c,

//图G的领接矩阵

*dist;

//最短距离数组

};

classMinHeapNode

friendGraph<

Type>

operatorint()const{returnlength;

inti;

//顶点编号

Typelength;

//当前路长

voidGraph<

:

ShortesPaths(intv)//单源最短路径问题的优先队列式分支限界法

MinHeap<

MinHeapNode<

H(1000);

E;

//定义源为初始扩展节点

E.i=v;

E.length=0;

dist[v]=0;

while(true)//搜索问题的解空间

for(intj=1;

j<

=n;

if((c[E.i][j]!

=0)&

(E.length+c[E.i][j]<

dist[j])){

//顶点i到顶点j可达,且满足控制约束

dist[j]=E.length+c[E.i][j];

prev[j]=E.i;

//加入活结点优先队列

N;

N.i=j;

N.length=dist[j];

H.Insert(N);

}'

try

H.DeleteMin(E);

//取下一扩展结点

catch(int)

break;

if(H.currentsize==0)//优先队列空

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

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 农林牧渔 > 林学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1