(前几天并多少时间,现在补充一下!)下面是原始的dijkstra算法:
public static void dijkstra(int v,float[][] a, flaot[] dist,int[] prev)
{
int n=dist.length-1;
if(v<1||v>n)return;
boolean[] s = new boolean[n+1];
//此处的循环是初始化
for(int i=1; i<=n; i++)
{
dis[i]=a[v][i];
s[i]= false;
if(dist[i]==Float.MAX_VALUE)prev[i]=0;
else prev[i]=v;
}
//此处开始遍历
dist[v]=0; s[v]=true;
//该循环是求的所有节点到源节点的路径,每循环一次求的一个节点到源节点的距离
for(int i=1; i<n; i++)
{
float temp = Float.MAX_VALUE;
int u=v;
//shortestPath(此处取该循环为shortestPath)
for(int j=1; j<n; j++)
{
if((!s[j])&&(dist[j]<temp))
{
u=j;
temp=dist[j];
}
}
s[u]=true;
//updateDist(取名为updateDist)
for(int j=1; j<n; j++)
{
if((!s[j])&&(a[u][j]<Float.MAX.VALUE))
{
float newdist = dist[u]+a[u][j];
if(newdist<dist[j])
{
dist[j]=newdist;
prev[j]=u;
}
}
}
}
}
以前看过Dijkstra算法,但是一直没有深入的研究它!最近由于项目的需要,所以今天研究了一下!下面介绍一下这个算法几个重要的几点!
其实这个算法有两个比较重要的地方!在书上开始有一个循环,是对参数初始化。这个就没必要研究了!主要的是第二个循环里面的两个循环,第二个循环要进行n-1次(也就是循环节点个数减去源节点),这就是要取得其他节点到源节点的距离,一次循环就是取得一个节点到源节点的距离。那么在第二个循环里面的第一个循环(这里叫该循环为shortestPath)就是取得当前能够到达源节点最短的节点,并且该节点是未被访问过的节点。取得在未被访问的节点里面到源节点最短路径的节点u后,最一个循环就是修改和u节点相连的节点到源节点的距离(这里称该循环为updateDist),我这里称这一步为更新u的邻接节点到源节点的距离。再回到shortestPath循环,就有可能取到u的邻接节点。下面我谈谈对这个算法的改进。
我们知道在shortestPath循环中,在书上的源码都是要遍历图中所有的节点,这样我觉得存在极大的浪费,我们知道该步是取得在dis数组中到源节点最短的节点,并且该节点是未被访问过的,所以这里根本没必要遍历图中所有的节点,只需遍历dis数组中的节点,而且我们知道dist的新的距离都是通过updateDist循环得到的,所以我们完全可以将dist数组里的距离存储到一个集合中,我们可以自定义一个集合,当我们每次想该集合添加元素(也就是到源节点的距离)的时候自动对该集合中进行排序,进行递增排序,我们取该集合的第一个元素就是当前到源节点最短的节点,并且该节点是未被访问的,取出时并将该节点从该集合中移出。这样我们就省掉了shortestPath这个循环了,这样对算法的运行将有极大的提高!还有就是后面的updateDist循环,在书上的源码中也是对图中的所有节点进行遍历,其实也没必要,只需对u的领结节点遍历即使!这样有省掉了没必要的循环,这样的Dijkstra算法,我相信应该不会很慢!
注意的是这种优化也需要对你的图结构进行优化,具体的优化可以见本博客的《新颖的图存储结构【看来之后你会对图的结构有新的想法】》文章,里面有详细讲解一种图的存储结构!
下面贴出我改进的算法:
public class ShortestPathIterator_3 {
private Graph graph;
private boolean visited[];
private int prev[];
private int source;
private int position;
private float pathCost[];
private int n;
private Map<Integer,Float> visitable;
//获得当前的源节点
public int getSource()
{
return this.source;
}
public ShortestPathIterator_3(Graph graph,int source)
{
visited = new boolean[graph.getNode_Count()];
this.visitable = new HashMap<Integer,Float>();
prev = new int[graph.getNode_Count()];
this.graph = graph;
this.source = source;
this.pathCost = new float[this.graph.getNode_Count()];
for(int i=0; i<graph.getNode_Count(); i++)
{
this.pathCost[i]=Float.MAX_VALUE;
this.visited[i]=false;
}
EdgeIterator edgeIterator = graph.getEdgeIterator(this.source);//获得所有和元节点相邻的节点集合
int adjancentNode;
while(edgeIterator.hasNext())
{
adjancentNode = this.graph.getAdjancentNode(edgeIterator.next());
this.pathCost[adjancentNode] = this.graph.getEdgePrestige(edgeIterator.next());
this.visitable.put(adjancentNode, this.graph.getEdgePrestige(edgeIterator.next()));
this.prev[adjancentNode] = this.source;
}
this.visited[this.source]=true;
this.position=0;
this.n=this.graph.getNode_Count()-1;
}
public int getNext()
{
Integer u = this.source;
if(this.position<=this.n-1)
{
float temp = Float.MAX_VALUE;
Iterator<Integer> keyIterator = this.visitable.keySet().iterator();
int next;
//取得未被访问并且,到源点最短的节点,并赋值给U,同时将和U相连的节点到源点的距离进行更新
while(keyIterator.hasNext())
{
next= keyIterator.next();
if(this.visitable.get(next)<temp)
{
u=next;
temp = this.visitable.get(next);
}
}
this.visited[u]=true;
//更新和u相连的节点到源点的距离
updatePathCost(u);
this.visitable.remove(u);
this.position++;
return u;
}
else
{
return -1;
}
}
public void updatePathCost(int u)
{
float newPathCost;
EdgeIterator edgeIterator = this.graph.getEdgeIterator(u);//获得所有和u节点相邻的节点集合
int adjancentNode;
while(edgeIterator.hasNext())
{
adjancentNode = this.graph.getAdjancentNode(edgeIterator.next());
//将还未被访问的节点进行判断到源点的距离
if(!this.visited[adjancentNode])
{
newPathCost = this.getPathCost(u)+this.graph.getEdgePrestige(this.graph.getEdgeId(adjancentNode, u));
if(newPathCost<this.getPathCost(adjancentNode))
{
this.visitable.put(new Integer(adjancentNode), newPathCost);
this.pathCost[adjancentNode] = newPathCost;
this.prev[adjancentNode]=u;
}
}
}
}
public float getPathCost(int node)
{
return this.pathCost[node];
}
public int getPrevNode(int node)
{
return this.prev[node];
}
}
这个优化我已经实现了!需要深入探讨的可以和我联系。希望能够帮助和我以前一样的人!谢谢浏览!
分享到:
相关推荐
代码 基于最短路dijkstra算法离散优化问题代码代码 基于最短路dijkstra算法离散优化问题代码代码 基于最短路dijkstra算法离散优化问题代码代码 基于最短路dijkstra算法离散优化问题代码代码 基于最短路dijkstra算法...
毕业设计:最短路径算法实现,Dijkstra算法,双向Dijkstra算法,CH算法,SILC算法 毕业设计:最短路径算法实现,Dijkstra算法,双向Dijkstra算法,CH算法,SILC算法 毕业设计:最短路径算法实现,Dijkstra算法,双向...
已知有 V 中有顶点 s 及 t,Dijkstra 算法可以找到 s 到 t的最低权重路径(例如,最短路径)。这个算法也可以在一个图中,找到从一个顶点 s 到任何其他顶点的最短路径。对于不含负权的有向图,Dijkstra算法是目前已知...
dijkstra算法C++实现的程序代码
Dijkstra算法算是贪⼼思想实现的,⾸先把起点到所有点的距离存下来找个最短的,然后松弛⼀次再找出最短的,所谓的松弛操作就是,遍历⼀遍看通过刚刚找到的距离最短的点作为中转站会不会更近,如果更近了就更新距离,...
毕设项目:基于springboot+mysql+Dijkstra算法实现物流优化管理系统.zip主要针对计算机相关专业的正在做课程设计和期末大作业的学生和需要项目实战练习的学习者。包含全部项目源码、该项目可以直接使用、项目都经过...
Dijkstra算法应用举例 Dijkstra算法应用举例Dijkstra算法应用举例 Dijkstra算法应用举例
MATLAB源码集锦-基于最短路dijkstra算法离散优化问题代码
本程序使用C语言实现了Dijkstra算法。程序中,定义好邻接矩阵,可以计算出任一节点到其他所有节点的最短路径,并打印路径与长度。其中对最短路径的存储是依据所得到的生成树,可以减少内存空间占用。
最短路径分析Dijkstra算法的优化实现,徐辛超,,最短路径问题是地理信息系统的关键问题,传统Dijkstra算法在求解节点间最短路径时,对已标识节点以外的大量节点进行了计算,从而影�
Dijkstra算法的应用, Dijkstra算法的应用 Dijkstra算法的应用 Dijkstra算法的应用 Dijkstra算法的应用 Dijkstra算法的应用 Dijkstra算法的应用
传统Dijkstra算法在求解节点间最短... 在对传统Dijkstra算法分析的基础上, 对其进行了优化,优化算法只对最短路径上节点的邻居做了处理,而 不涉及到其他节点. 因此,在优化算法中计算的节点数大幅减少,提高了算法的速度.
对传统Dijkstra算法进行分析,明确优化方向,再利用OpenMP开发工具对并行程序进行优化调试。结果表明,文中算法易于操作,并充分利用了多核处理器并行计算的优势,提高了算法的运行效率,验证了算法的优越性。
最短路径Dijkstra算法-最短路Dijkstra算法.rar 最短路径Dijkstra算法
Dijkstra算法,Dijkstra算法详细讲解,Dijkstra算法详细讲解
能够实现 Dijkstra算法,内涵代码,运行即可实现
Dijkstra算法程序的优化.pdf
Dijkstra算法的Matlab程序,用于求各点之间的最短路距离。该程序解决了一个有九个点的无向图中求任意两点之间最短路距离的例子。程序中的每一步都有详细说明。
Dijkstra算法演示flash 一看就会Dijkstra算法~~
基于Dijkstra算法的路径规划算法,matlab代码