感谢每一位朋友的阅读与建议,今天对最短路径blog进行了修改,调整图和部份内容。感谢各位关注。提前祝你们圣诞节平安快乐。java
给定一个带权有向图G=(V,E),其中每条边的权是一个实数。另外,还给定V中的一个顶点,称为源。如今要计算从源到其余全部各顶点的最短路径长度。这里的长度就是指路上各边权之和。这个问题一般称为单源最短路径问题git
借助队列实现每条边只访问一次。github
/** * 无权最短路径 * * @param s 起点 */ public void unweight(Vertex s) { Queue<Vertex> q = new LinkedList<Vertex>(); for (Vertex x : graph) { //每一个节点的初始最短路径为Integer的最大值,表示该节点的最短路径未知 x.setDist(Integer.MAX_VALUE); } s.dist = 0; q.add(s); while (!q.isEmpty()) { Vertex v = q.poll(); if (v != null) { if (v.getAdj() != null && !v.getAdj().isEmpty()) { for (Vertex w : v.getAdj()) { if (w.getDist() == Integer.MAX_VALUE) {//每条边只访问一次 w.setDist(v.getDist()+1); w.setPath(v); q.add(w); } } } } } }
O(|E|+|V|)
Dijkstra算法是解决有权无负值单源最短路径的经典算法。算法
/** * 著名的dijkstra算法 解决单源最短路径(权无负值) * * @param s * 起点 */ public void dijkstra(Vertex s) { for (Vertex v : graph) {// 初始默认全部顶点未被访问 v.setDist(Integer.MAX_VALUE); v.known = false; } s.dist = 0;// 声明起点的距离为0 PriorityQueue<Vertex> priorityQueue = new PriorityQueue<Vertex>(); // 将s放入优先队列 priorityQueue.add(s); while (!priorityQueue.isEmpty()) {// 知道全部顶点的最短路径都已知而且优先队列为空 Vertex v = priorityQueue.poll();// 取出未知节点中最短路径最小的节点 if (v != null) { if (!v.known) { v.known = true;// 声明该节点已知 if (v.getAdj() != null && !v.getAdj().isEmpty()) { // 如 dv+cvw<=dw 则更新临接点的最短路径,而且更新值放入到优先队列中 for (AdjVertex adjW : v.getAdj()) { if (!adjW.getW().known) { if (v.dist + adjW.cvw < adjW.getW().getDist()) { adjW.getW().setDist(v.dist + adjW.cvw); adjW.getW().setPath(v); priorityQueue.add(adjW.getW()); } } } } } } } }
针对一个有权图,该图的权有负值,使用某个顶点s做为输入参数,找出该顶点s到其余顶点的最短距离。url
借助广度优先搜素实现。.net
/** * 有权有负值最短路径 * 借助广度优先搜素 * @param s 起点 */ public void weightNegative(Vertex s) { Queue<Vertex> q = new LinkedList<Vertex>(); for (Vertex v : graph) { v.dist = Integer.MAX_VALUE; v.isInQueue = false; } s.dist = 0; s.isInQueue = true; q.add(s); while (!q.isEmpty()) { Vertex v = q.poll(); v.isInQueue = false; if (v.getAdj() != null && !v.getAdj().isEmpty()) { for (AdjVertex wadj : v.getAdj()) { if (wadj.cvw + v.dist < wadj.getW().dist) { wadj.getW().setDist(wadj.cvw + v.dist); wadj.getW().setPath(v); if (!wadj.getW().isInQueue) { wadj.getW().isInQueue = false; q.add(wadj.getW()); } } } } } }
O(|E|*|V|)
O(|E|+|V|)
Dijkstra是解决有权无负值图单源最短路径的经典算法。3d
若权有负值,借助广度优先搜素与有权无负值最短路径思想结合来解决 ,其时间界限为:code
O(|E|*|V|)
无权无圈最短路径blog