Dijkstra算法


上节中介绍了图的两种表示方法:邻接表和邻接矩阵。

本节将基于上面表示的图,求解路径规划问题。

BFS DFS算法

算法用途:遍历图的每个节点;求解无权图的最短路径
算法思想:
BFS
	1、使用队列,从起点开始,不断将邻接点加入队列进行访问。
DFS
	1、使用栈,从起点开始,不断将邻接点入栈(递归进行)。

Dijkstra算法

算法用途:求解有权图(没有负权值)的最短路径规划问题
算法思想:
	1、维护两个list,一个openList(访问过的节点),一个close(未访问的节点)
	2、从起点开始,每访问一个节点,就将其邻接点加入openList中,并更新起点到每个节点的权值和
	3、从openList中取出权值和最小的节点加入openList中
	4、不断重复,当closeList为空或取到终点时,done

具体过程如下:

1、图的表示如下:
在这里插入图片描述
2、不断从U(closeList)中选取最小的节点放入openList中,更新权值的时候记得更新parent值,方便后面回溯求得path。
在这里插入图片描述
3、closeList访问完毕或访问到终点,算法结束:
在这里插入图片描述

代码实现

java实现:


/**
* 图的顶点
*/
private static class Vertex{
	String data;
	Vertex(String data){
		this.data = data;
	}
}
/**
* 图的边
*/
private static class Edge{
	int index;
	int weight;
	Edge(int index,int weight){
		this.index = index;
		this.weight = weight;
	}
}
/**
* 图
*/
private static class Graph{
	private Vertex[] vertexes; // 所有顶点
	private LinkedList<Edge> adj[]; // 所有边
	Graph(int size){
		// 初始化顶点和邻接矩阵
		vertexes =new Vertex[size];
		adj =new LinkedList[size];
		for(int i=0; i<adj.length; i++){
			adj[i]=new LinkedList<Edge>();
		}
	}
}

/**
* Dijkstra最短路径算法
*/
public static Map<Integer,Integer> dijkstra(Graph graph,int startIndex){
	//创建距离表,存储从起点到每一个顶点的临时距离,closeList + openList
	Map<Integer,Integer> distanceMap =new HashMap<Integer,Integer>();
	//记录遍历过的顶点,openList
	Set<Integer> accessedSet =new HashSet<Integer>();
	//图的顶点数量
	int size = graph.vertexes.length;
	//初始化最短路径表,到达每个顶点的路径代价默认为无穷大
	for(int i=1; i<size; i++){
		distanceMap.put(i,Integer.MAX_VALUE);
	}
	//遍历起点,刷新距离表
	accessedSet.add(0);
	List<Edge> edgesFromStart = graph.adj[startIndex];// 遍历邻接点
	for(Edge edge : edgesFromStart)
	{
		distanceMap.put(edge.index, edge.weight);
	}
	//主循环,重复 遍历最短距离顶点和刷新距离表 的操作
	for(int i=1; i<size; i++)
	{
		//寻找最短距离顶点
		int minDistanceFromStart =Integer.MAX_VALUE;
		int minDistanceIndex =-1;
		for(int j=1; j<size; j++) // 遍历求权值最小的节点
		{
			if(!accessedSet.contains(j)&& distanceMap.get(j)< minDistanceFromStart)
			{
				minDistanceFromStart = distanceMap.get(j);
				minDistanceIndex = j;
			}
		}
		if(minDistanceIndex ==-1){
			break;
		}
		//遍历邻接点,刷新距离表
		accessedSet.add(minDistanceIndex);
		for(Edge edge : graph.adj[minDistanceIndex])
		{
			if(accessedSet.contains(edge.index)){ // openList中的点不用再访问
				continue;
			}
			int weight = edge.weight;
			int preDistance = distanceMap.get(edge.index);
			if(weight !=Integer.MAX_VALUE &&(minDistanceFromStart+ weight < preDistance))
			{
				distanceMap.put(edge.index, minDistanceFromStart + weight);
			}
		}
	}
	return distanceMap;
}
public static void main(String[] args){
	Graph graph =newGraph(7);
	initGraph(graph);
	Map<Integer,Integer> distanceMap = dijkstra(graph,0);
	int distance = distanceMap.get(6);
	System.out.println(distance);
}

private static void initGraph(Graph graph){
	graph.vertexes[0]=newVertex("A");
	graph.vertexes[1]=newVertex("B");
	graph.vertexes[2]=newVertex("C");
	graph.vertexes[3]=newVertex("D");
	graph.vertexes[4]=newVertex("E");
	graph.vertexes[5]=newVertex("F");
	graph.vertexes[6]=newVertex("G");
	graph.adj[0].add(newEdge(1,5));
	graph.adj[0].add(newEdge(2,2));
	graph.adj[1].add(newEdge(0,5));
	graph.adj[1].add(newEdge(3,1));
	graph.adj[1].add(newEdge(4,6));
	graph.adj[2].add(newEdge(0,2));
	graph.adj[2].add(newEdge(3,6));
	graph.adj[2].add(newEdge(5,8));
	graph.adj[3].add(newEdge(1,1));
	graph.adj[3].add(newEdge(2,6));
	graph.adj[3].add(newEdge(4,1));
	graph.adj[3].add(newEdge(5,2));
	graph.adj[4].add(newEdge(1,6));
	graph.adj[4].add(newEdge(3,1));
	graph.adj[4].add(newEdge(6,7));
	graph.adj[5].add(newEdge(2,8));
	graph.adj[5].add(newEdge(3,2));
	graph.adj[5].add(newEdge(6,3));
	graph.adj[6].add(newEdge(4,7));
	graph.adj[6].add(newEdge(5,3));
}

python实现:
参考仓库https://github.com/AtsushiSakai/PythonRobotics

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值