jules0707

SAP.java

Jan 7th, 2021 (edited)
228
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 6.22 KB | None | 0 0
  1. import edu.princeton.cs.algs4.Digraph;
  2. import edu.princeton.cs.algs4.In;
  3. import edu.princeton.cs.algs4.Queue;
  4. import edu.princeton.cs.algs4.StdOut;
  5.  
  6. import java.util.ArrayList;
  7.  
  8. public class SAP {
  9.  
  10.     private final Digraph G;
  11.     private final int range;
  12.  
  13.     // constructor takes a digraph (not necessarily a DAG)
  14.     public SAP(Digraph G) {
  15.         if (G == null) {
  16.             throw new NullPointerException();
  17.         }
  18.         this.G = new Digraph(G);
  19.         this.range = this.G.V();
  20.     }
  21.  
  22.     // length of shortest ancestral path between v and w; -1 if no such path
  23.     public int length(int v, int w) {
  24.         validate(v);
  25.         validate(w);
  26.         if (v == w) return 0;
  27.         ArrayList<Integer> vIterable = new ArrayList<>();
  28.         vIterable.add(v);
  29.         ArrayList<Integer> wIterable = new ArrayList<>();
  30.         wIterable.add(w);
  31.         return deluxeBfs(vIterable, wIterable)[1];
  32.     }
  33.  
  34.     // a common ancestor of v and w that participates in a shortest ancestral path; -1 if no such path
  35.     public int ancestor(int v, int w) {
  36.         validate(v);
  37.         validate(w);
  38.         if (v == w) return v;
  39.         ArrayList<Integer> vIterable = new ArrayList<>();
  40.         vIterable.add(v);
  41.         ArrayList<Integer> wIterable = new ArrayList<>();
  42.         wIterable.add(w);
  43.         return deluxeBfs(vIterable, wIterable)[0];
  44.     }
  45.  
  46.     // length of shortest ancestral path between any vertex in v and any vertex in w; -1 if no such path
  47.     public int length(Iterable<Integer> v, Iterable<Integer> w) {
  48.         validate(v, w);
  49.         return deluxeBfs(v, w)[1];
  50.     }
  51.  
  52.     // a common ancestor that participates in shortest ancestral path; -1 if no such path
  53.     public int ancestor(Iterable<Integer> v, Iterable<Integer> w) {
  54.         validate(v, w);
  55.         return deluxeBfs(v, w)[0];
  56.     }
  57.  
  58.     private int[] deluxeBfs(Iterable<Integer> v, Iterable<Integer> w) {
  59.         int ancestor = -1;
  60.         int path = Integer.MAX_VALUE;
  61.         int[] res = {ancestor, path};
  62.  
  63.         // do v and w have a common vertex?
  64.         ArrayList<Integer> vIterable = new ArrayList<>();
  65.         v.forEach(vIterable::add);
  66.         ArrayList<Integer> wIterable = new ArrayList<>();
  67.         w.forEach(wIterable::add);
  68.  
  69.  
  70.         for (int i : vIterable) {
  71.             if (wIterable.contains(i)) { // short circuit
  72.                 res[0] = i;
  73.                 res[1] = 0;
  74.                 return res;
  75.             }
  76.         }
  77.  
  78.         Queue<Integer> vQ = new Queue<>(); // queue from v
  79.         Queue<Integer> wQ = new Queue<>(); // queue from w
  80.         boolean[] vMarked = new boolean[range];
  81.         boolean[] wMarked = new boolean[range];
  82.         int[] distFromV = new int[range];
  83.         int[] distFromW = new int[range];
  84.  
  85.         // enqueue all the v-set vertices
  86.         for (int s : v) {
  87.             vMarked[s] = true;
  88.             distFromV[s] = 0;
  89.             vQ.enqueue(s);
  90.         }
  91.         // enqueue all the w-set vertices
  92.         for (int s : w) {
  93.             wMarked[s] = true;
  94.             distFromW[s] = 0;
  95.             wQ.enqueue(s);
  96.         }
  97.  
  98. /*SAP.java:109: Avoid quadruple nested 'if' statements; they are hard to read and error-prone to maintain. [AvoidDeeplyNestedIfStmts]
  99. SAP.java:125: Avoid quadruple nested 'if' statements; they are hard to read and error-prone to maintain. [AvoidDeeplyNestedIfStmts]*/
  100.  
  101.         //bfs in lockstep
  102.         while (!vQ.isEmpty() || !wQ.isEmpty()) {
  103.             if (!vQ.isEmpty()) {
  104.                 int v1 = vQ.dequeue();
  105.                 for (int v2 : G.adj(v1)) {
  106.                     if (!vMarked[v2]) {
  107.                         vMarked[v2] = true;
  108.                         vQ.enqueue(v2);
  109.                         distFromV[v2] = distFromV[v1] + 1;
  110.                         if (wMarked[v2]) {// we have a path
  111.                             int distV2 = distFromV[v2] + distFromW[v2];
  112.                             if (distV2 >= res[1]) continue; // no shorter path from this vertex
  113.                             res[0] = v2;
  114.                             res[1] = distV2;
  115.                         }
  116.                     }
  117.                 }
  118.             }
  119.             if (!wQ.isEmpty()) {
  120.                 int w1 = wQ.dequeue();
  121.                 for (int w2 : G.adj(w1)) {
  122.                     if (!wMarked[w2]) {
  123.                         wMarked[w2] = true;
  124.                         wQ.enqueue(w2);
  125.                         distFromW[w2] = distFromW[w1] + 1;
  126.                         if (vMarked[w2]) {
  127.                             int distW2 = distFromV[w2] + distFromW[w2];
  128.                             if (distW2 >= res[1]) continue;
  129.                             res[0] = w2;
  130.                             res[1] = distW2;
  131.                         }
  132.                     }
  133.                 }
  134.             }
  135.         }
  136.         if (res[1] == Integer.MAX_VALUE) {
  137.             return new int[]{-1, -1};
  138.         }
  139.         return res;
  140.     }
  141.  
  142.     private void validate(Object v) {
  143.         if (null == v) throw new IllegalArgumentException();
  144.         if ((int) v < 0 || (int) v >= range) throw new IllegalArgumentException();
  145.     }
  146.  
  147.     private void validate(Iterable<Integer> v, Iterable<Integer> w) {
  148.         try {
  149.             for (Object i : v) {
  150.                 validate(i);
  151.             }
  152.             for (Object j : w) {
  153.                 validate(j);
  154.             }
  155.         } catch (NullPointerException e)  {
  156.             throw new IllegalArgumentException();
  157.         }
  158.     }
  159.  
  160.     public static void main(String[] args) {
  161.         In in = new In(args[0]);
  162.         Digraph G = new Digraph(in);
  163.         SAP sap = new SAP(G);
  164.         // while (!StdIn.isEmpty()) {
  165. /*        int v = 12; //StdIn.readInt();
  166.         int w = 13; //StdIn.readInt();*/
  167.         ArrayList<Integer> v = null;
  168.         //= new ArrayList<>();
  169.         //{ 0, 7, 9, 12 }
  170.         /*v.add(0);
  171.         v.add(7);
  172.         v.add(9);
  173.         v.add(12);
  174.        */ //v.add(10);
  175.  
  176.         ArrayList<Integer> w = null;
  177.         /*= new ArrayList<>();
  178.         w.add(null);
  179.       */  /*w.add(10);
  180.         w.add(12);*/
  181.  
  182.  
  183.         int ancestor = sap.ancestor(v, w);
  184.         StdOut.printf("ancestor = %d\n", ancestor);
  185.         int length = sap.length(v, w);
  186.         StdOut.printf("length = %d\n", length);
  187.     }
  188. }
  189.  
  190.  
Add Comment
Please, Sign In to add comment