# 基于无向图且权重单一的最短路径Dijkstra算法——JAVA实现

2760人阅读 评论(0)

http://blog.csdn.net/javaman_chen/article/details/8254309

Coordinate.java

Coordinate中包含相邻坐标的List，以及距离起始点的距离。

package com.harlan.dijkstra;

import java.util.LinkedList;

/**
* 坐标点的数据结构
*
* @author Harlan
*
*/
public class Coordinate {
//x坐标
public int x;
//y坐标
public int y;
//相邻坐标
public LinkedList<Coordinate> adj;
//距离
public int steps;
// 最短路径中的前一个顶点
public Coordinate lastPoint;
;

public Coordinate(){

}

public Coordinate(int newX, int newY) {
x = newX;
y = newY;
adj=new LinkedList<Coordinate>();
reset();
}

public void reset(){
steps=Integer.MAX_VALUE;
lastPoint=null;
}

@Override
public boolean equals(Object obj) {
if (!(obj instanceof Coordinate))
return false;

Coordinate other = (Coordinate) obj;
if (x == other.x && y == other.y) {
return true;
}
return false;
}

@Override
public int hashCode() {
return x*10000+y;
}

/**
* 以JSON格式展示坐标
*/
@Override
public String toString() {
return "{\"x\":" + x + ",\"y\":" + y + "}";
}
}  

PathInfo.java

import java.util.List;

/**
* 路径信息
* @author Harlan
*
*/
public class PathInfo {

//目标点的坐标
private Coordinate targetCd;

//去往目标点的最佳路径
private List<Coordinate> cdList;

public Coordinate getTargetCd() {
return targetCd;
}

public void setTargetCd(Coordinate targetCd) {
this.targetCd = targetCd;
}

public List<Coordinate> getCdList() {
return cdList;
}

public void setCdList(List<Coordinate> cdList) {
this.cdList = cdList;
}

}  

<span style="white-space:pre">	</span> /**
* 和周围的四个点建立关系
*
* @param node
*/
private void getContactWithF(Coordinate node) {
Coordinate coordinate = getCoordinate(node);
Coordinate EAST = new Coordinate(node.x + 1, node.y);
Coordinate SOUTH = new Coordinate(node.x, node.y + 1);
Coordinate WEST = new Coordinate(node.x - 1, node.y);
Coordinate NORTH = new Coordinate(node.x, node.y - 1);
if (isCellSafe(EAST, mRoads)) {
EAST = getCoordinate(EAST);
coordinate.adj.add(EAST);
}
if (isCellSafe(SOUTH, mRoads)) {
SOUTH = getCoordinate(SOUTH);
coordinate.adj.add(SOUTH);
}
if (isCellSafe(WEST, mRoads)) {
WEST = getCoordinate(WEST);
coordinate.adj.add(WEST);
}
if (isCellSafe(NORTH, mRoads)) {
NORTH = getCoordinate(NORTH);
coordinate.adj.add(NORTH);
}
}

/**
* 判断周围的位子是不是道路
*
* @param head
* @return
*/
public boolean isCellSafe(Coordinate park, Set<Coordinate> roads) {
boolean isSafe = false;
// 在道路集合里面，就是安全的，否则，不安全
for (Coordinate info : roads) {
if (info.equals(park)) {
isSafe = true;
}
}
return isSafe;
}

  <span style="white-space:pre">	</span>// 无权最短路径计算
public void unweighted(Coordinate enter) {

if (enter == null)
throw new NoSuchElementException("Start vertex not found!");

LinkedList<Coordinate> q = new LinkedList<Coordinate>();

clearAll();
enter = vertexMap.get(enter.toString());

System.out.println("unweighted Harlan:" + enter.adj.toString());

q.addLast(enter);

enter.steps = 0;

while (!q.isEmpty()) {
Coordinate v = q.removeFirst();
for (Iterator<Coordinate> itr = v.adj.iterator(); itr.hasNext();) {
Coordinate w = itr.next();
if (w.steps == Integer.MAX_VALUE) {
w.steps = v.steps + 1;
w.lastPoint = v;
q.addLast(w);
}
}
}
}


