▶ 书中第四章部分程序,包括在加上自己补充的代码,无环图最短 / 最长路径通用程序,关键路径方法(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. phinx 使用指南

    一 使用 第一步 安装 composer require robmorgan/phinx第二步 初始化php vendor/robmorgan/phinx/bin/phinx init创建目录db/m ...

  2. 模拟a标签click,弹出新页面

    $("<a>").attr("href", url).attr("target", "_blank")[0] ...

  3. uoj#187. 【UR #13】Ernd

    http://uoj.ac/problem/187 每个点只能从时间,b+a,b-a三维都不大于它的点转移过来,将点按时间分成尽量少的一些段,每段内三维同时非严格单调,每段内的点可能因为连续选一段而产 ...

  4. 1.汇编指令介绍(arm)

    本文作为本人学习过程中的记录及时不时的突发奇想偶记.鄙人菜鸟一只,文中如有错误或疏漏,若读者肯不吝赐教,在下感激零涕.文章一直不断更新中 一.汇编语言 汇编语言是一种应用计算机.微处理器.微控制器或其 ...

  5. 迭代器和增强for

    增强for 内部原理其实是个Iterator迭代器,所以在遍历的过程中,不能对集合中的元素进行增删操作. 格式: for(元素的数据类型  变量 : Collection集合or数组){ } 它用于遍 ...

  6. java高并发编程(四)高并发的一些容器

    摘抄自马士兵java并发视频课程: 一.需求背景: 有N张火车票,每张票都有一个编号,同时有10个窗口对外售票, 请写一个模拟程序. 分析下面的程序可能会产生哪些问题?重复销售?超量销售? /** * ...

  7. PAT 乙级 1027 打印沙漏(20) C++版

    1027. 打印沙漏(20) 时间限制 200 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 本题要求你写个程序把给定的符号打印成 ...

  8. 运行java飞行记录器JFR(java flight recorder)

    JFR 上面讲到的工具都是作为快速的查看诊断工具的.如果要深入分析问题,可以选择使用内置的Java飞行记录器:Java Mission Control. 转储JFR需要三步: 1. 创建一个包含了你自 ...

  9. 客户端负载均衡Ribbon之一:Spring Cloud Netflix负载均衡组件Ribbon介绍

    Netflix:['netfliːks] ribbon:英[ˈrɪbən]美[ˈrɪbən]n. 带; 绶带; (打印机的) 色带; 带状物;v. 把…撕成条带; 用缎带装饰; 形成带状;     L ...

  10. Java-Runoob-高级教程-实例-方法:05. Java 实例 – 阶乘

    ylbtech-Java-Runoob-高级教程-实例-方法:05. Java 实例 – 阶乘 1.返回顶部 1. Java 实例 - 阶乘  Java 实例 一个正整数的阶乘(英语:factoria ...