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算法、带负权值最短路径算法的更多相关文章

  1. Expm 10_1 带负权值边的有向图中的最短路径问题

    [问题描述] 对于一个带负权值边的有向图,实现Bellman-Ford算法,求出从指定顶点s到其余顶点的最短路径,并判断图中是否存在负环. package org.xiu68.exp.exp10; p ...

  2. 非负权值有向图上的单源最短路径算法之Dijkstra算法

    问题的提法是:给定一个没有负权值的有向图和其中一个点src作为源点(source),求从点src到其余个点的最短路径及路径长度.求解该问题的算法一般为Dijkstra算法. 假设图顶点个数为n,则针对 ...

  3. Wormholes 最短路判断有无负权值

    Description While exploring his many farms, Farmer John has discovered a number of amazing wormholes ...

  4. poj 3259 Wormholes 判断负权值回路

    Wormholes Time Limit: 2000 MS Memory Limit: 65536 KB 64-bit integer IO format: %I64d , %I64u   Java ...

  5. SPFA 最短路 带负权边的---- 粗了解

    SPFA(Shortest Path Faster Algorithm)是Bellman-Ford算法的一种队列实现,减少了不必要的冗余计算. 算法大致流程是用一个队列来进行维护. 初始时将源加入队列 ...

  6. Bellman-Ford算法——解决负权边

    Dijkstra算法虽然好,但是它不能解决带有负权边(边的权值为负数)的图. 接下来学习一种无论在思想上还是在代码实现上都可以称为完美的最短路径算法:Bellman-Ford算法. Bellman-F ...

  7. POJ-2195 Going Home---KM算法求最小权值匹配(存负边)

    题目链接: https://vjudge.net/problem/POJ-2195 题目大意: 给定一个N*M的地图,地图上有若干个man和house,且man与house的数量一致.man每移动一格 ...

  8. 分布式技术专题-分布式协议算法-带你彻底认识Paxos算法、Zab协议和Raft协议的原理和本质

    内容简介指南 Paxo算法指南 Zab算法指南 Raft算法指南 Paxo算法指南 Paxos算法的背景 [Paxos算法]是莱斯利·兰伯特(Leslie Lamport)1990年提出的一种基于消息 ...

  9. 理解KNN算法中的k值-knn算法中的k到底指的是什么 ?

    2019-11-09 20:11:26为方便自己收藏学习,转载博文from:https://blog.csdn.net/llhwx/article/details/102652798 knn算法是指对 ...

随机推荐

  1. linux中/bin和/sbin和/usr/bin和/usr/sbin

    首先先解释一下bin和sbin的意思: 1.bin:为任何用户都可以使用的指令 2.sbin:(super bin)也就是只有超级管理员才能使用的指令 /usr    UNIX Software Re ...

  2. django新手第一课

    django是基于python的一个web框架,大致结构如下: 在pycharm,python2.7,django1.8,mysql都装好的情况下,现在开始django的初试: 一.基础启动djang ...

  3. PHP二维数组排序(感谢滔哥)

    滔哥原创 /* _ooOoo_ o8888888o 88" . "88 (| -_- |) O\ = /O ____/`---'\____ .' \\| |// `. / \\|| ...

  4. JavaScript 一个进行枚举选择的jquery插件(仿easyui风格)

    某次做项目要实现一个功能: 按星期选择一个连续的时间范围 比如:周一到周五,周六到周日 或 周六到周三 聪明的朋友马上想出办法:用两个选项为周一到周日的下拉列表实现,对 那样可以,但是我觉得不够友好, ...

  5. Golang里实现Http服务器并解析header参数和表单参数

    在http服务里,header参数和表单参数是经常使用到的,本文主要是练习在Go语言里,如何解析Http请求的header里的参数和表单参数,具体代码如下: package server import ...

  6. 使用flask_sqlalchemy

    首先引用一下廖雪峰Python教程里关于sqlalchemy的话, 这里我们要讲的是flask_sqlalchemy的用法. 1. 安装 用pip安装即可, 进入cmd控制台输入 pip instal ...

  7. 转: JavaScript 获取对象属性和方法

    一.获取对象属性和方法 Object.keys()for in 返回对象的可枚举属性和方法的名称数组. Object.getOwnPropertyNames() 返回的数组的所有属性(可枚举或不可枚举 ...

  8. 安装STS报错(一)

    安装STS报错 1.具体报错如下 2.报错原因 3.解决办法

  9. python version 2. required,which was not found in the registry 解决方案

    不能在注册表中识别python2.7 新建一个register.py 文件 import sys from _winreg import * # tweak as necessary version ...

  10. Django学习-24-Ajax

    jQuery.Ajax是原生Ajax的封装,它能自动识别浏览器的Ajax对象HttpResponse(status='404',reason='Page Not Found') 原生Ajax使用Xml ...