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

● 无环图最短 / 最长路径通用程序

 package package01;

 import edu.princeton.cs.algs4.In;
import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.Topological;
import edu.princeton.cs.algs4.DirectedEdge;
import edu.princeton.cs.algs4.EdgeWeightedDigraph;
import edu.princeton.cs.algs4.Stack; public class class01
{
private double[] distTo; // 起点到各顶点的距离
private DirectedEdge[] edgeTo; // 引入各顶点时引入的边 public class01(EdgeWeightedDigraph G, int s)
{
distTo = new double[G.V()];
edgeTo = new DirectedEdge[G.V()];
for (int v = 0; v < G.V(); v++)
distTo[v] = Double.POSITIVE_INFINITY; // 求最长路径时改为 distTo[v] = Double.POSITIVE_INFINITY;
distTo[s] = 0.0;
Topological topological = new Topological(G); // 堆图 G 进行拓扑排序
if (!topological.hasOrder())
throw new IllegalArgumentException("\n<Constructor> Digraph is not acyclic.\n");
for (int v : topological.order()) // 依照拓扑顺序松弛每条边
{
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 的距离变短
{ // 求最长路径时将其改为 if (distTo[w] < distTo[v] + e.weight())
distTo[w] = distTo[v] + e.weight(); // 确认加入该边
edgeTo[w] = e;
}
} public double distTo(int v)
{
return distTo[v];
} public boolean hasPathTo(int v)
{
return distTo[v] < Double.POSITIVE_INFINITY;// 求最长路径时将其改为 return distTo[v] < Double.POSITIVE_INFINITY;
} public Iterable<DirectedEdge> pathTo(int v)
{
if (!hasPathTo(v))
return null;
Stack<DirectedEdge> path = new Stack<DirectedEdge>();
for (DirectedEdge e = edgeTo[v]; e != null; e = edgeTo[e.from()])
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 v = 0; v < G.V(); v++)
{
if (sp.hasPathTo(v))
{
StdOut.printf("%d to %d (%.2f) ", s, v, sp.distTo(v));
for (DirectedEdge e : sp.pathTo(v))
StdOut.print(e + " ");
StdOut.println();
}
else
StdOut.printf("%d to %d no path\n", s, v);
}
}
}

● 关键路径方法(critical path method)解决任务调度问题

 package package01;

 import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.AcyclicLP;
import edu.princeton.cs.algs4.DirectedEdge;
import edu.princeton.cs.algs4.EdgeWeightedDigraph; public class class01
{
private class01() {} public static void main(String[] args)
{
int n = StdIn.readInt(); // 任务数
int source = 2 * n; // 0 ~ n-1 为各任务起点,n ~ 2n-1 为各任务终点
int sink = 2 * n + 1; // 2n 为总起点,2n + 1 为总终点
EdgeWeightedDigraph G = new EdgeWeightedDigraph(2 * n + 2);
for (int i = 0; i < n; i++)
{
double duration = StdIn.readDouble(); // 第一列,任务耗时
G.addEdge(new DirectedEdge(source, i, 0.0)); // 总起点到任务起点的边
G.addEdge(new DirectedEdge(i + n, sink, 0.0)); // 任务终点到总终点的边
G.addEdge(new DirectedEdge(i, i + n, duration)); // 任务起点到任务终点的边 int m = StdIn.readInt(); // 以该任务完成为前提的其他任务数
for (int j = 0; j < m; j++)
{
int precedent = StdIn.readInt(); // 后续任务的编号
G.addEdge(new DirectedEdge(n + i, precedent, 0.0)); // 添加本任务终点到后续任务起点的边
}
} AcyclicLP lp = new AcyclicLP(G, source); // 生成最长路径图,尽量选权值较大的边意味着尽量把任务往前靠
StdOut.println(" job start finish");
StdOut.println("--------------------");
for (int i = 0; i < n; i++)
StdOut.printf("%4d %7.1f %7.1f\n", i, lp.distTo(i), lp.distTo(i + n));
StdOut.printf("Finish time: %7.1f\n", lp.distTo(sink));
}
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. DOM confirm setTimeout url刷新

    console.log 输出框 alert 弹出框 confirm 确认框 // URL和刷新 location.href 获取URL location.href = "url" ...

  2. vmware虚拟机三种网络模式的区别

    首先安装了VMware,在其中安装了Ubuntu系统,正常启动之后开始考虑怎么才能够让主机和虚拟机实现网络互连并且由主机向虚拟机发送文件,通过在网上查阅相关资料,记录学习笔记如下. 学习参考资料: l ...

  3. SQL删除指定列的指定长度的字符

    update );

  4. 一个简单的springmvc例子 入门(1)

    一直是从事棋牌游戏,平常用的东西 大多数只是使用一些javase的一些 api对spring 这方面 用到的比较少,每次学了都忘,始终记不住.为了 更轻松学习springboot,从新学习了sprin ...

  5. JVM异常之:栈溢出StackOverflowError

    在java虚拟机规范中,虚拟机栈和本地方法栈都会出现StackOverflowError和OutofMemoryError,程序计数器是java虚拟机中唯一一块不会产生error的内存区域. 一.St ...

  6. mysql查询优化之一:mysql查询优化常用方式

    一.为什么查询速度会慢? 一个查询的生命周期大致可以按照顺序来看:从客户端,到服务器,然后在服务器上进行解析,生成执行计划,执行,并返回结果给客户端.其中在“执行”阶段包含了大量为了检索数据到存储引擎 ...

  7. C# 读写 ini 配置文件

    虽说 XML 文件越发流行,但精简的 ini 配置文件还是经常会用到,在此留个脚印. 当然,文中只是调用系统API,不会报错,如有必要,也可以直接以流形式读取 ini文件并解析. /// <su ...

  8. 廖雪峰Java5集合-4Set-1使用Set

    集合 Set用于存储不重复的元素集合: boolean add(E e) boolean remove(Object o) boolean contains(Object o) int size() ...

  9. go语言笔记——切片函数常见操作,增删改查和搜索、排序

    7.6.6 搜索及排序切片和数组 标准库提供了 sort 包来实现常见的搜索和排序操作.您可以使用 sort 包中的函数 func Ints(a []int) 来实现对 int 类型的切片排序.例如  ...

  10. 阿里云线上ROS静态路由转发,有大坑。

    原因见上去,阿里云不支持VPC中转流量,VPC1和VPC2都在国内,VPC3在香港,如果按阿里云的做法,必须付费2次国际隧道的钱,才可以实现三个VPC互通.明显很浪费钱. 所以我们只能在三个VPC,各 ...