贪心算法初探3——最短路径(Dijkstra算法)

  问题描述:给定有向带权图G=(V,E),其中每条边的权是非负实数。此外,给定V中的一个顶点,称为源点。现在要计算从源点到所有其他各顶点的最短路径长度,这里路径长度指路上各边的权之和。

  算法设计:这个问题一般采用迪杰斯特拉算法(Dijkstra)算法思想是先求出长度最短的一条路径,再参照该最短路径求出长度次短的一条路径,直到求出从源点到其他各个顶点的最短路径。

  算法基本思想:先假定源点为u,顶点集合V被划分为两部分:集合V以及集合V-S。初始时S中仅含有u,其中S的顶点到源点的最短路径已经确定。集合V-S中华包含的顶点到源点的最短路径长度待定,称从源点出发只经过S中的点到V-S中点的路径为特殊路径,并用数组dict[]记录当前每个顶点所对应的最短特殊路径长度。

  贪心策略选择:选择特殊路径长度最短的路径,将其连接的V-S顶点加入到集合S中,同时更新数组dict[].一旦S包含了所有的顶点,dict[]就储存了从源到所有其他顶点之间的最短路径长度。

  算法详情:

  1:设置地图带权邻接矩阵为map[][],如果从源点u到顶点i有边,就map[u][i]等于<u,i>的权值,否则map[u][i]=∞;使用一维数组dict[i]记录从源点到i顶点的最短路径长度;使用一维数组p[i]记录最短路径上i顶点的前驱。

  2:设置一个集合S={u},对于集合V-S中所有顶点x,初始化dist[i]=map[u][i],如果u与i有边项链,初始化p[i]=u,否则p[i]=-1。

  3:在集合V-S中依照贪心策略寻找使得dist[j]具有最小值的的顶点t,即dist[t]=min(dist[j]j属于V-S),则顶点t就是集合V-S中距离源点u最近的顶点。

  4:将t加入S中,同时更新V-S。

  5:如果集合V-S已经为空,算法结束,否则转入第6步。

  6:在第三步中已经找到了源点到t的最短路径,那么对于集合V-S中所有与顶点t相邻的顶点j都可以通过t走捷径。如果dist[j]>dist[t]+map[t][j],则dist[j]=dist[t]+map[t][j],同时记录顶点j的前驱为t,有p[j]=t,转入第3步。

  由此,可以求得源点u到图G的其余各个顶点的最短路径及长度,也可以通过数组p[]逆向找到最短路径上经过的地点。

  算法实现:

  

 1 private static final int MAX_Number=1000000;//定义静态常量用于表示无穷大
 2 public int[] Solution4(int u){
 3             int[][] ints=new int[][]{{MAX_Number,2,5,MAX_Number,MAX_Number},
 4                                 {MAX_Number,MAX_Number,2,6,MAX_Number,},
 5                                 {MAX_Number,MAX_Number,MAX_Number,7,1},
 6                                 {MAX_Number,MAX_Number,2,MAX_Number,4},
 7                                 {MAX_Number,MAX_Number,MAX_Number,MAX_Number,MAX_Number}};//初始邻接矩阵,选择点1作为源点。
 8             int[] dist=new int[]{0,2,5,MAX_Number,MAX_Number};//记录源点到i顶点的最短路径长度
 9             int[] p=new int[]{-1,1,1,-1,-1};//记录前驱顶点
10             boolean[] S=new boolean[]{true,false,false,false,false};//如果i顶点已经加入S,S[i]的值会是true,否则就是false
11             for (int j=1;j<dist.length;j++){
12                 int temp=MAX_Number;//中间变量
13                 int t=u;
14                 for(int i=0;i<dist.length;i++){
15                     if(!S[i] && dist[i]<temp){
16                         t=i+1;
17                         temp=dist[i];
18                     }
19                     if(i==dist.length-1){
20                         if(t!=u){
21                             S[t-1]=true;
22                         }
23                     }
24                 }
25                 for(int k=0;k<dist.length;k++){
26                     if(!S[k]&&dist[k]>dist[t-1]+ints[t-1][k]){
27                         dist[k]=dist[t-1]+ints[t-1][k];
28                         p[k]=t;
29                     }
30                 } }
31             return dist;
32     }//单源最短路径(Dijkstra)

  返回值[0,2,4,8,5],时间复杂度O(n2)> 

  可以再尝试使用栈来获取每次更新dict数组时的路径,最终也返回源点到每个点的最短路径。之后会继续加上最短路径并且优化算法使时间复杂度降至O(logn)。

  (我为什么这么菜,为什么这么菜)

原文地址:https://www.cnblogs.com/jason-Ralston/p/11944877.html

时间: 2024-10-28 10:34:08

贪心算法初探3——最短路径(Dijkstra算法)的相关文章

数据结构:单源最短路径--Dijkstra算法

