▶ 书中第四章部分程序,包括在加上自己补充的代码,Dijkstra 算法求有向 / 无向图最短路径,以及所有顶点对之间的最短路径

● Dijkstra 算法求有向图最短路径

 package package01;

 import edu.princeton.cs.algs4.In;
import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.DirectedEdge;
import edu.princeton.cs.algs4.EdgeWeightedDigraph;
import edu.princeton.cs.algs4.Stack;
import edu.princeton.cs.algs4.IndexMinPQ; public class class01
{
private double[] distTo; // 起点到各顶点的距离
private DirectedEdge[] edgeTo; // 由于引入顶点 v 使得图中新增加的边记作 edgeTo[v]
private IndexMinPQ<Double> pq; // 搜索队列 public class01(EdgeWeightedDigraph G, int s)
{
for (DirectedEdge e : G.edges()) // 确认所有变的权值为正
{
if (e.weight() < 0)
throw new IllegalArgumentException("\n<Constructor> e.weight < 0.\n");
}
distTo = new double[G.V()];
edgeTo = new DirectedEdge[G.V()];
for (int v = 0; v < G.V(); v++)
distTo[v] = Double.POSITIVE_INFINITY;
distTo[s] = 0.0; // 起点
pq = new IndexMinPQ<Double>(G.V());
for (pq.insert(s, distTo[s]); !pq.isEmpty();) // 每次从搜索队列中取出一个顶点,松弛与之相连的所有边
{
int v = pq.delMin();
for (DirectedEdge e : G.adj(v))
relax(e);
}
} private void relax(DirectedEdge e)
{
int v = e.from(), w = e.to();
if (distTo[w] > distTo[v] + e.weight()) // 加入这条边会使起点到 w 的距离变短
{
distTo[w] = distTo[v] + e.weight(); // 加入该条边,更新 w 距离
edgeTo[w] = e;
if (pq.contains(w)) // 若 w 已经在搜索队列中
pq.decreaseKey(w, distTo[w]); // 更新 w 在搜索队列中的权值为当前起点到 w 的距离
else
pq.insert(w, distTo[w]); // 否则将顶点 w 加入搜索队列
}
} public double distTo(int v)
{
return distTo[v];
} public boolean hasPathTo(int v)
{
return distTo[v] < Double.POSITIVE_INFINITY;
} public Iterable<DirectedEdge> pathTo(int v) // 生成起点到 v 的最短路径
{
if (!hasPathTo(v))
return null;
Stack<DirectedEdge> path = new Stack<DirectedEdge>();
for (DirectedEdge e = edgeTo[v]; e != null; e = edgeTo[e.from()]) // 从 v 开始不断寻找父顶点,依次压入栈中
path.push(e);
return path;
} public static void main(String[] args)
{
In in = new In(args[0]);
int s = Integer.parseInt(args[1]);
EdgeWeightedDigraph G = new EdgeWeightedDigraph(in);
class01 sp = new class01(G, s);
for (int t = 0; t < G.V(); t++)
{
if (sp.hasPathTo(t))
{
StdOut.printf("%d to %d (%.2f) ", s, t, sp.distTo(t));
for (DirectedEdge e : sp.pathTo(t))
StdOut.print(e + " ");
StdOut.println();
}
else
StdOut.printf("%d to %d no path\n", s, t);
}
}
}

● Dijkstra 算法求无向图最短路径

 package package01;

 import edu.princeton.cs.algs4.In;
