单源最短路径 贪心算法 JAVA实现

合集下载

Java实现单源最短路径算法(Dijkstra算法)

Java实现单源最短路径算法(Dijkstra算法)

Java实现单源最短路径算法(Dijkstra算法)参考:《算法导论》@Data@AllArgsConstructorpublic class WeightGraph {//节点名,前驱节点,最短路径private List<Node<String,String,Integer>> nodes;//节点名,连接节点索引,边权重private Table<String, Integer, Integer> edgeTable;public static void main(String[] args) {//构建图WeightGraph graph = buildGraph();List<Node<String, String, Integer>> nodes = graph.getNodes();Table<String, Integer, Integer> edgeTable = graph.getEdgeTable();//已知最短路径的节点集合SHashSet<String> S = new HashSet<>();//优先队列,以最短路径为排序keyQueue<Node<String,String, Integer>> queue = new PriorityQueue<>(paring(Node::getDistance));//节点信息的初始化,v1=0,其他未知都是⽆穷⼤nodes.forEach(node->{if (node.getName().equals("v1")) {node.setDistance(0);}});//队列初始化,将所有节点加⼊队列queue.addAll(nodes);while (!queue.isEmpty()) {//第⼀个获取的就是v1Node<String,String, Integer> nodeU = queue.remove();String nodeUName = nodeU.getName();S.add(nodeUName);Map<Integer, Integer> row = edgeTable.row(nodeUName);//对u->v节点进⾏松弛操作//如果v.d⼤于u.d+w(u,v),则将更⼩的值更新为v.dfor (Map.Entry<Integer, Integer> entry : row.entrySet()) {Integer nodeVIndex = entry.getKey();Node<String, String, Integer> nodeV = nodes.get(nodeVIndex);Integer weightUV = entry.getValue();if (nodeV.getDistance() > nodeU.getDistance() + weightUV) {nodeV.setDistance(nodeU.getDistance() + weightUV);nodeV.setPre(nodeUName);}}}for (Node<String, String, Integer> node : nodes) {System.out.println(node.getName()+":"+node.getDistance());}System.out.println(S);}/*** 初始化图结构** @return*/public static WeightGraph buildGraph() {List<String> nodes = Lists.newArrayList("v1", "v2", "v3", "v4", "v5", "v6");List<Node<String, String, Integer>> nodeList = nodes.stream().map(node -> {Node<String, String, Integer> nodeObj = new Node<>();nodeObj.setName(node);nodeObj.setPre(null);nodeObj.setDistance(Integer.MAX_VALUE);return nodeObj;}).collect(Collectors.toList());Table<String, Integer, Integer> edgeTable = HashBasedTable.create();edgeTable.put("v1", nodes.indexOf("v2"), 10);edgeTable.put("v2", nodes.indexOf("v3"), 7);edgeTable.put("v4", nodes.indexOf("v3"), 4);edgeTable.put("v4", nodes.indexOf("v5"), 7);edgeTable.put("v6", nodes.indexOf("v5"), 1);edgeTable.put("v1", nodes.indexOf("v6"), 3);edgeTable.put("v6", nodes.indexOf("v2"), 2);edgeTable.put("v4", nodes.indexOf("v1"), 3);edgeTable.put("v2", nodes.indexOf("v4"), 5);edgeTable.put("v6", nodes.indexOf("v4"), 6);return new WeightGraph(nodeList,edgeTable); }/*** 节点名,前驱节点,最短路径* 也⽤于存储最终的最短路径数据** @param <N>* @param <D>*/@Data@AllArgsConstructor@NoArgsConstructorstatic class Node<N,P, D> {private N name;private P pre;private D distance;}}输出:v1:0v2:5v3:12v4:9v5:4v6:3。

基于Java的Dijkstra最短路径算法实现

基于Java的Dijkstra最短路径算法实现

基于Java的Dijkstra最短路径算法实现作者:段汝东侯至群朱大明来源:《价值工程》2016年第21期摘要:最短路径是一个顶点到其他所有顶点的距离的最优解。

传统Dijkstra算法是求最短路径最经典的算法,是后续最短路径算法改进的基础。

本文介绍了传统Dijkstra算法的相关概念及其实现原理,使用Java编程语言实现算法,最后给出关键伪码和运行结果。

Abstract: The shortest path is the optimal solution to get the distance from a node to all other nodes. Traditional Dijkstra algorithm is the most classical algorithm to find the shortest path and is the basis of optimizing algorithm. The paper introduces the corresponding concepts of the traditional Dijkstra algorithm and its working principle. Then the algorithm is realized by Java, the pseudo key codes and operational results are given at last.关键词:最短路径;Dijkstra算法;JavaKey words: the shortest path;Dijkstra algorithm;Java中图分类号:TP31 文献标识码:A 文章编号:1006-4311(2016)21-0208-030 引言最短路径问题是图论中的一个重点问题[1]。

随着图论、数据结构和算法的不断改进,部分最短路径算法也不断被提出,这些算法在时间复杂度、实现难易度及应用领域都有很大改进。

最短路径dijkstra算法 java

最短路径dijkstra算法 java

最短路径dijkstra算法java摘要:1.Dijkstra算法简介2.Dijkstra算法原理3.Dijkstra算法在Java中的实现4.代码示例与解析5.算法应用与优化正文:**一、Dijkstra算法简介**Dijkstra算法,又称迪科斯特拉算法,是一种用于解决单源最短路径问题的贪心算法。

它以荷兰计算机科学家Edsger W.Dijkstra的名字命名,于1959年提出。

Dijkstra算法广泛应用于图论、网络优化等领域,具有较高的实用价值。

**二、Dijkstra算法原理**Dijkstra算法的基本思想是:从未访问过的节点中,选择距离起点最近的节点进行访问,然后逐步扩展到其他节点。

具体步骤如下:1.创建一个集合,用于存储已访问过的节点(用标记符“*”表示);2.初始化起点到自身的距离为0,其他节点距离为正无穷;3.从未访问过的节点中,选择距离起点最近的节点进行访问;4.更新已访问节点的相邻节点距离,将原距离减去当前节点的距离,再加1(表示通过当前节点到达相邻节点的距离);5.重复步骤3和4,直到所有节点都被访问或找不到未访问的节点。

**三、Dijkstra算法在Java中的实现**在Java中,我们可以通过以下步骤实现Dijkstra算法:1.创建一个表示图的二维数组,其中元素为节点之间的边权;2.初始化起点到自身的距离为0,其他节点距离为正无穷;3.创建一个优先队列(最小堆),用于存储未访问过的节点及其距离;4.将起点插入优先队列;5.当优先队列不为空时,重复以下步骤:a.弹出队列最小元素(当前节点);b.标记当前节点为已访问;c.更新相邻节点距离;d.将未访问过的相邻节点插入优先队列;6.返回起点到终点的最短路径。

贪心算法-单源最短路径问题

贪心算法-单源最短路径问题

单源最短路径问题给定一个带权图G=(V,E),其中每条边的权势非负数实数。

另外,还给定V中的一个顶点,成为源。

现在要计算从源到其他所有顶点的最短路径长度(路径长度是指路径上各边的权重之和)。

针对上述问题,写一份详细的算法设计报告。

1.首先证明最优子结构性质:反证法:设P(I,j)为顶点i到j的最短路径,途中经过a,b两点,即p(i,j)={pi,…,pa,pb,…pj}若p(I,j)为最短路径,那么p(a,b)也必定是a,b之间的最短路径,即p(I,j)的最优解一定包含子问题的最优解,若p(a,b)不是最短路径,那么就有p`(a,b)更短,那么p`(I,j)=p(I,a)+p`(a,b)+p(b,j)<p(I,j)与题设p(i,j)为最短路径矛盾,因而得证2.证明贪心选择性质:该题的贪心选择性质即计算dist[i]时每次都选择最短的边设源点为v,源点到顶点u的最短路径为dist[u]设有第三个点x,存在一条边d(v,x)>=dist[x]的,那么d(v,x)+d(x,u)=d(v,u)<dist[u]由于d(x,u)非负,因此由上面两式可推得dist[x]<dist[u],矛盾,即如果每次不选择最短的边将得不到最优解3.算法过程设图G=<V,E>,源顶点为V0,U={V0},dist[i]记录V0到i的最短距离1.选择使dist[i]值最小的顶点i,将i加入到U中2.更新与i直接相邻顶点的dist值。

(dist[j]=min{dist[j],dist[i]+d(I,j)})3.直到V中没有节点停止。

使用一个二维数组储存计算dist,最后一行即源点到各点的最短路径。

dijkstra算法代码实现

dijkstra算法代码实现

dijkstra算法代码实现Dijkstra算法是用来求解单源最短路径问题的一种贪心算法。

下面是Dijkstra算法的代码实现:```import sys# 定义一个类来保存图的节点和边的信息class Node:def __init__(self, name): = nameself.visited = Falseself.distance = sys.maxsizeself.adjacent_nodes = []self.previous_node = None# Dijkstra算法的实现函数def dijkstra(start_node):start_node.distance = 0unvisited_nodes = [start_node]while unvisited_nodes:current_node = unvisited_nodes[0]for neighbor in current_node.adjacent_nodes:if not neighbor.visited:new_distance = current_node.distance +neighbor.distanceif new_distance < neighbor.distance:neighbor.distance = new_distanceneighbor.previous_node = current_nodecurrent_node.visited = Trueunvisited_nodes.remove(current_node)unvisited_nodes.sort(key=lambda node: node.distance)# 测试nodeA = Node("A")nodeB = Node("B")nodeC = Node("C")nodeD = Node("D")nodeE = Node("E")nodeF = Node("F")nodeA.adjacent_nodes = [(nodeB, 10), (nodeC, 15)]nodeB.adjacent_nodes = [(nodeD, 12), (nodeF, 15)]nodeC.adjacent_nodes = [(nodeE, 10)]nodeD.adjacent_nodes = [(nodeE, 2), (nodeF, 1)]nodeF.adjacent_nodes = [(nodeE, 5)]dijkstra(nodeA)print(nodeE.distance)```在上面的代码中,我们定义了一个`Node`类用来保存节点的信息,包括节点的名称、是否已访问、距离起始节点的距离、相邻节点和前置节点等。

dijkstra算法 java最短路径

dijkstra算法 java最短路径

dijkstra算法java最短路径Dijkstra算法是一种用于寻找图中两个节点之间最短路径的算法。

它采用的是贪心策略,将图中的节点分为两个集合:已访问节点集S和未访问节点集T。

算法从源节点开始,每次从T中选择到源节点距离最短的节点加入S集合,并更新S集合中各节点到源节点的最短路径。

直到T集合中的节点全部加入S集合,算法结束。

Dijkstra算法的Java实现如下:●public class Dijkstra{●public static void main(String[]args){●创建图●Graph graph=new Graph();●graph.addVertex("A");●graph.addVertex("B");●graph.addVertex("C");●graph.addEdge("A","B",10);●graph.addEdge("A","C",20);●graph.addEdge("B","C",30);●计算最短路径●dijkstra(graph,"A");}●private static void dijkstra(Graph graph,String startVertex){●初始化●Set<String>visited=new HashSet<>();●Map<String,Integer>distances=new HashMap<>();●for(String vertex:graph.getVertices()){●distances.put(vertex,Integer.MAX_VALUE);}●distances.put(startVertex,0);●遍历所有节点●for(String vertex:graph.getVertices()){●找到未访问节点中距离源节点最小的节点●String nearestVertex=findNearestVertex(distances,visited);●将该节点加入已访问节点集合●visited.add(nearestVertex);●更新该节点到其他节点的最短路径●for(String neighbor:graph.getAdjacentVertices(nearestVertex)){●intnewDistance=distances.get(nearestVertex)+graph.getEdgeWeight(nearestVertex,neighbor ●if(newDistance<distances.get(neighbor)){●distances.put(neighbor,newDistance);}}}●输出结果●System.out.println("从"+startVertex+"到其他节点的最短路径:");●for(String vertex:graph.getVertices()){●System.out.println(vertex+"的最短路径是:"+distances.get(vertex));}}●private static String findNearestVertex(Map<String,Integer>distances,Set<String>visited){●int minDistance=Integer.MAX_VALUE;●String nearestVertex=null;●for(String vertex:distances.keySet()){●if(!visited.contains(vertex)&&distances.get(vertex)<minDistance){●minDistance=distances.get(vertex);●nearestVertex=vertex;}}●return nearestVertex;}}该算法的工作原理如下:1.初始化距离表,将所有节点的距离初始化为无穷大。

javaFloyd算法求解最短路径问题完整程序代码

javaFloyd算法求解最短路径问题完整程序代码

引言在图论中经常会遇到这样的问题,在一个有向图里求出任意两个节点之间的最短距离。

当节点之间的权值是正值的时候,我们可以采用Dijkstra算法,用贪心策略加于解决。

但当节点之间的权值有负数的时候,Dijkstra就行不通了,这里介绍另外一种算法—Floyd最短路径算法。

对于任意图,选择存储结构存储图并实现FLOYD算法求解最短路经。

将问题分解,分解为两方面。

一是对于任意图的存储问题,第二个是实现FLOYD算法求解最短路经。

首先对于图的创建选择合适的存储结构进行存储,对于合适的存储结构可以简化程序。

本实验采用邻接矩阵存储。

然后是实现FLOYD算法求解最短路经,在FLOYD算法中路径的长度即是图中两定点间边的权值,FLOYD算法要求输出任意两个顶点间的最短路径,而且经过的顶点也要输出。

考虑到问题的特殊性,采用一个二维数组和一个三维数组进行存储。

二维数组存储最短路径,三维数组存储路径经过的顶点,在进行适当的算法后对这两个数组进行输出即可。

通过问题的分解,逐个解决,事先所要求的程序。

最短路径算法问题是计算机科学、运筹学、地理信息系统和交通诱导、导航系统等领域研究的一个热点。

传统的最短路径算法主要有Floyd算法和Dijkstra算法。

Floyd算法用于计算所有结点之间的最短路径。

Dijkstra算法则用于计算一个结点到其他所有结点的最短路径。

Dijkstra算法是已经证明的能得出最短路径的最优解,但它的效率是一个很大的问题。

对于具有n个结点的一个图,计算一个结点到图中其余结点最短路径的算法时间复杂度为O(n2)。

对于一座大中型城市,地理结点数目可能达到几万个到几十万个,计算最短路径的时间开销将是非常巨大的。

本文根据吴一民老师的建议,分析当前存在的各种求最短路径的算法,提出一种新的基于层次图的最短路径算法,即将一个平面图划分若干子图,子图抽象为一个高层图。

最短路径的计算首先在高层图中进行,缩小了最短路径的查找范围,降低了最短路径计算的时间开销。

实验项目名称∶用贪心算法解单源最短路径问题

实验项目名称∶用贪心算法解单源最短路径问题

实验项目名称:用贪心算法解单源最短路径问题一、实验目的:明确单源最短路径问题的概念;利用贪心算法解决单源最短路径问题;并通过本例熟悉贪心算法在程序设计中的应用方法。

二、实验原理:贪心算法原理:在贪婪算法(greedy method)中采用逐步构造最优解的方法。

在每个阶段,都作出一个看上去最优的决策(在一定的标准下)。

决策一旦作出,就不可再更改。

作出贪婪决策的依据称为贪婪准则(greedy criterion)。

三、实验内容与步骤:问题描述:求网(带权有向图)中从一个顶点到其余各顶点间的最短路径。

一个有向图G,它的每条边都有一个非负的权值c[i,j],“路径长度”就是所经过的所有边的权值之和。

对于源点需要找出从源点出发到达其他所有结点的最短路径。

基本思想分步求出最短路径,每一步产生一个到达新目的顶点的最短路径。

下一步所能达到的目的顶点通过如下贪婪准则选取:在未产生最短路径的顶点中,选择路径最短的目的顶点。

设置顶点集合S并不断作贪心选择来扩充这个集合。

当且仅当顶点到该顶点的最短路径已知时该顶点属于集合S。

初始时S中只含源。

设u为G中一顶点,我们把从源点到u 且中间仅经过集合S中的顶点的路称为从源到u特殊路径,并把这个特殊路径记录下来(例如程序中的dist[i])。

每次从V-S选出具有最短特殊路径长度的顶点u,将u添加到S中,同时对特殊路径长度进行必要的修改。

一旦V=S,就得到从源到其他所有顶点的最短路径,也就得到问题的解。

如上图所示,编程实现求从任一顶点出发到其它顶点的最短路径长度。

如下:please input the first number:00->0:00->1:450->2:100->3:250->4:450->5:50please input the first number:11->0:351->1:01->2:151->3:181->4:101->5:15please input the first number:22->0:202->1:352->2:02->3:152->4:452->5:50please input the first number:33->0:553->1:203->2:353->3:03->4:303->5:35please input the first number:44->0:634->1:284->2:434->3:84->4:04->5:5please input the first number:55->0:585->1:235->2:385->3:35->4:335->5:0四实验结果与结论自己总结五实验中遇到的问题及解决办法自己总结六实验结论自己总结参考程序段如下#include<stdio.h>#define MAX 10000int main(){int cost[6][6]={{0,50,10,MAX,45,MAX},{MAX,0,15,MAX,10,MAX},{20,MAX,0,15,MAX,MAX},{MAX,20,MAX,0,35,MAX},{MAX,MAX,MAX,30,0,5},{MAX,MAX,MAX,3,MAX,0}};int s[6],dist[6];int n;int i,j,k,m,min;clrscr();printf("please input the first number:");while(scanf("%d",&n)&&n>=0&&n<6){for(i=0;i<6;i++){s[i]=0;dist[i]=cost[n][i];}s[n]=1,dist[n]=0;for(j=1;j<6;j++){min=MAX;for(k=0;k<6;k++){if(s[k]==0&&min>dist[k]){min=dist[k];m=k;}}if(min==MAX)break;s[m]=1,dist[m]=min;for(k=0;k<6;k++){if(s[k]==0)dist[k]=(dist[k]<(dist[m]+cost[m][k]))?dist[k]:(dist[m]+cost[m ][k]);}}for(i=0;i<6;i++){if(dist[i]<MAX)printf("%d->%d:%d\n",n,i,dist[i]);}printf("please input the first number:");}}。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档