Dijkstra算法java现实

来源:互联网 发布:uc davis 人工智能 编辑:程序博客网 时间:2024/05/21 01:29

先上一张路径图


一共有8个点,每个点之间的连线数字,表示这两个点之间的距离,如果两个点之间无直接连线,那么只能通过其它点到达。

Dijkstra算法,网上有逼格较高的定义,描述文字不是太通俗,且不管它。

下面就以求AG的最短路径为例,谈一下具体的算法实现思路:

前提条件:定义一个close集合,分析过的点都放入此集合中,A为起点,首先放入集合。

1.以A为起点,首先寻找离A最近的相连的某个点(上图是C点)

2.找到这个C点后,循环C相连的所有点(其实B和D),重新计算A到B,A到D的临时最短距离(最初A到D不相连,AD之间距离值设为,用Integer.MAX_VALUE表示)并保存。注意此最短距离是临时的,后面路径没有完全搜索之前,可能存在更短的距离。分析过C点后,把C点放入close集合。

3.再次寻找离A最近的某个点(不在close集合中的点,即还没有分析过的点,AF=25,AB=13,AD=15,其实就是B点)

4.然后再以B点执行step2的动作,找到A距离B的所有子节点的临时最短距离,如此反复,直到close集合包括了所有点。

具体java代码如下:

/** *  */package com.test.dijkstra;import java.util.ArrayList;import java.util.HashMap;import java.util.LinkedHashSet;import java.util.List;import java.util.Map;/** * @author chaisson * @since 2015-5-30 上午11:51:59 * */public class Dijkstra {List<Node> openList = new ArrayList<Node>();//未访问过List<Node> closeList = new ArrayList<Node>();//已访问过Node A = new Node("A");Node B = new Node("B");Node C = new Node("C");Node D = new Node("D");Node E = new Node("E");Node F = new Node("F");Node G = new Node("G");Node H = new Node("H");//初始化数据节点之间的关系private void init(){A.linkedNode.add(B);A.linkedNode.add(C);A.linkedNode.add(F);A.setValue(B,14);A.setValue(C,4);A.setValue(F,25);B.linkedNode.add(A);B.linkedNode.add(C);B.linkedNode.add(E);B.setValue(A, 14);B.setValue(C, 9);B.setValue(E, 7);C.linkedNode.add(A);C.linkedNode.add(B);C.linkedNode.add(D);C.setValue(A, 4);C.setValue(B, 9);C.setValue(D, 11);D.linkedNode.add(C);D.linkedNode.add(E);D.linkedNode.add(H);D.setValue(C, 11);D.setValue(E, 12);D.setValue(H, 5);E.linkedNode.add(B);E.linkedNode.add(D);E.linkedNode.add(F);E.linkedNode.add(H);E.setValue(B, 7);E.setValue(D, 12);E.setValue(F, 3);E.setValue(H, 9);F.linkedNode.add(A);F.linkedNode.add(E);F.linkedNode.add(G);F.setValue(A, 25);F.setValue(E, 3);F.setValue(G, 8);G.linkedNode.add(F);G.linkedNode.add(H);G.setValue(F, 8);G.setValue(H, 17);H.linkedNode.add(D);H.linkedNode.add(E);H.linkedNode.add(G);H.setValue(D, 5);H.setValue(E, 9);H.setValue(G, 17);openList.add(A);openList.add(B);openList.add(C);openList.add(D);openList.add(E);openList.add(F);openList.add(G);openList.add(H);}//计算从start到end,走过的路径public void calculate(Node start,Node end){if(closeList.size() == openList.size()){System.out.println(start.getName()+"->"+end.getName()+" min.length.length:"+start.getValue(end));return;}Node childNode = getMinValueNode(start);//找到目前除已经分析过的节点之外的距离start节点最近的节点start.getAllPassNodes(childNode).add(childNode);//记录扩展到当前最近节点所有经过的节点if(childNode == end){System.out.println(start.getName()+"->"+end.getName()+" min.length:"+start.getValue(end));return;}//System.out.println("当前距离"+start.getName()+"最近节点为:"+childNode.getName());for(Node ccNode : childNode.linkedNode){if(closeList.contains(ccNode)){continue;}/** * start节点到距离其最近的一个节点的其中一个子节点的距离(假设有1个或多个子节点) * 即start节点到子子节点的距离 * 重新计算一遍A(假设start就是A,下同)到所有点的距离,与原来的距离相比较 */int ccnodeValue = start.getValue(childNode)+childNode.getValue(ccNode);//超过最大值之后,会变成负数if(Math.abs(ccnodeValue) < start.getValue(ccNode)){start.setValue(ccNode,ccnodeValue);System.out.println(start.getName()+"->"+ccNode.getName()+"的目前最短距离是:"+ccnodeValue);//这个最短距离只是暂时的,只要分析没有结束,最短距离可能进一步缩小start.getAllPassNodes(ccNode).clear();//临时最短距离缩小,所经过路径也清除重新添加start.getAllPassNodes(ccNode).addAll(start.getAllPassNodes(childNode));start.getAllPassNodes(ccNode).add(ccNode);} }closeList.add(childNode);calculate(start,end);//重复计算A到所有点的最短距离之后,再取距离A最短的节点,对其进行子节点分析【往外面节点扩展分析】}//取跟入参节点距离最近的节点,如果有多个相同距离的节点,则随便取其中一个private Node getMinValueNode(Node node){Node retNode = null;int minValue = Integer.MAX_VALUE;for(Node n : node.getValueMap().keySet()){if(closeList.contains(n)){continue;}if(node.getValue(n) < minValue){minValue = node.getValue(n);retNode = n;}}return retNode;}public static void main(String[] args) {Dijkstra d = new Dijkstra();d.init();d.closeList.add(d.A);d.calculate(d.A, d.G);//打印路径for(Node node : d.A.getAllPassNodes(d.G)){System.out.print(node.getName()+"->");}}}class Node {private String name;//记录本Node所有相连的Nodepublic List<Node> linkedNode = new ArrayList<Node>();//记录本Node与其它Node的最短距离private Map<Node,Integer> valueMap = new HashMap<Node,Integer>();//记录从本Node到其它Node之间最短距离时所有经过的节点,并保持前后顺序,其实与valueMap对应private Map<Node,LinkedHashSet<Node>> orderSetMap = new HashMap<Node,LinkedHashSet<Node>>();public Node(String name){this.name = name;}public void setValue(Node node,Integer value){valueMap.put(node, value);}//如果没有本节点到参数节点的取值,则默认最大值public Integer getValue(Node node){return valueMap.get(node) == null? Integer.MAX_VALUE : valueMap.get(node);}public String getName() {return name;}public void setName(String name) {this.name = name;}public Map<Node, Integer> getValueMap() {return valueMap;}//取本节点到参数节点经过的所有节点集合public LinkedHashSet<Node> getAllPassNodes(Node node) {if(orderSetMap.get(node) == null){LinkedHashSet<Node> set = new LinkedHashSet<Node>(); set.add(this);orderSetMap.put(node, set);}return orderSetMap.get(node);}}
main方法执行从A到G的计算,执行结果为:

A->B的目前最短距离是:13
A->D的目前最短距离是:15
A->E的目前最短距离是:20
A->H的目前最短距离是:20
A->G的目前最短距离是:37
A->F的目前最短距离是:23
A->G的目前最短距离是:31
A->G min.length:31
A->C->B->E->F->G->




0 0
原创粉丝点击