import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.Edge;
import edu.princeton.cs.algs4.EdgeWeightedGraph;
import edu.princeton.cs.algs4.Stack;
import edu.princeton.cs.algs4.IndexMinPQ; public class class01
{
private double[] distTo;
private Edge[] edgeTo;
private IndexMinPQ<Double> pq; public class01(EdgeWeightedGraph G, int s)
{
for (Edge e : G.edges())
{
if (e.weight() < 0)
throw new IllegalArgumentException("\n<Constructor> e.weight < 0.\n");
}
distTo = new double[G.V()];
edgeTo = new Edge[G.V()];
for (int v = 0; v < G.V(); v++)
distTo[v] = Double.POSITIVE_INFINITY;
distTo[s] = 0.0;
pq = new IndexMinPQ<Double>(G.V());
for (pq.insert(s, distTo[s]); !pq.isEmpty();)
{
int v = pq.delMin();
for (Edge e : G.adj(v))
relax(e, v);
}
} private void relax(Edge e, int v) // 无向图没有 from 和 to 分量,需要给出新边已经遍历了的那个顶点
{
int w = e.other(v);
if (distTo[w] > distTo[v] + e.weight())
{
distTo[w] = distTo[v] + e.weight();
edgeTo[w] = e;
if (pq.contains(w))
pq.decreaseKey(w, distTo[w]);
else
pq.insert(w, distTo[w]);
}
} public double distTo(int v)
{
return distTo[v];
} public boolean hasPathTo(int v)
{
return distTo[v] < Double.POSITIVE_INFINITY;
} public Iterable<Edge> pathTo(int v)
{
if (!hasPathTo(v))
return null;
Stack<Edge> path = new Stack<Edge>();
int x = v; // 无向图需要变量记录父顶点,以便向回跳
for (Edge e = edgeTo[v]; e != null; e = edgeTo[x])
{
path.push(e);
x = e.other(x);
}
return path;
} public static void main(String[] args)
{
In in = new In(args[0]);
int s = Integer.parseInt(args[1]);
EdgeWeightedGraph G = new EdgeWeightedGraph(in);
class01 sp = new class01(G, s);
for (int t = 0; t < G.V(); t++)
{
if (sp.hasPathTo(t))
{
StdOut.printf("%d to %d (%.2f) ", s, t, sp.distTo(t));
for (Edge e : sp.pathTo(t))
StdOut.print(e + " ");
StdOut.println();
}
else
StdOut.printf("%d to %d no path\n", s, t);
}
}
}

● Dijkstra 算法求所有顶点对之间的最短路径

 package package01;

 import edu.princeton.cs.algs4.In;
import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.DijkstraSP;
import edu.princeton.cs.algs4.DirectedEdge;
import edu.princeton.cs.algs4.EdgeWeightedDigraph; public class class01
{
private DijkstraSP[] all; public class01(EdgeWeightedDigraph G)
{
all = new DijkstraSP[G.V()];
for (int v = 0; v < G.V(); v++) // 循环,每个点为起点都来一次 DijkstraSP
all[v] = new DijkstraSP(G, v);
} public Iterable<DirectedEdge> path(int s, int t)
{
return all[s].pathTo(t);
} public boolean hasPath(int s, int t)
{
return dist(s, t) < Double.POSITIVE_INFINITY;
} public double dist(int s, int t)
{
return all[s].distTo(t);
} public static void main(String[] args)
{
In in = new In(args[0]);
EdgeWeightedDigraph G = new EdgeWeightedDigraph(in);
class01 spt = new class01(G);
StdOut.printf(" "); // 输出没对定点之间的最小路径距离
for (int v = 0; v < G.V(); v++)
StdOut.printf("%6d ", v);
StdOut.println();
for (int v = 0; v < G.V(); v++)
{
StdOut.printf("%3d: ", v);
for (int w = 0; w < G.V(); w++)
{
if (spt.hasPath(v, w)) StdOut.printf("%6.2f ", spt.dist(v, w));
else StdOut.printf(" Inf ");
}
StdOut.println();
}
StdOut.println();
for (int v = 0; v < G.V(); v++) // 输出每对顶点之间最小路径
{
for (int w = 0; w < G.V(); w++)
{
if (spt.hasPath(v, w))
{
StdOut.printf("%d to %d (%5.2f) ", v, w, spt.dist(v, w));
for (DirectedEdge e : spt.path(v, w))
StdOut.print(e + " ");
StdOut.println();
}
else
StdOut.printf("%d to %d no path\n", v, w);
}
}
}
}