<span style="white-space:pre">	</span>private List<Coordinate> getPath(Coordinate dest, List<Coordinate> cdList) {
if (dest.lastPoint != null) {
cdList = (getPath(dest.lastPoint, cdList));
}
cdList.add(dest);
return cdList;
}

<span style="white-space:pre">	</span>// 显示一条路径
public void printPath(String coodrStr) throws NoSuchElementException {
Coordinate coord = vertexMap.get(coodrStr);
if (coord == null)
throw new Exception(No path  found!");
else if (coord.steps == Integer.MAX_VALUE)
System.out.println(coord.toString() + "is unreachable!");
else {
printPath(coord);
System.out.println();
}
}

// 显示实际最短路径
private void printPath(Coordinate dest) {

if (dest.lastPoint != null) {
printPath(dest.lastPoint);
System.out.print(",");
}
System.out.print(dest.toString());
}

GetDijkstraPath.java

package com.harlan.dijkstra;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class GetDijkstraPath {

private static final String TAG = GetDijkstraPath.class.getSimpleName();

/**
* 主函数，测试类
* @param args
*/
public static void main(String[] args) {
Coordinate enter = new Coordinate(2, 0);

Set<Coordinate> roads = new HashSet<Coordinate>();
roads.add(new Coordinate(3, 10));
roads.add(new Coordinate(3,11));
roads.add(new Coordinate(3, 8));
roads.add(new Coordinate(3, 9));
roads.add(new Coordinate(3, 6));
roads.add(new Coordinate(3, 7));
roads.add(new Coordinate(3, 4));
roads.add(new Coordinate(3, 5));
roads.add(new Coordinate(3, 2));
roads.add(new Coordinate(3, 3));
roads.add(new Coordinate(3, 1));
roads.add(new Coordinate(6, 1));
roads.add(new Coordinate(1, 9));
roads.add(new Coordinate(1, 8));
roads.add(new Coordinate(1, 11));
roads.add(new Coordinate(1, 10));
roads.add(new Coordinate(1, 5));
roads.add(new Coordinate(1, 4));
roads.add(new Coordinate(1, 7));
roads.add(new Coordinate(1, 6));
roads.add(new Coordinate(1, 1));
roads.add(new Coordinate(1, 3));
roads.add(new Coordinate(1, 2));
roads.add(new Coordinate(4, 1));
roads.add(new Coordinate(4, 11));
roads.add(new Coordinate(7, 5));
roads.add(new Coordinate(7, 4));
roads.add(new Coordinate(2, 11));
roads.add(new Coordinate(7, 7));
roads.add(new Coordinate(7,6));
roads.add(new Coordinate(7, 1));
roads.add(new Coordinate(7, 3));
roads.add(new Coordinate(7,2));
roads.add(new Coordinate(2, 1));
roads.add(new Coordinate(7, 9));
roads.add(new Coordinate(7,8));
roads.add(new Coordinate(7, 11));
roads.add(new Coordinate(7, 10));
roads.add(new Coordinate(5,11));
roads.add(new Coordinate(5, 10));
roads.add(new Coordinate(5, 9));
roads.add(new Coordinate(5,8));
roads.add(new Coordinate(5,7));
roads.add(new Coordinate(5,6));
roads.add(new Coordinate(5,5));
roads.add(new Coordinate(5,4));
roads.add(new Coordinate(5,3));
roads.add(new Coordinate(5,2));
roads.add(new Coordinate(5,1));
System.out.println("nearest roads.size(): "+roads.size());

Set<Coordinate> trags = new HashSet<Coordinate>();
trags.add(new Coordinate(5, 4));
trags.add(new Coordinate(5, 5));
PathInfo nearest = getNearestPathInfo(roads,trags,enter);
System.out.println("nearest : "+nearest.getCdList());
}

/**
* 对外的接口(如果计算多入口的最短路径的时候使用)
* 获取多入口的最佳路径
* @param roads
* @param trags
* @param enters
* @return
*/
public static PathInfo getNearestPathInfoFromDiffEnter(Set<Coordinate> roads,
Set<Coordinate> trags, Set<Coordinate> enters){
List<PathInfo> list = new ArrayList<>();
for(Coordinate enter:enters){
list.add(getNearestPathInfo(roads,trags,enter));
}
//每条路径的步长
int steps = Integer.MAX_VALUE;
PathInfo nearste = new PathInfo();
for(PathInfo pathInfo:list){
if(pathInfo.getCdList().size()<steps){
steps = pathInfo.getCdList().size();
nearste = pathInfo;
}
}
return nearste;

}

/**
* 对外的接口(如果计算单一入口的最短路径时候使用)
* 获取单一入口的最佳路径
*
* @param roads
* @param trags
* @param enter
* @return
*/
public static PathInfo getNearestPathInfo(Set<Coordinate> roads,
Set<Coordinate> trags, Coordinate enter){
List<PathInfo> list = getAllAvailablePathInfo(roads,trags,enter);
//		 for(PathInfo info:list){
//	    		System.out.println("getNearestPathInfo targ:"+info.getTargetCd());
//	    		System.out.println("getNearestPathInfo route:"+info.getCdList());
//	    		System.out.println("getNearestPathInfo *********************");
//	    	}
//
//每条路径的步长
int steps = Integer.MAX_VALUE;
PathInfo nearste = new PathInfo();
for(PathInfo pathInfo:list){
if(pathInfo.getCdList().size()<steps){
steps = pathInfo.getCdList().size();
nearste = pathInfo;
}
}
return nearste;
}

/**
* 获取到达所有目标点的所有可用路径
*
* @param roads
* @param trags
* @param enter
* @return
*/
private static List<PathInfo> getAllAvailablePathInfo(Set<Coordinate> roads,
Set<Coordinate> trags, Coordinate enter) {
Set<Coordinate> availableRoadTar = getAllRoadNearTarg(roads,trags);

//计算出起始点到各个可达点的距离
HarlanDijkstra test=new HarlanDijkstra(roads,enter);
test.unweighted(enter);

//得出到停车位的可达点的最短路径
List<PathInfo> availableList = new ArrayList<>();
for(Coordinate info:availableRoadTar){
PathInfo pathInfo = test.getPathInfo(info.toString());
availableList.add(pathInfo);

}
return availableList;
}

/**
* 获取通往所有目标的有效道路点(一个目标的临近道路点的集合)
* @param roads
* @param tragSet
* @return
*/
private static Set<Coordinate> getAllRoadNearTarg(Set<Coordinate> roads,
Set<Coordinate> tragSet) {
Set<Coordinate> allOfNearList = new HashSet<>();
for (Coordinate targ : tragSet) {
//			System.out.println("getAllRoadNearTarg targ:"+targ);
Set<Coordinate> childSet = getRoadNearTarg(roads,targ);
allOfNearList.addAll(childSet);
}
return allOfNearList;
}

/**
* 获取通往一个目标的临近道路点
*
* @param roads
* @param targ
* @return
*/
private static Set<Coordinate> getRoadNearTarg(Set<Coordinate> roads,
Coordinate targ) {
Set<Coordinate> nearList = new HashSet<>();
Coordinate EAST = new Coordinate(targ.x + 1, targ.y);
Coordinate SOUTH = new Coordinate(targ.x, targ.y + 1);
Coordinate WEST = new Coordinate(targ.x - 1, targ.y);
Coordinate NORTH = new Coordinate(targ.x, targ.y - 1);
for (Coordinate info : roads) {
if (EAST.equals(info)) {
nearList.add(EAST);
}
if (SOUTH.equals(info)) {
nearList.add(SOUTH);
}
if (WEST.equals(info)) {
nearList.add(WEST);
}
if (NORTH.equals(info)) {
nearList.add(NORTH);
}
}
return nearList;
}

}

nearest roads.size(): 49
nearest : [{"x":2,"y":0}, {"x":2,"y":1}, {"x":3,"y":1}, {"x":4,"y":1}, {"x":5,"y":1}, {"x":5,"y":2}, {"x":5,"y":3}]

0
0

* 以上用户言论只代表其个人观点，不代表CSDN网站的观点或立场
个人资料
• 访问：537754次
• 积分：5423
• 等级：
• 排名：第5130名
• 原创：86篇
• 转载：1篇
• 译文：0篇
• 评论：218条
阅读排行
最新评论