导航:首页 > 源码编译 > a算法csdn

a算法csdn

发布时间:2025-02-07 01:30:10

A. 图遍历算法之最短路径Dijkstra算法

最短路径问题是图论研究中一个经典算法问题,旨在寻找图中两节点或单个节点到其他节点之间的最短路径。根据问题的不同,算法的具体形式包括:

常用的最短路径算法包括:Dijkstra算法,A 算法,Bellman-Ford算法,SPFA算法(Bellman-Ford算法的改进版本),Floyd-Warshall算法,Johnson算法以及Bi-direction BFS算法。本文将重点介绍Dijkstra算法的原理以及实现。

Dijkstra算法,翻译作戴克斯特拉算法或迪杰斯特拉算法,于1956年由荷兰计算机科学家艾兹赫尔.戴克斯特拉提出,用于解决赋权有向图的 单源最短路径问题 。所谓单源最短路径问题是指确定起点,寻找该节点到图中任意节点的最短路径,算法可用于寻找两个城市中的最短路径或是解决着名的旅行商问题。

问题描述 :在无向图 中, 为图节点的集合, 为节点之间连线边的集合。假设每条边 的权重为 ,找到由顶点 到其余各个节点的最短路径(单源最短路径)。

为带权无向图,图中顶点 分为两组,第一组为已求出最短路径的顶点集合(用 表示)。初始时 只有源点,当求得一条最短路径时,便将新增顶点添加进 ,直到所有顶点加入 中,算法结束。第二组为未确定最短路径顶点集合(用 表示),随着 中顶点增加, 中顶点逐渐减少。

以下图为例,对Dijkstra算法的工作流程进行演示(以顶点 为起点):

注:
01) 是已计算出最短路径的顶点集合;
02) 是未计算出最短路径的顶点集合;
03) 表示顶点 到顶点 的最短距离为3
第1步 :选取顶点 添加进


第2步 :选取顶点 添加进 ,更新 中顶点最短距离




第3步 :选取顶点 添加进 ,更新 中顶点最短距离




第4步 :选取顶点 添加进 ,更新 中顶点最短距离





第5步 :选取顶点 添加进 ,更新 中顶点最短距离



第6步 :选取顶点 添加进 ,更新 中顶点最短距离



第7步 :选取顶点 添加进 ,更新 中顶点最短距离

示例:node编号1-7分别代表A,B,C,D,E,F,G

(s.paths <- shortest.paths(g, algorithm = "dijkstra"))输出结果:

(s.paths <- shortest.paths(g,4, algorithm = "dijkstra"))输出结果:

示例:

找到D(4)到G(7)的最短路径:

[1] 维基网络,最短路径问题: https://zh.wikipedia.org/wiki/%E6%9C%80%E7%9F%AD%E8%B7%AF%E9%97%AE%E9%A2%98 ;
[2]CSDN,Dijkstra算法原理: https://blog.csdn.net/yalishadaa/article/details/55827681 ;
[3]RDocumentation: https://www.rdocumentation.org/packages/RNeo4j/versions/1.6.4/topics/dijkstra ;
[4]RDocumentation: https://www.rdocumentation.org/packages/igraph/versions/0.1.1/topics/shortest.paths ;
[5]Pypi: https://pypi.org/project/Dijkstar/

B. Dijkstra算法

Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。注意该算法要求图中不存在负权边。

设G=(V,E)是一个带权有向图,把图中顶点集合V分成两组,第一组为已求出最短路径的顶点集合(用S表示,初始时S中只有一个源点,以后每求得一条最短路径 , 就将加入到集合S中,直到全部顶点都加入到S中,算法就结束了),第二组为其余未确定最短路径的顶点集合(用U表示),按最短路径长度的递增次序依次把第二组的顶点加入S中。在加入的过程中,总保持从源点v到S中各顶点的最短路径长度不大于从源点v到U中任何顶点的最短路径长度含侍仿。此外,每个顶点对应一个距离,S中的顶点的距离就是从v到此顶点的最短路径长度,U中的顶点的距离,是从v到此顶点只包括S中的顶点为中间顶点的当前最短路径长度。

(1)初始时,S只包含起点D;U包含除D外的其他顶点,且U中顶点的距离为“起点D到该顶点的距离”(例如,U中顶点A的距离为[D,A]的长度,然后D和A不相邻,则谈枣A的距离为∞)
(2)从U中选出“距离最短的顶点K”,并将顶点K加入到S中;同时,从U中移除顶点K
(3)更新U中各个顶点到起点D的距离。之所以更新U中顶点的距离,是由于上一步谈纤中确定了K是求出最短路径的顶点,从而可以利用K来更新其他顶点到起点D的距离(例如,[D,A]的距离可能大于[D,K]+[K,A]的距离)
(4)重复步骤(2)和(3),直到遍历完所有顶点

https://blog.csdn.net/yalishadaa/article/details/55827681

C. Ackerman函数的动态规范算法

试设计一个计算A(m,n)的动态规划算法,该算法只占用O(m)空间。