Dijkstra算法 单源最短路径 给定一带权图,图中每条边的权值是非负的,代表着两顶点之间的距离.指定图中的一顶点为源点,找出源点到其它顶点的最短路径和其长度的问题,即是单源最短路径问题. Dijkstra算法 求解单源最短路径问题的常用方法是Dijkstra(迪杰斯特拉)算法.该算法使用的是贪心策略:每次都找出剩余顶点中与源点距离最近的一个顶点. 算法思想 带权图G=<V,E>,令S为已确定了最短路径顶点的集合,则可用V-S表示剩余未确定最短路径顶点的集合.假设V0是源点,则初始 S={V

有向网络(带权的有向图)的最短路径Dijkstra算法

什么是最短路径? 单源最短路径(所谓单源最短路径就是只指定一个顶点,最短路径是指其他顶点和这个顶点之间的路径的权值的最小值) 什么是最短路径问题? 给定一带权图,图中每条边的权值是非负的,代表着两顶点之间的距离.指定图中的一顶点为源点,找出源点到其它顶点的最短路径和其长度的问题,即是单源最短路径问题. 什么是Dijkstra算法? 求解单源最短路径问题的常用方法是Dijkstra(迪杰斯特拉)算法.该算法使用的是贪心策略:每次都找出剩余顶点中与源点距离最近的一个顶点. 算法思想 带权图G=<V,

图的最短路径-----------Dijkstra算法详解(TjuOj2870_The Kth City)

做OJ需要用到搜索最短路径的题,于是整理了一下关于图的搜索算法: 图的搜索大致有三种比较常用的算法: 迪杰斯特拉算法(Dijkstra算法) 弗洛伊德算法(Floyd算法) SPFA算法 Dijkstra算法使用了广度优先搜索解决赋权有向图或者无向图的单源最短路径问题,算法最终得到一个最短路径树. 算法的思路: Dijkstra算法采用的是一种贪心的策略,声明一个数组dis来保存源点到各个顶点的最短距离和一个保存已经找到了最短路径的顶点的集合:T,初始时,原点 s 的路径权重被赋为 0 (dis

最短路径——dijkstra算法(Java)

在刷题的过程中常常会遇到求最短路径的问题,在求无权图的问题中我们常常使用BFS来求其最短路径,而BFS无法解决网(有权图)中的问题,我们解决网中的最短路径常常使用dijkstra算法来求解. dijkstra算法是一种贪心的思想,具体其正确性的证明,这里就不再赘述.下面来直接讲解如何使用dijkstra算法: 1.我们在使用dijkstra算法时为了其编写的便捷性一般使用邻接矩阵来描述一个图.并将邻接矩阵中每个元素的值初始化为无穷大(或者很大很大的值).之后根据图中的结构加入数字,称这个矩阵为E

最短路径-Dijkstra算法与Floyd算法

一.最短路径 ①在非网图中,最短路径是指两顶点之间经历的边数最少的路径. AE:1    ADE:2   ADCE:3   ABCE:3 ②在网图中,最短路径是指两顶点之间经历的边上权值之和最短的路径. AE:100   ADE:90   ADCE:60   ABCE:70 ③单源点最短路径问题 问题描述:给定带权有向图G=(V, E)和源点v∈V,求从v到G中其余各顶点的最短路径. 应用实例--计算机网络传输的问题:怎样找到一种最经济的方式,从一台计算机向网上所有其它计算机发送一条消息. ④每

单源最短路径Dijkstra算法

1.单源最短路径 函数:返回还未被收录顶点中dist最小者 1 Vertex FindMinDist(MGraph Graph, int dist[], int collected[]) 2 { 3 /*返回未被收录顶点中dist最小者*/ 4 Vertex MinV, V; 5 int MinDist = INFINITY; 6 7 8 for (V = 0; V < Graph->Nv; ++V) 9 { 10 if (collected[V] == false && di

算法导论——最短路径Dijkstra算法

package org.loda.graph; import org.loda.structure.IndexMinQ; import org.loda.structure.Stack; import org.loda.util.In; /** * * @ClassName: Dijkstra * @Description: Dijkstra最短路径算法--贪心算法 * @author minjun * @date 2015年5月27日 下午4:49:27 * */ public class D

(转)图算法单源最短路径Dijkstra算法(邻接表/邻接矩阵+优先队列STL)

一.前言 最短路径算法,顾名思义就是求解某点到某点的最短的距离.消耗.费用等等,有各种各样的描述,在地图上看,可以说是图上一个地点到达另外一个地点的最短的距离.比方说,我们把地图上的每一个城市想象成一个点,从一个城市到另一个城市的花费是不一样的.现在我们要从上海去往北京,需要考虑的是找到一条路线,使得从上海到北京的花费最小.有人可能首先会想到,飞机直达啊,这当然是时间消耗最小的方法,但是考虑到费用的高昂,这条线路甚至还不如上海到北京的高铁可取.更有甚者,假设国家开通了从上海到西藏,再从西藏到兰州

数据结构与算法——最短路径Dijkstra算法的C++实现

之前的讨论了无权图的最短路径算法.数据结构与算法--无权最短路径算法的C++实现 如果是加权图,那么问题就变得困难了,不过仍然可以采用无权情况的想法. 我们仍然保留之前的信息.因此,每个顶点会被标记为known或unknown,每个顶点保留一个尝试性的距离dv(这个距离是只使用一些known顶点作为中间顶点从s到v的最短路径的长),每个顶点还保留字段pv,该字段是记录引起dv变化的最后的顶点. 图顶点信息的数据结构: //保存每个顶点信息的数据结构 struct GraphNode{ bool