▶ 书中第四章部分程序,包括在加上自己补充的代码,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. 利用VMware虚拟机安装CentOS7

    CentOS7镜像下载:http://isoredirect.centos.org/centos/7/isos/x86_64/CentOS-7-x86_64-DVD-1804.iso VMware虚拟 ...

  2. oracle常用小知识点

    alter table us_studies modify enroldate  default to_char(sysdate,'yyyy-mm-dd'); ALTER TABLE QS_QUEUE ...

  3. Azure SQL 数据库仓库Data Warehouse (3) DWU

    <Windows Azure Platform 系列文章目录> 在笔者的上一篇文章中:Azure SQL 数据库仓库Data Warehouse (2) 架构 介绍了SQL DW的工作节点 ...

  4. 黄聪:实用WordPress SQL查询方法

    为所有文章和页面添加自定义字段 这段代码可以为WordPress数据库内所有文章和页面添加一个自定义字段. 你需要做的就是把代码中的‘UniversalCutomField‘替换成你需要的文字,然后把 ...

  5. python中pip和pygame的安装

    1.安装pip和pygame都很简单.首先咱们来安装pip,官网https://pypi.python.org/pypi/pip#download,下载pip的压缩文件,并将其解压. 我们在cmd的p ...

  6. html json 导出Excel

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  7. 【深度学习】BP反向传播算法Python简单实现

    转载:火烫火烫的 个人觉得BP反向传播是深度学习的一个基础,所以很有必要把反向传播算法好好学一下 得益于一步一步弄懂反向传播的例子这篇文章,给出一个例子来说明反向传播 不过是英文的,如果你感觉不好阅读 ...

  8. Unity3d- 资源

    Data与Resources文件夹一般只读文件放到Resources目录Data用于新建的文件或者要修改的文件============================================= ...

  9. 测试用例脚本,调用其他模块方法的实例(数据分类 appium 和 selenium 看这里)

    1.脚本里调用其他类里面的方法 需要把脚本里面的self.dr 传到其他类里面,其他类里面要先初始化这个self.dr 变成自己类里面的 脚本里面的dr是 appium启动的代码 dr= webdri ...

  10. [UE4]手持多把枪的位置调节

    如果一个角色有多把枪,但是骨骼插槽只有一个,可以通过直接在枪蓝图中调整枪的位置和旋转角度.