zoukankan      html  css  js  c++  java
  • 《算法》第四章部分程序 part 9

    ▶ 书中第四章部分程序,包括在加上自己补充的代码,两种拓扑排序的方法

    ● 拓扑排序 1

     1 package package01;
     2 
     3 import edu.princeton.cs.algs4.Digraph;
     4 import edu.princeton.cs.algs4.SymbolDigraph;
     5 import edu.princeton.cs.algs4.DirectedCycle;
     6 import edu.princeton.cs.algs4.DepthFirstOrder;
     7 import edu.princeton.cs.algs4.EdgeWeightedDigraph;
     8 import edu.princeton.cs.algs4.EdgeWeightedDirectedCycle;
     9 
    10 public class class01
    11 {
    12     private Iterable<Integer> order;    // 拓扑排序的结果
    13     private int[] rank;                 // 顶点 v 在拓扑排序中的序号为 rank[v]
    14 
    15     public class01(Digraph G)           // 从有向图生成拓扑排序
    16     {
    17         DirectedCycle finder = new DirectedCycle(G);        // 存在环则不能排序
    18         if (!finder.hasCycle())
    19         {
    20             DepthFirstOrder dfs = new DepthFirstOrder(G);   // 做 G 的深度优先搜索
    21             order = dfs.reversePost();                      // 取逆后序依次标号
    22             rank = new int[G.V()];
    23             int i = 0;
    24             for (int v : order)
    25                 rank[v] = i++;
    26         }
    27     }
    28 
    29     public class01(EdgeWeightedDigraph G)                   // 从加权边有向图生成拓扑排序(算法一样,只是数据结构不同)
    30     {
    31         EdgeWeightedDirectedCycle finder = new EdgeWeightedDirectedCycle(G);
    32         if (!finder.hasCycle())
    33         {
    34             DepthFirstOrder dfs = new DepthFirstOrder(G);
    35             order = dfs.reversePost();
    36             rank = new int[G.V()];
    37             int i = 0;
    38             for (int v : order)
    39                 rank[v] = i++;
    40         }
    41     }
    42 
    43     public Iterable<Integer> order()
    44     {
    45         return order;
    46     }
    47 
    48     public boolean hasOrder()
    49     {
    50         return order != null;
    51     }
    52 
    53     public int rank(int v)
    54     {
    55         return hasOrder() ? rank[v] : -1;
    56     }
    57 
    58     public static void main(String[] args)
    59     {
    60         String filename = args[0];
    61         String delimiter = args[1];                                 // 分隔符
    62         SymbolDigraph sg = new SymbolDigraph(filename, delimiter);
    63         class01 topological = new class01(sg.digraph());
    64         for (int v : topological.order())
    65             System.out.println(sg.nameOf(v));
    66     }
    67 }

    ● 拓扑排序 2

      1 package package01;
      2 
      3 import edu.princeton.cs.algs4.StdOut;
      4 import edu.princeton.cs.algs4.StdRandom;
      5 import edu.princeton.cs.algs4.DigraphGenerator;
      6 import edu.princeton.cs.algs4.Digraph;
      7 import edu.princeton.cs.algs4.Queue;
      8 import edu.princeton.cs.algs4.DirectedEdge;
      9 import edu.princeton.cs.algs4.EdgeWeightedDigraph;
     10 
     11 public class class01
     12 {
     13     private Queue<Integer> order;
     14     private int[] rank;
     15 
     16     public class01(Digraph G)
     17     {
     18         order = new Queue<Integer>();
     19         rank = new int[G.V()];
     20         int[] indegree = new int[G.V()];
     21         for (int v = 0; v < G.V(); v++)
     22             indegree[v] = G.indegree(v);
     23         int count = 0;
     24         Queue<Integer> queue = new Queue<Integer>();
     25         for (int v = 0; v < G.V(); v++)                 // 收集所有没有前提条件的顶点
     26         {
     27             if (indegree[v] == 0)
     28                 queue.enqueue(v);
     29         }
     30         for (; !queue.isEmpty();)
     31         {
     32             int v = queue.dequeue();
     33             order.enqueue(v);                           // 事件 v 完成,将其放入输出队列, 并给一个序号
     34             rank[v] = count++;
     35             for (int w : G.adj(v))                      // 所有紧接着 v 的事件的前提条件减少 1
     36             {
     37                 indegree[w]--;
     38                 if (indegree[w] == 0)                   // 收集此时没有前提条件的事件
     39                     queue.enqueue(w);
     40             }
     41         }
     42         if (count != G.V())                             // 遍历结束,还有顶点有入度,说明存在环
     43             order = null;
     44     }
     45 
     46     public class01(EdgeWeightedDigraph G)
     47     {
     48         order = new Queue<Integer>();
     49         rank = new int[G.V()];
     50         int[] indegree = new int[G.V()];
     51         for (int v = 0; v < G.V(); v++)
     52             indegree[v] = G.indegree(v);
     53         int count = 0;
     54         Queue<Integer> queue = new Queue<Integer>();
     55         for (int v = 0; v < G.V(); v++)
     56         {
     57             if (indegree[v] == 0)
     58                 queue.enqueue(v);
     59         }
     60         for (; !queue.isEmpty();)
     61         {
     62             int v = queue.dequeue();
     63             order.enqueue(v);
     64             rank[v] = count++;
     65             for (DirectedEdge e : G.adj(v))
     66             {
     67                 int w = e.to();
     68                 indegree[w]--;
     69                 if (indegree[w] == 0)
     70                     queue.enqueue(w);
     71             }
     72         }
     73         if (count != G.V())
     74             order = null;
     75     }
     76 
     77     public Iterable<Integer> order()
     78     {
     79         return order;
     80     }
     81 
     82     public boolean hasOrder()
     83     {
     84         return order != null;
     85     }
     86 
     87     public int rank(int v)
     88     {
     89         return hasOrder() ? rank[v] : -1;
     90     }
     91 
     92     public static void main(String[] args)
     93     {
     94         int V = Integer.parseInt(args[0]);                  // 生成DAG G(V,E),再添加 F 条边
     95         int E = Integer.parseInt(args[1]);
     96         int F = Integer.parseInt(args[2]);
     97         Digraph G1 = DigraphGenerator.dag(V, E);            // G1 是无边圈的
     98         EdgeWeightedDigraph G2 = new EdgeWeightedDigraph(V);// G2 有边权的
     99         for (int v = 0; v < G1.V(); v++)
    100         {
    101             for (int w : G1.adj(v))
    102                 G2.addEdge(new DirectedEdge(v, w, 0.0));
    103         }
    104         for (int i = 0; i < F; i++)
    105         {
    106             int v = StdRandom.uniform(V);
    107             int w = StdRandom.uniform(V);
    108             G1.addEdge(v, w);
    109             G2.addEdge(new DirectedEdge(v, w, 0.0));
    110         }
    111         StdOut.println(G1);
    112         StdOut.println();
    113         StdOut.println(G2);
    114         class01 topological1 = new class01(G1);             // 分别计算 G1 和 G2 的
    115         if (!topological1.hasOrder())
    116             StdOut.println("Not a DAG");
    117         else
    118         {
    119             StdOut.print("Topological order: ");
    120             for (int v : topological1.order())
    121                 StdOut.print(v + " ");
    122             StdOut.println();
    123         }
    124         class01 topological2 = new class01(G2);
    125         if (!topological2.hasOrder())
    126             StdOut.println("Not a DAG");
    127         else
    128         {
    129             StdOut.print("Topological order: ");
    130             for (int v : topological2.order())
    131                 StdOut.print(v + " ");
    132             StdOut.println();
    133         }
    134     }
    135 }
  • 相关阅读:
    for 循环/ while 循环/ do-while 循环
    让元素脱离动画流
    缓存布局信息
    一个程序员的管理心得
    CenOS下Tomcat外网不能访问
    卸载CentOS自带的JDK并配置指定JDK环境变量
    Linux系统安装Mysql
    系统的非功能性需求
    做软件的追求
    路途小歇
  • 原文地址:https://www.cnblogs.com/cuancuancuanhao/p/9823059.html
Copyright © 2011-2022 走看看