图之单源Dijkstra算法、带负权值最短路径算法
1、图类基本组成
存储在邻接表中的基本项
/**
* Represents an edge in the graph
*
*/
class Edge implements Comparable<Edge> {
public Vertex dest; //Second vertex in Edge
public double cost; //Edge cost public Edge(Vertex d, double c) {
dest = d;
cost = c;
} @Override
public int compareTo(Edge o) {
double otherCost = o.cost;
return cost < otherCost ? -1 : cost > otherCost ? 1 : 0;
} @Override
public String toString() {
return "Edge{" + "dest=" + dest + ", cost=" + cost + '}';
}
}
存储每个顶点信息
/**
* Represents a vertex in the graph
*/
class Vertex {
public String name;
public List<Edge> adj;//Adjacent vertices
public double dist;
public Vertex prev;
public int scratch;//Extra variable used in algorithm public Vertex(String name) {
this.name = name;
adj = new LinkedList<Edge>();
reset();
} public void reset() {
dist = Graph.INFINITY;
prev = null;
scratch = 0;
} @Override
public String toString() {
return "Vertex{" + "name='" + name + '\'' + ", prev=" + prev + ", adj=" + adj + ", dist=" + dist + '}';
}
}
图类的框架
import java.util.*; /**
* Created by Vanguard on 2017/4/6.
*/
public class Graph {
public static final double INFINITY = Double.MAX_VALUE;
private Map<String, Vertex> vertexMap = new HashMap<String, Vertex>(); public void addEdge(String sourceName, String destName, double cost) {
Vertex v = getVertex(sourceName);
Vertex w = getVertex(destName);
v.adj.add(new Edge(w, cost));
} /**
* 通过查询图的表,打印最短路径
*
* @param destName
*/
public void printPath(String destName) {
Vertex w = vertexMap.get(destName);
if (w == null) {
System.out.println("NoSuchElementException");
return;
} else if (w.dist == INFINITY) {
System.out.println(destName + " is unreachable.");
} else {
System.out.print("(Cost is: " + w.dist + ") ");
printPath(w);
System.out.println();
}
} private void printPath(Vertex dest) {
if (dest.prev != null) {
printPath(dest.prev);
System.out.print(" --> ");
}
System.out.print(dest.name);
} private Vertex getVertex(String vertexName) {
Vertex v = vertexMap.get(vertexName);
if (v == null) { //create if not exist.
v = new Vertex(vertexName);
vertexMap.put(vertexName, v);
}
return v;
} private void clearAll() {
for (Vertex v : vertexMap.values()) {
v.reset();
}
}
}
2、最短路径算法
广度优先搜索
/**
* Single-source unweighted shortest-path algorithm.
* 无权单源最短路径算法——广度优先搜索
*
* @param startName
*/
public void unweighted(String startName) {
clearAll();
Vertex start = vertexMap.get(startName);
if (start == null) {
throw new NoSuchElementException("Start vertex not fond.");
}
Queue<Vertex> q = new LinkedList<Vertex>();
q.add(start);
start.dist = 0;
while (!q.isEmpty()) {
Vertex v = q.remove();
for (Edge e : v.adj) {
Vertex w = e.dest;
if (w.dist == INFINITY) {
w.dist = v.dist + 1;
w.prev = v;
q.add(w);
}
}
}
}
Dijstra算法
/**
* Single-source unweighted shortest-path algorithm.
* 无权单源最短路径算法——广度优先搜索
*
* @param startName
*/
public void unweighted(String startName) {
clearAll();
Vertex start = vertexMap.get(startName);
if (start == null) {
throw new NoSuchElementException("Start vertex not fond.");
}
Queue<Vertex> q = new LinkedList<Vertex>();
q.add(start);
start.dist = 0;
while (!q.isEmpty()) {
Vertex v = q.remove();
for (Edge e : v.adj) {
Vertex w = e.dest;
if (w.dist == INFINITY) {
w.dist = v.dist + 1;
w.prev = v;
q.add(w);
}
}
}
}
带负权值得最短路径算法
/**
* Single-source negative-weighted shortest-path algorithm.
* 带负权值得最短路径算法
*
* @param startName
*/
public void negative(String startName) {
clearAll(); Vertex start = vertexMap.get(startName);
if (start == null) {
throw new NoSuchElementException("Start vertex not fond.");
}
Queue<Vertex> q = new LinkedList<>();
q.add(start);
start.dist = 0;
start.scratch++;
while (!q.isEmpty()) {
Vertex v = q.remove();
if (v.scratch++ > 2 * vertexMap.size()) {
System.out.println("Negative cycle detected.");
}
for (Edge e : v.adj) {
Vertex w = e.dest;
double costvw = e.cost;
if (w.dist > v.dist + costvw) {
w.dist = v.dist + costvw;
w.prev = v;
//Enqueue only if not already on the queue
if (w.scratch++ % 2 == 0)
q.add(w);
else
w.scratch--;
}
} }
}
THE END.
图之单源Dijkstra算法、带负权值最短路径算法的更多相关文章
- Expm 10_1 带负权值边的有向图中的最短路径问题
[问题描述] 对于一个带负权值边的有向图,实现Bellman-Ford算法,求出从指定顶点s到其余顶点的最短路径,并判断图中是否存在负环. package org.xiu68.exp.exp10; p ...
- 非负权值有向图上的单源最短路径算法之Dijkstra算法
问题的提法是:给定一个没有负权值的有向图和其中一个点src作为源点(source),求从点src到其余个点的最短路径及路径长度.求解该问题的算法一般为Dijkstra算法. 假设图顶点个数为n,则针对 ...
- Wormholes 最短路判断有无负权值
Description While exploring his many farms, Farmer John has discovered a number of amazing wormholes ...
- poj 3259 Wormholes 判断负权值回路
Wormholes Time Limit: 2000 MS Memory Limit: 65536 KB 64-bit integer IO format: %I64d , %I64u Java ...
- SPFA 最短路 带负权边的---- 粗了解
SPFA(Shortest Path Faster Algorithm)是Bellman-Ford算法的一种队列实现,减少了不必要的冗余计算. 算法大致流程是用一个队列来进行维护. 初始时将源加入队列 ...
- Bellman-Ford算法——解决负权边
Dijkstra算法虽然好,但是它不能解决带有负权边(边的权值为负数)的图. 接下来学习一种无论在思想上还是在代码实现上都可以称为完美的最短路径算法:Bellman-Ford算法. Bellman-F ...
- POJ-2195 Going Home---KM算法求最小权值匹配(存负边)
题目链接: https://vjudge.net/problem/POJ-2195 题目大意: 给定一个N*M的地图,地图上有若干个man和house,且man与house的数量一致.man每移动一格 ...
- 分布式技术专题-分布式协议算法-带你彻底认识Paxos算法、Zab协议和Raft协议的原理和本质
内容简介指南 Paxo算法指南 Zab算法指南 Raft算法指南 Paxo算法指南 Paxos算法的背景 [Paxos算法]是莱斯利·兰伯特(Leslie Lamport)1990年提出的一种基于消息 ...
- 理解KNN算法中的k值-knn算法中的k到底指的是什么 ?
2019-11-09 20:11:26为方便自己收藏学习,转载博文from:https://blog.csdn.net/llhwx/article/details/102652798 knn算法是指对 ...
随机推荐
- Java long类型和Long类型的那些事
还记得最近做了一个项目使用的是Long类型作为主键Id坑死人了,对于我们来说Long类型一样是一个包装类型,类似String类型,使用==符号进行比较的时候有时候会出现问题,建议适应equal()方法 ...
- Yii2中把路由地址中的%2F改为/
第一步:找到/vendor/yiisoft/yii2/web/UrlManager.php 第二步:搜索$url = "$baseUrl?{$this->routeParam}=&qu ...
- 为什么要使用Docker?
作为一种新兴的虚拟化方式,Docker跟传统的虚拟化方式相比具有众多的优势. 更高效的利用系统资源 由于容器不需要进行硬件虚拟及运行完整操作系统等额外开销,Docker对系统资源的利用率更高.无论是应 ...
- 《android开发艺术探索》读书笔记(十一)--Android的线程和线程池
接上篇<android开发艺术探索>读书笔记(十)--Android的消息机制 No1: 在Android中可以扮演线程角色的有很多,比如AsyncTask.IntentService.H ...
- Docker系统八:Docker的存储驱动
Docker存储驱动 1. Docker存储驱动历史 Docker目前支持的greph driver包括: AUFS device-mapper btrfs overlayfs(重点) 关于各存储驱的 ...
- SMJobBless官方Demo笔记
SMJobBless是苹果官方提供的用于"MacOS app获取root权限"的demo. 具体思路 使用Security.framework和ServiceManagement. ...
- URL末尾处的斜杠“/”
在输入网址的时候,比如输入"http://www.xxx.com/",此URL中末尾的斜杠是至关重要的.因为在这种情况下,浏览器能安全的添加斜杠.而像"http://ww ...
- ASP.NET没有魔法——ASP.NET MVC 模型绑定解析(下篇)
上一篇<ASP.NET没有魔法——ASP.NET MVC 模型绑定解析(上篇)>文章介绍了ASP.NET MVC模型绑定的相关组件和概念,本章将介绍Controller在执行时是如何通过这 ...
- 如何编译linux第一个模块 hellomod.ko
Linux下的驱动程序也没有听上去的那么难实现,我们可以看一下helloworld这个例子就完全可以了解它的编写的方式! 我们还是先看一个这个例子,helloworld 1. [代码]hellowor ...
- Eviews 9.0新功能——估计方法(ARDL、面板自回归、门限回归)
每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- 9.2 估计功能 eviews9.0下载链接: ...