Dijkstra算法java现实

先上一张路径图

一共有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所有相连的Node
	public 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->

时间: 2024-10-12 02:27:48

Dijkstra算法java现实的相关文章

Dijkstra算法 java实现

/* * 设置一个U集合,包含最小路径长度和上一个结点 * V-U集合表示还没有进行调整 * 把V-U集合逐渐加入U中,并调整最小路径 * */ public class Dijkstra { private static int MAX = 10000; public static void dijkstra(GraphMatrix grap, Path dist[]){ // 初始化V0 init(grap,dist); int n = dist.length; int minw = MAX

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

做一个无向图的权重单一的最短路径算法. 模拟停车场最近车位的选择. 首先参考了博友JavaMan_chen的博文 http://blog.csdn.net/javaman_chen/article/details/8254309 但是这个算法是有问题的. 算法中,如果A点是当前点,是选取距离A点权重最小的那一点作为下一个路径点的. 这就带来了一个问题,即,距离A点的2个点如果权重相同,那就会随机选取其中一条. 于是,在数据量稍微大点的时候,就出错了. 在这里使用Dijkstra算法使用的是用OP

最短路径算法之Dijkstra算法(java实现)

前言 Dijkstra算法是最短路径算法中为人熟知的一种,是单起点全路径算法.该算法被称为是“贪心算法”的成功典范.本文接下来将尝试以最通俗的语言来介绍这个伟大的算法,并赋予java实现代码. 一.知识准备: 1.表示图的数据结构 用于存储图的数据结构有多种,本算法中笔者使用的是邻接矩阵.  图的邻接矩阵存储方式是用两个数组来表示图.一个一维数组存储图中顶点信息,一个二维数组(邻接矩阵)存储图中的边或弧的信息. 设图G有n个顶点,则邻接矩阵是一个n*n的方阵,定义为: 从上面可以看出,无向图的边

Dijkstra算法Java实现

从最短路径开始,学习Dijstar算法 下面是求最短路径问题描述: 下面是Dijkstar算法的描述: 下面是使用Dijkstar算法求解右图中的问题: 下面是图的邻接矩阵: 下面是计算过程: 下面是求解最短路径: 下面是Java代码实现,其中需要注意的问题我已经标出(一定要细心!!!!): package greedy_algorithm; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSe

(HW)Dijkstra算法(Java)

1 import java.util.Comparator; 2 import java.util.HashMap; 3 import java.util.LinkedList; 4 import java.util.List; 5 import java.util.Map; 6 import java.util.PriorityQueue; 7 import java.util.Stack; 8 9 public class test 10 { 11 public static void ma

Dijkstra算法(三)之 Java详解

前面分别通过C和C++实现了迪杰斯特拉算法,本文介绍迪杰斯特拉算法的Java实现. 目录 1. 迪杰斯特拉算法介绍 2. 迪杰斯特拉算法图解 3. 迪杰斯特拉算法的代码说明 4. 迪杰斯特拉算法的源码 转载请注明出处:http://www.cnblogs.com/skywang12345/ 更多内容:数据结构与算法系列 目录 迪杰斯特拉算法介绍 迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个节点到其他节点的最短路径. 它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想

Dijkstra算法求最短路径(java)(转)

原文链接:Dijkstra算法求最短路径(java) 任务描述:在一个无向图中,获取起始节点到所有其他节点的最短路径描述 Dijkstra(迪杰斯特拉)算法是典型的最短路径路由算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止. Dijkstra一般的表述通常有两种方式,一种用永久和临时标号方式,一种是用OPEN, CLOSE表方式用OPEN,CLOSE表的方式,其采用的是贪心法的算法策略,大概过程如下:1.声明两个集合,open和close

Dijkstra算法应用之Java实现

缘来是你: 前几天在博客园里,有小伙伴贴出华为2010年10K(薪资)员工3级晋级试题. 问题主要是算法实现. 在师兄大批入住华为的环境下,作为一名热爱算法的小伙伴,也想小试一下身手. 问题地址:http://www.cnblogs.com/preacher/p/4126261.html 在解决上述问题前先来复习一下基础知识: Dijkstra最短路径算法 上述问题放在下一期随笔上 算法简析: Dijkstra算法又称为单源最短路径,所谓单源是在一个有向图中,从一个顶点出发,求该顶点至所有可到达

最短路径——dijkstra算法(Java)

在刷题的过程中常常会遇到求最短路径的问题,在求无权图的问题中我们常常使用BFS来求其最短路径,而BFS无法解决网(有权图)中的问题,我们解决网中的最短路径常常使用dijkstra算法来求解. dijkstra算法是一种贪心的思想,具体其正确性的证明,这里就不再赘述.下面来直接讲解如何使用dijkstra算法: 1.我们在使用dijkstra算法时为了其编写的便捷性一般使用邻接矩阵来描述一个图.并将邻接矩阵中每个元素的值初始化为无穷大(或者很大很大的值).之后根据图中的结构加入数字,称这个矩阵为E