图的最短路径java
‘壹’ 用java怎么用迪杰斯特拉算有向图有权值的最短路径
Dijkstra(迪杰斯特拉)算法是典型的最短路径路由算法,用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。
Dijkstra一般的表述通常有两种方式,一种用永久和临时标号方式,一种是用OPEN, CLOSE表方式
用OPEN,CLOSE表的方式,其采用的是贪心法的算法策略,大概过程如下:
1.声明两个集合,open和close,open用于存储未遍历的节点,close用来存储已遍历的节点
2.初始阶段,将初始节点放入close,其他所有节点放入open
3.以初始节点为中心向外一层层遍历,获取离指定节点最近的子节点放入close并从新计算路径,直至close包含所有子节点
代码实例如下:
Node对象用于封装节点信息,包括名字和子节点
[java] view plain
public class Node {
private String name;
private Map<Node,Integer> child=new HashMap<Node,Integer>();
public Node(String name){
this.name=name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Map<Node, Integer> getChild() {
return child;
}
public void setChild(Map<Node, Integer> child) {
this.child = child;
}
}
MapBuilder用于初始化数据源,返回图的起始节点
[java] view plain
public class MapBuilder {
public Node build(Set<Node> open, Set<Node> close){
Node nodeA=new Node("A");
Node nodeB=new Node("B");
Node nodeC=new Node("C");
Node nodeD=new Node("D");
Node nodeE=new Node("E");
Node nodeF=new Node("F");
Node nodeG=new Node("G");
Node nodeH=new Node("H");
nodeA.getChild().put(nodeB, 1);
nodeA.getChild().put(nodeC, 1);
nodeA.getChild().put(nodeD, 4);
nodeA.getChild().put(nodeG, 5);
nodeA.getChild().put(nodeF, 2);
nodeB.getChild().put(nodeA, 1);
nodeB.getChild().put(nodeF, 2);
nodeB.getChild().put(nodeH, 4);
nodeC.getChild().put(nodeA, 1);
nodeC.getChild().put(nodeG, 3);
nodeD.getChild().put(nodeA, 4);
nodeD.getChild().put(nodeE, 1);
nodeE.getChild().put(nodeD, 1);
nodeE.getChild().put(nodeF, 1);
nodeF.getChild().put(nodeE, 1);
nodeF.getChild().put(nodeB, 2);
nodeF.getChild().put(nodeA, 2);
nodeG.getChild().put(nodeC, 3);
nodeG.getChild().put(nodeA, 5);
nodeG.getChild().put(nodeH, 1);
nodeH.getChild().put(nodeB, 4);
nodeH.getChild().put(nodeG, 1);
open.add(nodeB);
open.add(nodeC);
open.add(nodeD);
open.add(nodeE);
open.add(nodeF);
open.add(nodeG);
open.add(nodeH);
close.add(nodeA);
return nodeA;
}
}
图的结构如下图所示:
Dijkstra对象用于计算起始节点到所有其他节点的最短路径
[java] view plain
public class Dijkstra {
Set<Node> open=new HashSet<Node>();
Set<Node> close=new HashSet<Node>();
Map<String,Integer> path=new HashMap<String,Integer>();//封装路径距离
Map<String,String> pathInfo=new HashMap<String,String>();//封装路径信息
public Node init(){
//初始路径,因没有A->E这条路径,所以path(E)设置为Integer.MAX_VALUE
path.put("B", 1);
pathInfo.put("B", "A->B");
path.put("C", 1);
pathInfo.put("C", "A->C");
path.put("D", 4);
pathInfo.put("D", "A->D");
path.put("E", Integer.MAX_VALUE);
pathInfo.put("E", "A");
path.put("F", 2);
pathInfo.put("F", "A->F");
path.put("G", 5);
pathInfo.put("G", "A->G");
path.put("H", Integer.MAX_VALUE);
pathInfo.put("H", "A");
//将初始节点放入close,其他节点放入open
Node start=new MapBuilder().build(open,close);
return start;
}
public void computePath(Node start){
Node nearest=getShortestPath(start);//取距离start节点最近的子节点,放入close
if(nearest==null){
return;
}
close.add(nearest);
open.remove(nearest);
Map<Node,Integer> childs=nearest.getChild();
for(Node child:childs.keySet()){
if(open.contains(child)){//如果子节点在open中
Integer newCompute=path.get(nearest.getName())+childs.get(child);
if(path.get(child.getName())>newCompute){//之前设置的距离大于新计算出来的距离
path.put(child.getName(), newCompute);
pathInfo.put(child.getName(), pathInfo.get(nearest.getName())+"->"+child.getName());
}
}
}
computePath(start);//重复执行自己,确保所有子节点被遍历
computePath(nearest);//向外一层层递归,直至所有顶点被遍历
}
public void printPathInfo(){
Set<Map.Entry<String, String>> pathInfos=pathInfo.entrySet();
for(Map.Entry<String, String> pathInfo:pathInfos){
System.out.println(pathInfo.getKey()+":"+pathInfo.getValue());
}
}
/**
* 获取与node最近的子节点
*/
private Node getShortestPath(Node node){
Node res=null;
int minDis=Integer.MAX_VALUE;
Map<Node,Integer> childs=node.getChild();
for(Node child:childs.keySet()){
if(open.contains(child)){
int distance=childs.get(child);
if(distance<minDis){
minDis=distance;
res=child;
}
}
}
return res;
}
}
Main用于测试Dijkstra对象
[java] view plain
public class Main {
public static void main(String[] args) {
Dijkstra test=new Dijkstra();
Node start=test.init();
test.computePath(start);
test.printPathInfo();
}
}
‘贰’ JAVA求10个景点间各个景点的最短路径 图随便话 距离随便 求代码
最有效,切不复杂的方法使用Breadth First Search (BFS). 基本代码如下(伪代码)。因为BFS不用递归,所以可能会有点难理解。
public Stack findPath(Vertex 起始景点, Vertex 目标景点){
Queue <Vertex> q = new Queue<Vertex>();
s.enqueue(起始景点);
Vertex 当前位置;
while(!s.isEmpty()){
当前位置 = s.dequeue();
if (当前位置 == 目标景点) break;
for (每一个相邻于 当前位置 的景点 Vertex v){
if (!v.visited){
v.parent = 当前位置;
// 不是规定,不过可以节省一点时间
if (v == 目标景点){
current = v;
break;
}
s.enqueue(Vertex v);
v.visited = true;
}
}
}
Stack <Vertex> solution = new Stack <Vertex>();
Vertex parent = current;
while (parent != 起始景点){
solution.push(parent);
parent = current.parent;
}
for (graph中的每一个vertex) vertex.visited = false;
return solution(); // 其实这里建议用一个 Path 的inner class 来装所获得的路线
}
然后再 main 求每两个景点之间的距离即可
public static void main(String[] argv){
PathFinder pf = new PathFinder();
Stack[][] 路径 = new Stack[10][10];
for(int i=0; i<pf.vertices.length; i++){
for(int j=i+1; j<pf.vertices.length; j++){
Stack s = pf.findPath(pf.vertices[i], pf.vertices[j]);
路径[i][j] = s; 路径[j][i] = s; // 假设你的graph是一个undirected graph
}
}
// 这么一来就大功告成了!对于每两个景点n 与 m之间的最短路径就是在 stack[n][m] 中
}
还有一种方法就是用Depth First Search递归式的寻找路径,不过这样比较慢,而且我的代码可能会造成stack overflow
public Stack dfs(Vertex 当前景点,Vertex 目标景点){
if(当前景点 == 目标景点) return;
Stack solution = new Stack();
Stack temp;
for (相邻于 点钱景点 的每一个 Vertex v){
if (!v.visited){
v.visited = true;
temp = dfs(v, 目标景点);
// 抱歉,不记得是stack.size()还是stack.length()
if (solution.size() == 0) solution = temp;
else if(temp.size() < solution.size()) solution = temp;
v.visited = false; 复原
}
}
return solution;
}
然后再在上述的Main中叫dfs...
参考:
http://www.cs.berkeley.e/~jrs/61b/lec/29
http://www.cs.berkeley.e/~jrs/61b/lec/28
‘叁’ 请教JAVA实现GIS最短路径输出
而输出最短路径的时候,在网上也进行了查阅,没发现什么标准的方法,于是在下面的实现中,我给出了一种能够想到的比较精简的方式:利用prev[]数组进行递归输出。
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
package graph.dijsktra;
import graph.model.Point;
import java.util.*;
/**
* Created by MHX on 2017/9/13.
*/
public class Dijkstra {
private int[][] map; // 地图结构保存
private int[][] edges; // 邻接矩阵
private int[] prev; // 前驱节点标号
private boolean[] s; // S集合中存放到起点已经算出最短路径的点
private int[] dist; // dist[i]表示起点到第i个节点的最短路径
private int pointNum; // 点的个数
private Map<Integer, Point> indexPointMap; // 标号和点的对应关系
private Map<Point, Integer> pointIndexMap; // 点和标号的对应关系
private int v0; // 起点标号
private Point startPoint; // 起点
private Point endPoint; // 终点
private Map<Point, Point> pointPointMap; // 保存点和权重的映射关系
private List<Point> allPoints; // 保存所有点
private int maxX; // x坐标的最大值
private int maxY; // y坐标的最大值
public Dijkstra(int map[][], Point startPoint, Point endPoint) {
this.maxX = map.length;
this.maxY = map[0].length;
this.pointNum = maxX * maxY;
this.map = map;
this.startPoint = startPoint;
this.endPoint = endPoint;
init();
dijkstra();
}
‘肆’ 求java代码,关于带权有向图找最短距离,数据结构方面
so..................复杂
‘伍’ 求java实现矩阵图上任意两点的最短路径源码
我用的是递归调用方法,有个小问题就是在打印步数的时候是返向的,原因是就是程序不断的调用自己,到最后判断基值位准退出调用。这才开始从栈里取出方法进行执行的原因。
代码欣赏:
publicstaticintstep=1;
=newStringBuffer();
publicstaticint[][]maze={{1,1,1,1,1,1,1,1,1,1,1},
{1,0,1,0,1,0,0,0,0,0,1},
{1,0,1,0,0,0,1,0,1,1,1},
{1,0,0,0,1,0,1,0,0,0,1},
{1,0,1,1,0,0,1,0,0,1,1},//0代表可以通过,1代表不可通过
{1,0,1,0,1,1,0,1,0,0,1},
{1,0,0,0,0,0,0,0,1,0,1},
{1,0,1,0,1,0,1,0,1,0,1},
{1,0,0,1,0,0,1,0,1,0,1},
{1,1,1,1,1,1,1,1,1,1,1}};
publicstaticvoidmain(String[]args){
inti,j;//循环记数变量
Sample.way(1,1);//二维数组起始值从下标1,1开始
System.out.println("起点从坐标x=1,y=1开始");
System.out.println("终点坐标是x=8,y=9结束");
System.out.println("这是迷宫图表");
System.out.println("012345678910");
System.out.println("+---+---+---+---+---+---+---+---+---+---+---+---+---+");
for(i=0;i<10;i++){
System.out.print(""+i+"‖");
for(j=0;j<11;j++)
System.out.print("-"+maze[i][j]+"-‖");
System.out.println("");
System.out.println("+---+---+---+---+---+---+---+---+---+---+---+---+---+");
}
//打印显示步数
System.out.print(printStep.toString());
}
publicstaticbooleanway(intx,inty){
if(maze[8][9]==2)//代表递归终止条件(也就是当走出出口时标记为2)
returntrue;
else{
if(maze[y][x]==0){
maze[y][x]=2;
/*
*下面if判断条件代表当前坐标为基点,
*根据判断对当前位置进行递归调用:如:
*往上、往右上、往右、往右下、往下、
*往左下、往左、往左上的坐标是否可走,
*判断是否可走的返回条件是:
*2代表可通过、1代表不能通过、3表示已经走过,但是未能走通。
*/
if(way(x,y-1)){
printStep.append("第"+step+"步的所走的位置是x="+x+"y="+y+" ");
step++;
returntrue;
}elseif(way(x+1,y-1)){
printStep.append("第"+step+"步的所走的位置是x="+x+"y="+y+" ");
step++;
returntrue;
}elseif(way(x+1,y)){
printStep.append("第"+step+"步的所走的位置是x="+x+"y="+y+" ");
step++;
returntrue;
}elseif(way(x+1,y+1)){
printStep.append("第"+step+"步的所走的位置是x="+x+"y="+y+" ");
step++;
returntrue;
}elseif(way(x,y+1)){
printStep.append("第"+step+"步的所走的位置是x="+x+"y="+y+" ");
step++;
returntrue;
}elseif(way(x-1,y+1)){
printStep.append("第"+step+"步的所走的位置是x="+x+"y="+y+" ");
step++;
returntrue;
}elseif(way(x-1,y)){
printStep.append("第"+step+"步的所走的位置是x="+x+"y="+y+" ");
step++;
returntrue;
}elseif(way(x-1,y-1)){
printStep.append("第"+step+"步的所走的位置是x="+x+"y="+y+" ");
step++;
returntrue;
}else{
maze[y][x]=3;
returnfalse;
}
}else
returnfalse;
}
}
复制代码前需要楼主自己创建个类
Sample.way(1,1);这句代码是我的类的静态调用,改下XXXXX.way(1,1);
XXXXX代表你创建的类。
下面是这个程序运行后的截图
‘陆’ 有什么无权无向图的最短路径算法比较好,求一个用java实现的
有什么无权无向图的最短路径算法比较好
带权图也分有向和无向两种,基本的算法可以看看书咯。 带权的无向图的最短路径又叫最小生成树,Prim算法和Kruskal算法; 带权的有向图的最短路径算法有迪杰斯特拉算法和佛洛依德算法;
String[]s={"January","February","March","April","May","June","July","August","September","October","November","December"};
System.out.print("请输入数字(1-12):");
BufferedReaderbr=newBufferedReader(newInputStreamReader(System.in));
Stringstr=br.readLine();
intm=Integer.parseInt(str);
if(m<=0||m>=13)
{
‘柒’ 求大佬用java帮我实现dijkstra算法,单源最短路径
python">import heapq
from collections import defaultdict
edges = [["A","B"],["A","D"],["A","E"],["B","C"],["C","E"],["D","E"],["D","C"]]
dist = [10,30,100,50,10,60,20]
res = []
def dijkstra(e,dist,start,end):
hm = defaultdict(list)
for i in range(len(e)):
hm[e[i][0]].append((e[i][1],dist[i]))
r = {}
r[start] = 0
q = [(0,start,[start])]
while q:
dis,node,res = heapq.heappop(q)
if node == end:
return dis,res
for u,v in hm[node]:
t = dis+v
if u not in r or t < r[u]:
r[u] = t
heapq.heappush(q,(t,u,res+[u]))
return 0,[]
dijkstra(edges,dist,"A","E")