图之单源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算法是指对 ...
随机推荐
- Dubbo广播模式下报错:Can't assign requested address解决办法
原因: 尝试使用Dubbo的multicast模式,发现一运行就报Can't assign requested address的错误,造成这种原因的主要是系统中开启了IPV6协议(比如window7) ...
- 用yii2给app写接口(上)
Yii2如何实现RESTful风格的API 1.建立单独的应用程序 为了增加程序的可维护性,易操作性,我们选择新建一套应用程序,这也是为了和前台应用.后台应用区分开操作.有些人要嚷嚷了,为啥非得单独搞 ...
- UVA129
坑点在于输出格式. 四个字母一个空格,行末没有空格,64个字母换行重新打印. AC代码 #include<cstdio> const int maxn=200; int cnt; int ...
- java的mac自动化-自动运行java程序
本文旨在帮助读者介绍,如果一个测试工程师拿到了mac本,该如何在本地自动运行java代码 首先如图所示写下如下一段代码 package zlr;import org.junit.Test;public ...
- layui的几个简单使用(简单弹窗,加载效果,移除加载效果)
1.加载效果和移除加载效果 function layuiLoading(msg){ layui.use(['layer', 'form'], function(){ index = layer.loa ...
- Hive:子查询
Hive只支持在FROM子句中使用子查询,子查询必须有名字,并且列必须唯一:SELECT ... FROM(subquery) name ...
- CDN中前端层的复制
前端层的复制是为了提高静态内容分发的性能和可扩展性.将静态内容的分发转由边缘服务器来完成是为了解决可扩展性的问题,因为这样做可以避免出现在对等点和广域网链路处的网络拥堵风险,而这两个地方的拥堵是网络延 ...
- Typescript 基础应用
什么是 TypeScript TypeScript 是微软开发的 JavaScript 的超集,TypeScript兼容JavaScript,可以载入JavaScript代码然后运行.TypeScri ...
- 【DDD】领域驱动设计实践 —— 一些问题及想法
在社区系统的DDD实践过程中,将遇到一些问题和产生的想法记录下来,共讨论. 本文为[DDD]系列文章中的其中一篇,其他内容可参考:使用领域驱动设计思想实现业务系统. 1.dto.model和entit ...
- FULL HD
FULL HD(全高清)是Full High Definition的简写,是指物理分辨率高达1920×1080显示(包括1080i和1080P),其中i(interlace)是指隔行扫描:P(Prog ...