《算法》第四章部分程序 part 17
▶ 书中第四章部分程序,包括在加上自己补充的代码,无环图最短 / 最长路径通用程序,关键路径方法(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的更多相关文章
- 《算法》第四章部分程序 part 19
▶ 书中第四章部分程序,包括在加上自己补充的代码,有边权有向图的邻接矩阵,FloydWarshall 算法可能含负环的有边权有向图任意两点之间的最短路径 ● 有边权有向图的邻接矩阵 package p ...
- 《算法》第四章部分程序 part 18
▶ 书中第四章部分程序,包括在加上自己补充的代码,在有权有向图中寻找环,Bellman - Ford 算法求最短路径,套汇算法 ● 在有权有向图中寻找环 package package01; impo ...
- 《算法》第四章部分程序 part 16
▶ 书中第四章部分程序,包括在加上自己补充的代码,Dijkstra 算法求有向 / 无向图最短路径,以及所有顶点对之间的最短路径 ● Dijkstra 算法求有向图最短路径 package packa ...
- 《算法》第四章部分程序 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 13
▶ 书中第四章部分程序,包括在加上自己补充的代码,图的前序.后序和逆后续遍历,以及传递闭包 ● 图的前序.后序和逆后续遍历 package package01; import edu.princeto ...
- 《算法》第四章部分程序 part 12
▶ 书中第四章部分程序,包括在加上自己补充的代码,图的几种补充数据结构,包括无向 / 有向符号图,有权边结构,有边权有向图 ● 无向符号图 package package01; import edu. ...
随机推荐
- NDK学习笔记(三):DynamicKnobs的机制
最近的NDK开发涉及到了动态input及动态knobs的问题. 开发需求如下:建立一个节点,该节点能获取每一个input上游的inputframerange信息. 具体下来就是:需要Node的inpu ...
- C#中数据库事务、存储过程基本用法
SQL 事务 public bool UpdateQsRegisterSql(List<string> ids, int newQueueId, string newQueueName) ...
- 黄聪:VPS服务器轻松备份工具配置
- vue父子组件(1.0)
1.父子组件 在上一篇随笔中展示了vue的组件,当我们继续在组件中写组件,形成组件嵌套的时候,就是我们所说的父子组件了. <!DOCTYPE html> <html lang=&qu ...
- java1.8新特性(四 创建 stream对象)
java1.8 提供了 stream对象 可以用作 对 集合 数组的 一系列操作,都是基于lambda 表达式 ,所以得先熟悉lambda 表达式 集合创建stream对象 // 1.集合创建stre ...
- [UE4]使用另一个相机Scene Capture Component 2D当小地图
挂一个相机(Scene Capture Component 2D)在人物角色的正上方,相机朝下,让UI上的某一块区域看到相机所显示的内容. 一.在人物角色正上方添加相机组件Scene Capture ...
- [UE4]一分钟实现聊天系统
天系统:客户端发消息到服务器端,服务器端把收到的消息广播到所有客户端. 由于聊天对象需要支持“可复制”和每个客户端都发给一个,所以GameInstance.GameModeGameState都不适合存 ...
- [UE4]Reliable,可靠性
1.Reliable,不会丢失,立刻发出,适合重要的事件 2.Unreliable,可能会丢失,适合表现相关的和不重要的事件 3.全部的远程调用都使用Reliable,可能会造成网络拥堵 4.尽量避免 ...
- [UE4]场景加载界面
就可以这样就可以了,当另外一个场景成功打开后,场景加载界面也会自动消失(因为这是加载界面是添加到当前场景). 加上delay是为了在小场景测试的时候可以方便看到加载场景,避免场景加载过快看不到,不加的 ...
- Webpack打包方式及各场景下模块化语法总结
1.nodejs的方式:commonjs var xx =require() modules.exports=xxxx 注意:这种方式引入模块,路径会遵循node的规则,和js的src路径规则不 ...