图之单源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对excel表格上传和下载的处理方法
详见:http://www.jb51.net/article/120443.htm
- Visual Studio 环境路径答疑!
工程目录结构如下: Console │ Console.sln │ Console.VC.db │ ├─Console │ │ Console.cpp │ │ Console.vcxproj │ │ ...
- UVA - 11636 Hello World! (贪心)
思路:复制次数最少并且可以部分复制,那么贪心地让当前尽量多的复制,如果最后一次复制会超过n,那就部分复制.即满足并且x尽量小. AC代码 #include <stdio.h> const ...
- 修长城 (区间DP)
Time Limit: 1000 ms Memory Limit: 256 MB Description 大家都知道,长城在自然条件下会被侵蚀,因此,我们需要修复.现在是21世纪,修复长城的事情当 ...
- Docker MariaDB 10.3 Galera Cluster 集群同步复制 多主 Docker Haproxy 负载均衡
mariadb 现有动态列,支持json格式存储,类似mongodb的bson,但是操作能力较为尴尬,中间件有spider,我非常感兴趣的一个东西 关于spider 这里有一篇很好的博文,有时间一定得 ...
- 使用IntelliJ IDEA 和 Maven创建Java Web项目
1. Maven简介 相对于传统的项目,Maven 下管理和构建的项目真的非常好用和简单,所以这里也强调下,尽量使用此类工具进行项目构建, 它可以管理项目的整个生命周期. 可以通过其命令做所有相关的工 ...
- Java 多线程入门
进程与线程 在学习Java多线程之前,先简单复习一下进程与线程的知识. 进程:进程是系统进行资源分配和调度的基本单位,可以将进程理解为一个正在执行的程序,比如一款游戏. 线程:线程是程序执行的最小单位 ...
- caffe+GPU︱AWS.G2+Ubuntu14.04+GPU+CUDA8.0+cudnn8.0
国服亚马逊的GPU实例G2.2xlarge的python+caffe的安装过程,被虐- 一周才装出来- BVLC/caffe的在AWS安装的官方教程github: https://github.com ...
- JLINK(SEGGER)灯不亮 USB不识别固件修复、clone修改
今天调SMT32插拔几下,JLINK竟然挂掉了网上找了这个教程,搞了半天才搞好,驱动没装好!WIN7系统,自动安装的驱动是GPS.COM10,郁闷,错误来的.应该是:atm6124.sys.要手动选择 ...
- Struts2实现文件上传(四)
Struts2实现文件上传 配置文件struts.xml <!-- /* * $Id: struts.xml 1364077 2012-07-21 12:57:02Z lukaszlenart ...