《算法》第四章部分程序 part 16
▶ 书中第四章部分程序,包括在加上自己补充的代码,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的更多相关文章
- 《算法》第四章部分程序 part 19
▶ 书中第四章部分程序,包括在加上自己补充的代码,有边权有向图的邻接矩阵,FloydWarshall 算法可能含负环的有边权有向图任意两点之间的最短路径 ● 有边权有向图的邻接矩阵 package p ...
- 《算法》第四章部分程序 part 18
▶ 书中第四章部分程序,包括在加上自己补充的代码,在有权有向图中寻找环,Bellman - Ford 算法求最短路径,套汇算法 ● 在有权有向图中寻找环 package package01; impo ...
- 《算法》第四章部分程序 part 15
▶ 书中第四章部分程序,包括在加上自己补充的代码,Kruskal 算法和 Boruvka 算法求最小生成树 ● Kruskal 算法求最小生成树 package package01; import e ...
- 《算法》第四章部分程序 part 14
▶ 书中第四章部分程序,包括在加上自己补充的代码,两种 Prim 算法求最小生成树 ● 简单 Prim 算法求最小生成树 package package01; import edu.princeton ...
- 《算法》第四章部分程序 part 10
▶ 书中第四章部分程序,包括在加上自己补充的代码,包括无向图连通分量,Kosaraju - Sharir 算法.Tarjan 算法.Gabow 算法计算有向图的强连通分量 ● 无向图连通分量 pack ...
- 《算法》第四章部分程序 part 9
▶ 书中第四章部分程序,包括在加上自己补充的代码,两种拓扑排序的方法 ● 拓扑排序 1 package package01; import edu.princeton.cs.algs4.Digraph ...
- 《算法》第四章部分程序 part 17
▶ 书中第四章部分程序,包括在加上自己补充的代码,无环图最短 / 最长路径通用程序,关键路径方法(critical path method)解决任务调度问题 ● 无环图最短 / 最长路径通用程序 pa ...
- 《算法》第四章部分程序 part 13
▶ 书中第四章部分程序,包括在加上自己补充的代码,图的前序.后序和逆后续遍历,以及传递闭包 ● 图的前序.后序和逆后续遍历 package package01; import edu.princeto ...
- 《算法》第四章部分程序 part 12
▶ 书中第四章部分程序,包括在加上自己补充的代码,图的几种补充数据结构,包括无向 / 有向符号图,有权边结构,有边权有向图 ● 无向符号图 package package01; import edu. ...
随机推荐
- 自定义自己的jQury插件
对于一个商业插件来说,自定义插件的样式是必不可少的.我们可以通过我们自己输入不同的样式,来改变开发者的默认样式.比如说最常见的 width.height.url.color等等.要是没有这些自定义的东 ...
- TensorFlow:tf.nn.max_pool实现池化操作
tf.nn.max_pool(value, ksize, strides, padding, name=None) 参数是四个,和卷积很类似: 第一个参数value:需要池化的输入,一般池化层接在卷积 ...
- c++中计算程序执行时间
#include<iostream> #include<time.h> using namespace std; int main() { clock_t t1 = clock ...
- .net 4.0 程序遇到 停止工作 appcrash ,kernelbase.dll 等提示
经测试,删除*.exe.config 中 <supportedRuntime version="v4.0" sku=".NETFramework,Version=v ...
- 第一个javascript
系统:windows10 编辑器:NotePad++ 首先开启浏览器的javascript,我的是google浏览器,步骤:设置--高级设置--内容设置--选中“允许所有网站使用javascri ...
- GitHub版本控制入门(新手学习)
要使用GitHub功能,首先要登陆官方网站https://github.com,注册GitHub账号. 在浏览器中的操作: 新建一个仓库.一个项目一旦被Git控制了版本历史,在GitHub上就有另外一 ...
- 数据仓库专题19-数据建模语言Information Engineering - IE模型(转载)
Information Engineering采用Crow's Foot表示法(也有叫做James Martin表示法的),中文翻译中对使用了Crow's Foot表示法的模型也有笼统的称做鸭掌模型的 ...
- Java线程池管理及分布式Hadoop调度框架搭建
平时的开发中线程是个少不了的东西,比如tomcat里的servlet就是线程,没有线程我们如何提供多用户访问呢?不过很多刚开始接触线程的开发工程师却在这个上面吃了不少苦头. 怎么做一套简便的线程开发模 ...
- centos7 安装 codeblock(rpm)
--------------------- 1.yum -y install epel-release 2.yum clean all && yum makecache 3.yum - ...
- API网关之Kong网关简介
1. Kong简介 那么,Kong是一个什么东东呢?它是一个开源的API网关,或者你可以认为它是一个针对API的一个管理工具.你可以在那些上游service之上,额外去实现一些功能.Kong是开源的, ...