《算法》第四章部分程序 part 16的更多相关文章

  1. 《算法》第四章部分程序 part 19

    ▶ 书中第四章部分程序,包括在加上自己补充的代码,有边权有向图的邻接矩阵,FloydWarshall 算法可能含负环的有边权有向图任意两点之间的最短路径 ● 有边权有向图的邻接矩阵 package p ...

  2. 《算法》第四章部分程序 part 18

    ▶ 书中第四章部分程序,包括在加上自己补充的代码,在有权有向图中寻找环,Bellman - Ford 算法求最短路径,套汇算法 ● 在有权有向图中寻找环 package package01; impo ...

  3. 《算法》第四章部分程序 part 15

    ▶ 书中第四章部分程序,包括在加上自己补充的代码,Kruskal 算法和 Boruvka 算法求最小生成树 ● Kruskal 算法求最小生成树 package package01; import e ...

  4. 《算法》第四章部分程序 part 14

    ▶ 书中第四章部分程序,包括在加上自己补充的代码,两种 Prim 算法求最小生成树 ● 简单 Prim 算法求最小生成树 package package01; import edu.princeton ...

  5. 《算法》第四章部分程序 part 10

    ▶ 书中第四章部分程序,包括在加上自己补充的代码,包括无向图连通分量,Kosaraju - Sharir 算法.Tarjan 算法.Gabow 算法计算有向图的强连通分量 ● 无向图连通分量 pack ...

  6. 《算法》第四章部分程序 part 9

    ▶ 书中第四章部分程序,包括在加上自己补充的代码,两种拓扑排序的方法 ● 拓扑排序 1 package package01; import edu.princeton.cs.algs4.Digraph ...

  7. 《算法》第四章部分程序 part 17

    ▶ 书中第四章部分程序,包括在加上自己补充的代码,无环图最短 / 最长路径通用程序,关键路径方法(critical path method)解决任务调度问题 ● 无环图最短 / 最长路径通用程序 pa ...

  8. 《算法》第四章部分程序 part 13

    ▶ 书中第四章部分程序,包括在加上自己补充的代码,图的前序.后序和逆后续遍历,以及传递闭包 ● 图的前序.后序和逆后续遍历 package package01; import edu.princeto ...

  9. 《算法》第四章部分程序 part 12

    ▶ 书中第四章部分程序,包括在加上自己补充的代码,图的几种补充数据结构,包括无向 / 有向符号图,有权边结构,有边权有向图 ● 无向符号图 package package01; import edu. ...

随机推荐

  1. Python3中Urllib库基本使用

    什么是Urllib? Python内置的HTTP请求库 urllib.request          请求模块 urllib.error              异常处理模块 urllib.par ...

  2. 【linux】之Centos6.x升级glibc

    因为Centos比较保守依赖的glibc最高版本是2.12 rpm -qa|grep glibc strings /lib64/libc.so. |grep GLIBC_ 但是经常我们安装一些源码包, ...

  3. 【maven】之打包不带版本号的问题

    今天在写maven项目的时候发现打包没有带版本号,只有包名 百思不得其解,我翻看之前的项目发现并没有这种情况,最后看了一下文档 发现是自己在build中写了fileName  导致的!删除自定义的fi ...

  4. 用windows自带的ftp.exe实现断点续传的方法

    摘自http://www.jb51.net/article/10604.htm 动画下载地址: http://www.chinesehack.org/soft/book/goonftp-jc.rar ...

  5. 利用cbmakegen导出Code::blocks的Makefile

    首先到官网下载cbmakegen 官网地址:http://developer.berlios.de/projects/cbmakegen/ 也可通过我的百度网盘下载 [windows版本]地址:htt ...

  6. uoj#209. 【UER #6】票数统计

    http://uoj.ac/problem/209 当x!=y时,这个限制条件是确定的,可以枚举总通过数,用组合数计算,当x==y时,这个限制条件表示前x个全部通过或后x个全部通过,只有最大的x有用, ...

  7. [转]短短几年,Ceph如何引爆中国的开源热潮?

    原文:http://article.ccw.com.cn/article/view/131427 ,2018-04-02,本文作者:计世传媒 赵新竹 世民Sammy:非常荣幸有机会在北京Cephalo ...

  8. dropwizard使用cors支持跨域浏览器取不到自定义header问题

    dropwizard支持cors的配置如下: public void run(Configuration conf, Environment environment) { // Enable CORS ...

  9. Linux下的文件操作——基于文件描述符的文件操作(2)

    文件描述符的复制 MMAP文件映射 ftruncate修改文件大小 文件描述符的复制 ​ 系统调用函数dup和dup2可以实现文件描述符的复制,经常用来重定向进程的stdin(0), stdout(1 ...

  10. python中变量的缓存机制

    同一文件中, 变量的缓存机制 (在此范围内的相同值内存地址一样) Number: int:                -5 ~ 正无穷 float:             非负数 bool:  ...