java 实现的Dijstra算法

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Dijstra {
	private List<Arc> arcs;
	private List<Integer> vertexs;
	private List<Integer> visitedNode; //未访问点集合
	private List<Integer> unVisitedNode;//已访问点集合
	private Map<Integer,Double> shortestPathLength;//起始点到该点的最短距离
	private Map<Integer,Integer> shortestPath;//最短距离,该点的前一个点
	private final double MAXLENGTH=100000000.0d;
	public Dijstra(List<Arc> arcs, List<Integer> vertexs) {
		this.arcs = arcs;
		this.vertexs = vertexs;
		visitedNode=new ArrayList<Integer>();
		unVisitedNode=new ArrayList<Integer>();
		shortestPathLength=new HashMap<Integer,Double>();
		shortestPath=new HashMap<Integer,Integer>();
	}
	public void init(int startNode){
		//初始化访问与未访问集合
		visitedNode.add(startNode);
		for(Integer node:vertexs){
			if(node.intValue()!=startNode){
				unVisitedNode.add(node);
			}
		}
		//初始化所有点到开始的最短路径
		shortestPathLength.put(startNode,0.0d);
		shortestPath.put(startNode, -1);
		for(int unNode:unVisitedNode){
			boolean access=false;
			for(Arc a:arcs){
				if(a.getNode1()==startNode&&a.getNode2()==unNode){ //若与起始点相连
					shortestPathLength.put(unNode, a.getLength());
					access=true;
					break;
				}
			}
			if(!access){
				shortestPathLength.put(unNode,MAXLENGTH);
			}
		}
		//初始化第一条路径
		int lastVisitedNode=startNode;
		for(int unNode:unVisitedNode){//遍历所有未访问的点
			double pathLength=getLength(lastVisitedNode,unNode);//两点的距离
			if(pathLength>0.0){//可达
				//重新计算 路径长度,与之前的对比
				double newPathLength=pathLength+shortestPathLength.get(lastVisitedNode);
				double oldPathLength=shortestPathLength.get(unNode);
				if(oldPathLength>=newPathLength){
					shortestPath.put(unNode, lastVisitedNode);
					shortestPathLength.put(unNode,newPathLength+shortestPathLength.get(lastVisitedNode));
				}
			}
		}
	}
	public void execute(){
		while(unVisitedNode.size()>0){
			int lastVisitedNode=visitedNode.get(visitedNode.size()-1);//之前最后访问的点
			for(int unNode:unVisitedNode){//遍历所有未访问的点
				double pathLength=getLength(lastVisitedNode,unNode);//两点的距离
				if(pathLength>0.0){//可达
					//重新计算 路径长度,与之前的对比
					double newPathLength=pathLength+shortestPathLength.get(lastVisitedNode);
					double oldPathLength=shortestPathLength.get(unNode);
					if(oldPathLength>newPathLength){
						shortestPath.put(unNode, lastVisitedNode);
						shortestPathLength.put(unNode,newPathLength+shortestPathLength.get(lastVisitedNode));
					}
				}
			}
		    //好到所有的未访问的节点中  到起始点距离最小的点
			Integer node=getMinPathLengthNode();
			visitedNode.add(node);
			unVisitedNode.remove(node);
		}
	}
	public List<Integer> getShortestPath(int node){
		List<Integer> path=new ArrayList<Integer>();
		getPath(path,node);
		Collections.reverse(path);
		return path;
	}
	private void getPath(List<Integer> path,int node){
		int pre=shortestPath.get(node);
		if(pre==-1){
			return;
		}else{
			path.add(pre);
			getPath(path,pre);
		}
	}
	//返回未访问的节点中 距离起始点最近的一个
	private Integer getMinPathLengthNode(){
		Integer minNode = null;
		double min=10000000000.0d;
		for(Integer node:unVisitedNode){
			double length=shortestPathLength.get(node);
			if(length<min){
				minNode=node;
				min=length;
			}
		}
		return minNode;
	}
	private double getLength(int node1,int node2){
		double length=-1.0d;
		for(Arc a:arcs){
			if(a.getNode1()==node1&&a.getNode2()==node2){
				length=a.getLength();
			}
		}
		return length;
	}
	
	
}


class Arc{
	
	private int node1;
	private int node2;
	private double length;
	public Arc(int node1, int node2, double length) {
		this.node1 = node1;
		this.node2 = node2;
		this.length = length;
	}
	public int getNode1() {
		return node1;
	}
	public void setNode1(int node1) {
		this.node1 = node1;
	}
	public int getNode2() {
		return node2;
	}
	public void setNode2(int node2) {
		this.node2 = node2;
	}
	public double getLength() {
		return length;
	}
	public void setLength(double length) {
		this.length = length;
	}
}


		List<Arc> arcs=new ArrayList<Arc>();
		List<Integer> vertexs=new ArrayList<Integer>();
		vertexs.add(1);
		vertexs.add(2);
		vertexs.add(3);
		vertexs.add(4);
		vertexs.add(5);
		arcs.add(new Arc(1,2,10));
		arcs.add(new Arc(1,4,30));
		arcs.add(new Arc(1,5,100));
		arcs.add(new Arc(2,3,50));
		arcs.add(new Arc(3,5,10));
		arcs.add(new Arc(4,3,20));
		arcs.add(new Arc(4,5,60));
		
		
		
		Dijstra dj=new Dijstra(arcs,vertexs);//Dijstra找全局最优
		dj.init(1);
		dj.execute();
		List<Integer> result=dj.getShortestPath(5);
		System.out.println(result.toString());



你可能感兴趣的:(java 实现的Dijstra算法)