用两个一维数组,ind[i]和val[i],使得当ind[i]等于t时,val[i]=A(i,ind[i])。
i ind[i] val[i]
0 0 1
1 -1 0
2 -1 0
……
初始时,令ind[0]=0,val[0]=1,ind[i]=-1(i>0),val[i]=0(i>0)。
1当m=0时,A(m,n)=n+1。
任给一个t,当ind[0]=t时,能够求出val[0]的值,val[0]等于ind[0]。
2当n=0,m>0时,A(m,n)=n+1。
能够求出当ind[i]=0时,val[i]的值,此时val[i]等于当ind[i-1]等于1时val[i-1]的值。
3当m>0,n>0时,A(m,n)=A(m-1,A(m,n-1))。
当ind[i]=t,val[i]=s时,要求当ind[i]’=t+1时val[i]’的值。
Val[i]’=A(i,ind[i]’)=A(i-1,A(i,ind[i]’-1)=A(i-1,A(i,ind[i]))=A(i-1,val[i])
所以,当ind[i-1]=val[i]时,能够求出当ind[i]’=k+1时,val[i]’=val[i-1]。

#include <stdio.h>
int ack(int& m,int& n)
{
int i,j;
int *val=new int[m+1];
int *ind=new int[m+1];
for(i=1;i<=m;i++)
{
ind[i]=-1;
val[i]=-1;
}
ind[0]=0;
val[0]=1;
while(ind[m]<n)
{
val[0]++;
ind[0]++;
printf("%d ",val[0]);
for(j=1;j<=m;j++)
{
if(1==ind[j-1])
{
val[j]=val[j-1];
ind[j]=0;
}
if(val[j]!=ind[j-1])
break;
ind[j]++;
val[j]=val[j-1];
}
}
printf("\n");
printf(" i ind[i] val[i]\n");
for(i=0;i<=m;i++)
printf("%5d %6d %6d\n",i,ind[i],val[i]);
return val[m];
}

D. A*算法(启发式算法)

A*算法
这是我写的第一篇有关A*算法的文章,写得比较简洁,我决定再写一篇,补充一下对A*算法的理解。

A*算法把 Dijkstra算法 (靠近初始点的结点)和 BFS算法 (靠近目标点的结点)的信息块结合起来。
g(n)表示从初始结点到任意结点n的实际代价
h(n)表示从结点n到目标点的启发式评估代价

(1)h(n)=0,一种极端情况
如果h(n)=0,则只有g(n)起作用,此时A*演变成Dijkstra算法,这保证能找到最短路径,但效率不到,因为得不到启发。
(2)h(n)<实际代价
如果h(n)经常都比从n移动到目标的实际代价小(或者相等),则A*保证能找到一条最短路径。h(n)越小,A*扩展的结点越多,运行就越慢。
(3)h(n)=实际代价
如果h(n)精确地等于从n移动到目标的实际代价,则A*将会仅仅寻找最佳路径而不扩展别的任何结点,这会运行得非常快。尽管这不可能在所有情况下发生,你仍可以在一些特殊情况下让它们精确地相等(指让h(n)精确地等于实际代价)。只要提供完美的信息,A*就会运行得很完美。
(4)h(n)>实际代价
如果h(n)有时比从n移动到目标的实际代价大,则A*不能保证找到一条最短路径,但它运行得更快。
(5)h(n)>>实际代价(>>远大于),另一种极端情况
如果h(n)比g(n)大很多,则只有h(n)起作用,A*演变成BFS算法。

数组?链表?
在Open集上主要有三种操作:查找优先级最高的结点&删除结点、查找相邻结点是否在集合中、插入新结点
在Close集上主要有两种操作:查找相邻结点是否在集合中、插入新节点
(1)未排序数组或链表
最简单的数据结构是未排序数组或链表。查找结点,花费O(N);插入结点,花费O(1);删除结点,花费O(N)
(2)排序数组
为了加快删除操作,可以对数组进行排序。查找结点,变成O(logN),因为可以使用折半查找;插入结点,花费O(N);查找和删除优先级最高的结点,花费O(1)
(3)排序链表
在排序数组中,插入操作很慢。如果使用链表则可以加速该操作。查找结点,花费O(N);插入结点,花费O(1),但查找插入位置,需要花费O(N)
(4)哈希表
使用哈希表,查找结点,花费O(1);插入结点,花费O(1);查找和删除优先级最高的结点,花费O(N)

https://blog.csdn.net/coutamg/article/details/53923717#!/_alzvzu0wsphb4nstr5bbro1or

阅读全文

与a算法csdn相关的资料

热点内容
基本初等函数的导数公式及导数的运算法则 浏览:915
为什么小米app启动广告关不了 浏览:877
空调压缩机一直不停 浏览:511
养殖系统开发源码 浏览:82
pdf的目录 浏览:406
光遇安卓如何一个人拍视频 浏览:277
怨女pdf 浏览:708
扭曲服务器什么时候开 浏览:23
加密货币换平台 浏览:609
手机内存压缩软件 浏览:33
生成树是否与遍历算法有关 浏览:728
python强化学习迷宫 浏览:450
老包子解压视频 浏览:885
服务器注册是什么意思 浏览:418
程序员群体焦虑如何破局 浏览:585
程序员在广州上班 浏览:803
androidlinuxadt 浏览:512
广联达软件加密锁原装芯片 浏览:338
如何打开数据库服务器 浏览:310
kppm是什么app 浏览:538