• 《算法》第四章部分程序 part 17


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

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

     1 package package01;
     2 
     3 import edu.princeton.cs.algs4.In;
     4 import edu.princeton.cs.algs4.StdOut;
     5 import edu.princeton.cs.algs4.Topological;
     6 import edu.princeton.cs.algs4.DirectedEdge;
     7 import edu.princeton.cs.algs4.EdgeWeightedDigraph;
     8 import edu.princeton.cs.algs4.Stack;
     9 
    10 public class class01
    11 {
    12     private double[] distTo;        // 起点到各顶点的距离
    13     private DirectedEdge[] edgeTo;  // 引入各顶点时引入的边
    14 
    15     public class01(EdgeWeightedDigraph G, int s)
    16     {
    17         distTo = new double[G.V()];
    18         edgeTo = new DirectedEdge[G.V()];
    19         for (int v = 0; v < G.V(); v++)
    20             distTo[v] = Double.POSITIVE_INFINITY;       // 求最长路径时改为 distTo[v] = Double.POSITIVE_INFINITY;
    21         distTo[s] = 0.0;
    22         Topological topological = new Topological(G);   // 堆图 G 进行拓扑排序
    23         if (!topological.hasOrder())
    24             throw new IllegalArgumentException("
    <Constructor> Digraph is not acyclic.
    ");
    25         for (int v : topological.order())               // 依照拓扑顺序松弛每条边
    26         {
    27             for (DirectedEdge e : G.adj(v))
    28                 relax(e);
    29         }
    30     }
    31 
    32     private void relax(DirectedEdge e)
    33     {
    34         int v = e.from(), w = e.to();
    35         if (distTo[w] > distTo[v] + e.weight())     // 加入这条边会使起点到 w 的距离变短
    36         {                                           // 求最长路径时将其改为 if (distTo[w] < distTo[v] + e.weight())
    37             distTo[w] = distTo[v] + e.weight();     // 确认加入该边
    38             edgeTo[w] = e;
    39         }
    40     }
    41 
    42     public double distTo(int v)
    43     {
    44         return distTo[v];
    45     }
    46 
    47     public boolean hasPathTo(int v)
    48     {
    49         return distTo[v] < Double.POSITIVE_INFINITY;// 求最长路径时将其改为 return distTo[v] < Double.POSITIVE_INFINITY;
    50     }
    51 
    52     public Iterable<DirectedEdge> pathTo(int v)
    53     {
    54         if (!hasPathTo(v))
    55             return null;
    56         Stack<DirectedEdge> path = new Stack<DirectedEdge>();
    57         for (DirectedEdge e = edgeTo[v]; e != null; e = edgeTo[e.from()])
    58             path.push(e);
    59         return path;
    60     }
    61 
    62     public static void main(String[] args)
    63     {
    64         In in = new In(args[0]);
    65         int s = Integer.parseInt(args[1]);
    66         EdgeWeightedDigraph G = new EdgeWeightedDigraph(in);
    67         class01 sp = new class01(G, s);
    68         for (int v = 0; v < G.V(); v++)
    69         {
    70             if (sp.hasPathTo(v))
    71             {
    72                 StdOut.printf("%d to %d (%.2f)  ", s, v, sp.distTo(v));
    73                 for (DirectedEdge e : sp.pathTo(v))
    74                     StdOut.print(e + "   ");
    75                 StdOut.println();
    76             }
    77             else
    78                 StdOut.printf("%d to %d         no path
    ", s, v);
    79         }
    80     }
    81 }

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

     1 package package01;
     2 
     3 import edu.princeton.cs.algs4.StdIn;
     4 import edu.princeton.cs.algs4.StdOut;
     5 import edu.princeton.cs.algs4.AcyclicLP;
     6 import edu.princeton.cs.algs4.DirectedEdge;
     7 import edu.princeton.cs.algs4.EdgeWeightedDigraph;
     8 
     9 public class class01
    10 {
    11     private class01() {}
    12 
    13     public static void main(String[] args)
    14     {
    15         int n = StdIn.readInt();                                // 任务数
    16         int source = 2 * n;                                     // 0 ~ n-1 为各任务起点,n ~ 2n-1 为各任务终点
    17         int sink = 2 * n + 1;                                   // 2n 为总起点,2n + 1 为总终点
    18         EdgeWeightedDigraph G = new EdgeWeightedDigraph(2 * n + 2);
    19         for (int i = 0; i < n; i++)
    20         {
    21             double duration = StdIn.readDouble();               // 第一列,任务耗时
    22             G.addEdge(new DirectedEdge(source, i, 0.0));        // 总起点到任务起点的边
    23             G.addEdge(new DirectedEdge(i + n, sink, 0.0));      // 任务终点到总终点的边
    24             G.addEdge(new DirectedEdge(i, i + n, duration));    // 任务起点到任务终点的边
    25 
    26             int m = StdIn.readInt();                                // 以该任务完成为前提的其他任务数
    27             for (int j = 0; j < m; j++)
    28             {
    29                 int precedent = StdIn.readInt();                    // 后续任务的编号
    30                 G.addEdge(new DirectedEdge(n + i, precedent, 0.0)); // 添加本任务终点到后续任务起点的边
    31             }
    32         }
    33 
    34         AcyclicLP lp = new AcyclicLP(G, source);    // 生成最长路径图,尽量选权值较大的边意味着尽量把任务往前靠
    35         StdOut.println(" job   start  finish");
    36         StdOut.println("--------------------");
    37         for (int i = 0; i < n; i++)
    38             StdOut.printf("%4d %7.1f %7.1f
    ", i, lp.distTo(i), lp.distTo(i + n));
    39         StdOut.printf("Finish time: %7.1f
    ", lp.distTo(sink));
    40     }
    41 }
  • 相关阅读:
    Oracle9i数据库移动过程
    基于索引的SQL语句优化之降龙十八掌
    activex发布步骤
    用ftpsupport进行ftp上传
    周五晚上看了变形金刚
    故宫游
    UTF8转GB2312
    跨数据库的视图【自己留着看】
    数学之美 - 布隆过滤器(Bloom Filter)【转】
    搜索引擎优化SEO的ppt讲义
  • 原文地址:https://www.cnblogs.com/cuancuancuanhao/p/9836330.html
Copyright © 2020-2023  润新知