单源最短路径 贪心算法 JAVA实现
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最短路径算法实现作者:段汝东侯至群朱大明来源:《价值工程》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摘要: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算法的代码实现:```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算法是一种用于寻找图中两个节点之间最短路径的算法。
它采用的是贪心策略,将图中的节点分为两个集合:已访问节点集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算法求解最短路径问题完整程序代码
引言在图论中经常会遇到这样的问题,在一个有向图里求出任意两个节点之间的最短距离。
当节点之间的权值是正值的时候,我们可以采用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. 贪心法求解单源最短路径问题实验内容本实验要求基于算法设计与分析的一般过程(即待求解问题的描述、算法设计、算法描述、算法正确性证明、算法分析、算法实现与测试)。
应用贪心策略求解有向带权图的单源最短路径问题。
实验目的通过本次实验,掌握算法设计与分析的一般过程,以及每个步骤的基本方法。
并应用贪心法求解单源最短路径问题。
环境要求对于环境没有特别要求。
对于算法实现,可以自由选择C, C++, Java,甚至于其他程序设计语言。
实验步骤步骤1:理解问题,给出问题的描述。
步骤2:算法设计,包括策略与数据结构的选择步骤3:描述算法。
希望采用源代码以外的形式,如伪代码、流程图等;步骤4:算法的正确性证明。
需要这个环节,在理解的基础上对算法的正确性给予证明;步骤5:算法复杂性分析,包括时间复杂性和空间复杂性;步骤6:算法实现与测试。
附上代码或以附件的形式提交,同时贴上算法运行结果截图;步骤7:技术上、分析过程中等各种心得体会与备忘,需要言之有物。
说明:步骤1-6在“实验结果”一节中描述,步骤7在“实验总结”一节中描述。
实验结果1.问题描述给定一个有向带全图G=(V,E),其中每条边的权是一个非负实数。
另外,给定V中的一个顶点,称为源点。
现在要计算源点到所有其他各个顶点的最短路径长度,这里的路径长度是指路径上所有经过边的权值之和。
这个问题通常称为单源最短路径问题。
2.(1)Dijkstra算法思想按各个结点与源点之间路径长度的非减次序,生成源点到各个结点的最短路径的方法。
即先求出长度最短的一条路径,再参照它求出长度次短的一条路径。
依此类推,直到从源点到其它各结点的最短路径全部求出为止。
1959年提出的,但当时并未发表。
因为在那个年代,算法基本上不被当做一种科学研究的问题。
贪心算法java代码
贪心算法java代码贪心算法Java代码贪心算法是一种高效的算法,它通过每次选择当前状态下最优解来得到全局最优解。
在贪心算法中,每个步骤都选择局部最优解,最终得到全局最优解。
贪心算法的应用非常广泛,比如最小生成树、最短路径、背包问题等。
下面我们以贪心算法解决最小生成树问题为例,给出Java代码实现。
最小生成树问题是指在一个带权无向图中,找到一棵树,使得这棵树包含了图中所有节点,且树的边的权值之和最小。
在贪心算法中,每次选择当前状态下最优解,因此我们可以从一个节点开始,不断添加与之相邻的边,直到所有节点都被包含在树中。
Java代码实现如下:```import java.util.*;class Edge implements Comparable<Edge>{int u;int v;int weight;public Edge(int u, int v, int weight){this.u = u;this.v = v;this.weight = weight;}public int compareTo(Edge e){return this.weight - e.weight;}}public class Prim {static int INF = Integer.MAX_VALUE;public static int prim(int[][] graph){int n = graph.length;boolean[] visited = new boolean[n];int[] dist = new int[n];Arrays.fill(dist, INF);PriorityQueue<Edge> pq = new PriorityQueue<>(); pq.offer(new Edge(0, 0, 0));int ans = 0;while(!pq.isEmpty()){Edge cur = pq.poll();if(visited[cur.v]) continue;visited[cur.v] = true;ans += cur.weight;for(int i = 0; i < n; i++){if(!visited[i] && graph[cur.v][i] < dist[i]){ dist[i] = graph[cur.v][i];pq.offer(new Edge(cur.v, i, dist[i]));}}}return ans;}public static void main(String[] args){int[][] graph = {{0, 1, 2, 3},{1, 0, 4, 5},{2, 4, 0, 6},{3, 5, 6, 0}};System.out.println(prim(graph));}}```在上面的代码中,我们定义了一个Edge类来表示边,包含起点、终点和边权值三个属性。