예제 #1
0
 private void unionWithAdjacentOpenSites(int i, int j) {
   int index = buildDsIndex(i, j);
   if ((i - 1 > 0) && isOpen(i - 1, j)) unionDs.union(index, buildDsIndex(i - 1, j));
   if ((i + 1 <= N) && isOpen(i + 1, j)) unionDs.union(index, buildDsIndex(i + 1, j));
   if ((j - 1 > 0) && isOpen(i, j - 1)) unionDs.union(index, buildDsIndex(i, j - 1));
   if ((j + 1 <= N) && isOpen(i, j + 1)) unionDs.union(index, buildDsIndex(i, j + 1));
 }
예제 #2
0
  // open site (row i, column j) if it is not already
  public void open(int i, int j) {
    // Check out of bounds
    if (i < 1 || i > size || j < 1 || j > size) {
      throw new IndexOutOfBoundsException("row index i out of bounds");
    }

    if (!isOpen(i, j)) {
      grid[i - 1][j - 1] = open;
    }

    // Union adjacent open sites:
    // Possible to union top?
    if (i > 1 && isOpen(i - 1, j)) {
      quickFind.union(size * (i - 1) + (j - 1), size * (i - 2) + (j - 1));
    }

    // Possible to union bottom?
    if (i < size && isOpen(i + 1, j)) {
      quickFind.union(size * (i - 1) + (j - 1), size * (i) + (j - 1));
    }

    // Possible to union left?
    if (j > 1 && isOpen(i, j - 1)) {
      quickFind.union(size * (i - 1) + (j - 1), size * (i - 1) + (j - 2));
    }

    // Possible to union right?
    if (j < size && isOpen(i, j + 1)) {
      quickFind.union(size * (i - 1) + (j - 1), size * (i - 1) + j);
    }
  }
예제 #3
0
 private void openSite(int i, int j) {
   sites[i - 1][j - 1] = true;
   if (i == 1) {
     uf.union(getFlatIndex(i, j), topRowGroup);
   }
   if (i == N) {
     uf.union(getFlatIndex(i, j), bottomRowGroup);
   }
 }
예제 #4
0
 private void connectCellsIfPossible(int i1, int j1, int i2, int j2) {
   if (isOpen(i2, j2)) {
     int currentCell = getFlatIndex(i1, j1);
     int appendedCell = getFlatIndex(i2, j2);
     if (!uf.connected(currentCell, appendedCell)) {
       uf.union(currentCell, appendedCell);
     }
   }
 }
 /**
  * Reads in a sequence of pairs of integers (between 0 and N-1) from standard input, where each
  * integer represents some object; if the objects are in different components, merge the two
  * components and print the pair to standard output.
  */
 public static void main(String[] args) {
   int N = StdIn.readInt();
   WeightedQuickUnionUF uf = new WeightedQuickUnionUF(N);
   while (!StdIn.isEmpty()) {
     int p = StdIn.readInt();
     int q = StdIn.readInt();
     if (uf.connected(p, q)) continue;
     uf.union(p, q);
     StdOut.println(p + " " + q);
   }
   StdOut.println(uf.count() + " components");
 }
 /**
  * @param i - row
  * @param j - column
  * @return if cell is full or not
  * @throws IndexOutOfBoundsException
  */
 public boolean isFull(int i, int j) {
   if (0 < i && i <= N && 0 < j && j <= N) {
     return wQUFHelper.connected(top, xyToUF(i, j));
   } else {
     throw new IndexOutOfBoundsException();
   }
 }
예제 #7
0
 public boolean percolates() {
   // does the system percolate?
   if (uf.connected(trans(1, 0), trans(n, 0))) {
     return true;
   }
   return false;
 }
  public static void main(String[] args) {
    int N = StdIn.readInt();
    WeightedQuickUnionUF uf = new WeightedQuickUnionUF(N);

    // read in a sequence of pairs of integers (each in the range 0 to N-1),
    // calling find() for each pair: If the members of the pair are not already
    // call union() and print the pair.
    while (!StdIn.isEmpty()) {
      int p = StdIn.readInt();
      int q = StdIn.readInt();
      if (uf.connected(p, q)) continue;
      uf.union(p, q);
      StdOut.println(p + " " + q);
    }
    StdOut.println("# components: " + uf.count());
  }
예제 #9
0
  public Percolation(int N) {
    this.N = N;
    wquf = new WeightedQuickUnionUF((N + 1) * (N + 1));
    for (int i = 1, j = 1; j <= N; j++) wquf.union(0, i * N + j);

    open = new boolean[(N + 1) * (N + 1)];
    for (int i = 1; i <= N * N; i++) open[i] = false;
    open[0] = true;
  }
예제 #10
0
 // open site (row i, column j) if it is not open already
 public void open(int i, int j) {
   validateIndexes(i, j);
   if (!isOpen(i, j)) {
     int index = buildDsIndex(i, j);
     isOpenArray[index] = true; // open site
     if ((i == 1) || (isAdjacentToFull(i, j)))
       unionDs.union(0, index); // fill the newly opened site
     unionWithAdjacentOpenSites(i, j);
   }
 }
예제 #11
0
  public void open(int i, int j) {
    if (i < 1 || i > N) throw new IndexOutOfBoundsException("row index i out of bounds");
    if (j < 1 || j > N) throw new IndexOutOfBoundsException("column index j out of bounds");

    open[i * N + j] = true;
    int[][] dir = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
    for (int d = 0; d < 4; d++) {
      int m = i + dir[d][0];
      int n = j + dir[d][1];
      if (m > 0 && m <= N && n > 0 && n <= N && isOpen(m, n)) wquf.union(N * i + j, N * m + n);
    }
  }
예제 #12
0
  // does the system percolate?
  public boolean percolates() {
    for (int i = 0; i < size; i++) {
      for (int j = 0; j < size; j++) {
        int lastRowMember = (size - 1) * size + j;
        if (quickFind.connected(i, lastRowMember)) {
          return true;
        }
      }
    }

    return false;
  }
예제 #13
0
  // create N-by-N grid, with all sites blocked
  public Percolation(int N) {
    if (N <= 0) throw new IllegalArgumentException();

    this.N = N;
    // ~N^2 time
    isOpenArray = new boolean[N * N + 2]; // Add 2 elements for connecting nodes
    // ~N^2 time
    unionDs = new WeightedQuickUnionUF(N * N + 2);
    // union the bottom row
    // ~N time
    int bottomApex = N * N + 1;
    for (int i = 1; i <= N; i++) unionDs.union(bottomApex, buildDsIndex(N, i));
  }
예제 #14
0
  // is site (row i, column j) full?
  public boolean isFull(int i, int j) {
    // Check out of bounds
    if (i < 1 || i > size || j < 1 || j > size) {
      throw new IndexOutOfBoundsException("row index i out of bounds");
    }

    for (int index = 0; index < size; index++) {
      if (isOpen(i, j) && quickFind.connected(index, size * (i - 1) + (j - 1))) {
        return true;
      }
    }

    return false;
  }
예제 #15
0
  public void open(int i, int j) { // throws IndexOutOfBoundsException {
    // open site (row i, column j) if it is not already
    if (i < 1 || j < 1 || i > n || j > n) {
      throw new IndexOutOfBoundsException("");
    }
    try {

      if (!isOpen(i, j)) {
        openMark[i][j] = true;
        if (i == 1 || i == n) {
          uf.union(trans(i, 0), trans(i, j));
          // System.out.print("111 \n ");

        }

        // System.out.printf("original:  %d %d \n ", i, j);
        if (isOpen(i + 1, j)) {
          uf.union(trans(i, j), trans(i + 1, j));
          // System.out.printf("%d %d \n ", i + 1, j);
        }
        if (isOpen(i - 1, j)) {
          uf.union(trans(i, j), trans(i - 1, j));
          // System.out.printf("%d %d \n ", i-1, j);
        }
        if (isOpen(i, j + 1)) {
          uf.union(trans(i, j), trans(i, j + 1));
          //  System.out.printf("%d %d \n ", i, j+1);
        }
        if (isOpen(i, j - 1)) {
          uf.union(trans(i, j), trans(i, j - 1));
          //  System.out.printf("%d %d \n ", i, j-1);
        }
      }
    } catch (IndexOutOfBoundsException e) {
      // System.err.println("");
    }
  }
예제 #16
0
 // union with all 4 neighboring sites
 private void unionAll(int i, int j, int pos) {
   if (isOpen(i - 1, j)) {
     uf.union(pos, getPos(i - 1, j)); // union above node if open
     uf2.union(pos, getPos(i - 1, j));
   }
   if (isOpen(i + 1, j)) {
     uf.union(pos, getPos(i + 1, j)); // union below node if open
     uf2.union(pos, getPos(i + 1, j));
   }
   if (isOpen(i, j + 1)) {
     uf.union(pos, getPos(i, j + 1)); // union right node if open
     uf2.union(pos, getPos(i, j + 1));
   }
   if (isOpen(i, j - 1)) {
     uf.union(pos, getPos(i, j - 1)); // union left node if open
     uf2.union(pos, getPos(i, j - 1));
   }
 }
예제 #17
0
  public boolean isFull(int i, int j) { // throws IndexOutOfBoundsException {
    // is site (row i, column j) full?
    if (i < 1 || j < 1 || i > n || j > n) {
      throw new IndexOutOfBoundsException("");
    }
    try {

      if (openMark[i][j]) {
        if (uf.connected(trans(i, j), trans(1, 0))) {
          return true;
        }
      }
    } catch (IndexOutOfBoundsException e) {
      // System.err.println("");
    }
    return false;
  }
예제 #18
0
 // union with neighboring sites on bottom
 private void unionTop(int i, int j, int pos) {
   uf.union(pos, top); // union with virtual top
   uf2.union(pos, top);
   if (isOpen(i + 1, j)) {
     uf.union(pos, getPos(i + 1, j)); // union below node if open
     uf2.union(pos, getPos(i + 1, j));
   }
   if (j > 1) {
     if (isOpen(i, j - 1)) {
       uf.union(pos, getPos(i, j - 1)); // union left node if open
       uf2.union(pos, getPos(i, j - 1));
     }
   }
   if (j < N) {
     if (isOpen(i, j + 1)) {
       uf.union(pos, getPos(i, j + 1)); // union right node if open
       uf2.union(pos, getPos(i, j + 1));
     }
   }
 }
예제 #19
0
 // union with neighboring sites on bottom
 private void unionBot(int i, int j, int pos) {
   uf.union(pos, bottom); // union with virtual bottom
   if (isOpen(i - 1, j)) {
     uf.union(pos, getPos(i - 1, j)); // union above node if open
     uf2.union(pos, getPos(i - 1, j));
   }
   if (j > 1) {
     if (isOpen(i, j - 1)) {
       uf.union(pos, getPos(i, j - 1)); // union left node if open
       uf2.union(pos, getPos(i, j - 1));
     }
   }
   if (j < N) {
     if (isOpen(i, j + 1)) {
       uf.union(pos, getPos(i, j + 1)); // union right node if open
       uf2.union(pos, getPos(i, j + 1));
     }
   }
 }
  /**
   * This method will help to open the cell.
   *
   * @param i - rowth cell to pen
   * @param j - column cell to open
   */
  public void open(int i, int j) {
    matrix[i - 1][j - 1] = 1;
    if (i == 1) {
      wQUFHelper.union(xyToUF(i, j), top);
    }
    if (i == N) {
      wQUFHelper.union(xyToUF(i, j), bottom);
    }

    if (j > 1 && isOpen(i, j - 1)) {
      wQUFHelper.union(xyToUF(i, j), xyToUF(i, j - 1));
    }
    if (j < N && isOpen(i, j + 1)) {
      wQUFHelper.union(xyToUF(i, j), xyToUF(i, j + 1));
    }
    if (i > 1 && isOpen(i - 1, j)) {
      wQUFHelper.union(xyToUF(i, j), xyToUF(i - 1, j));
    }
    if (i < N && isOpen(i + 1, j)) {
      wQUFHelper.union(xyToUF(i, j), xyToUF(i + 1, j));
    }
  }
예제 #21
0
 public boolean percolates() {
   return uf.connected(topRowGroup, bottomRowGroup);
 }
예제 #22
0
 /**
  * @param i the first coordinate
  * @param j the second coordinate
  * @return true if site (row i, column j) is full
  */
 public boolean isFull(final int i, final int j) {
   checkIndices(i, j);
   return isOpen(i, j) && uf.connected(0, toIndex(i, j));
 }
예제 #23
0
 /**
  * Connects with master node if in the upper row.
  *
  * @param i the first coordinate
  * @param j the second coordinate
  * @return
  */
 private void connectWithMaster(final int i, final int j) {
   if (i == 1) {
     uf.union(MASTER, toIndex(i, j));
   }
 }
예제 #24
0
 /**
  * Connects two nodes of the grid.
  *
  * @param i1 the first coordinate of the first node
  * @param j1 the second coordinate of the first node
  * @param i2 the first coordinate of the second node
  * @param j2 the second coordinate of the second node
  * @return
  */
 private void connect(final int i1, final int j1, final int i2, final int j2) {
   if (validCoordinates(i1, j1) && validCoordinates(i2, j2) && isOpen(i2, j2)) {
     uf.union(toIndex(i1, j1), toIndex(i2, j2));
   }
 }
  /**
   * Reads in a sequence of pairs of integers (between 0 and N-1) from standard input, where each
   * integer represents some object; if the objects are in different components, merge the two
   * components and print the pair to standard output.
   */
  public static void main(String[] args) {
    /**
     * int N = StdIn.readInt(); WeightedQuickUnionUF uf = new WeightedQuickUnionUF(N); while
     * (!StdIn.isEmpty()) { int p = StdIn.readInt(); int q = StdIn.readInt(); if (uf.connected(p,
     * q)) continue; uf.union(p, q); StdOut.println(p + " " + q); } StdOut.println(uf.count() + "
     * components");
     */

    /*int N = 10;
    WeightedQuickUnionUF uf = new WeightedQuickUnionUF(N);
    uf.print();
    StdOut.println();
    uf.union(2, 5);
    uf.print();
    StdOut.println();
    uf.union(0, 7);
    uf.union(2, 9);
    uf.union(6, 4);
    uf.union(1, 8);
    uf.union(6, 5);
    uf.union(0, 1);
    uf.union(0, 5);
    uf.union(9, 3);

    uf.print();*/

    /* Q1
    Social network connectivity. Given a social network containing N members
    and a log file containing M timestamps at which times pairs of members formed friendships,
    design an algorithm to determine the earliest time at which all members are connected
    (i.e., every member is a friend of a friend of a friend ... of a friend).
    Assume that the log file is sorted by timestamp and that friendship is an equivalence relation.
    The running time of your algorithm should be MlogN or better and use extra space proportional to N.
    */

    /*
    int N = 4;
    WeightedQuickUnionUF uf = new WeightedQuickUnionUF(N);
    StdOut.println();
    StdOut.println( uf.isConnectedAll());
    StdOut.println( uf.CntRoot());
    uf.print();StdOut.println();
    uf.union(0, 1);
    uf.union(0, 1);
    uf.union(0, 3);
    uf.union(2, 3);
    uf.print();
    StdOut.println();
    StdOut.println( uf.isConnectedAll());
    StdOut.println( uf.CntRoot());
    */

    /* Q2
     Union-find with specific canonical element. Add a method find() to the union-find data type so that find(i)
      returns the largest element in the connected component containing i.
      The operations, union(), connected(), and find() should all take logarithmic time or better.
        For example, if one of the connected components is {1,2,6,9}, then the find() method should return 9 for each of the four elements in the connected components.
    */

    /*int N = 4;
    WeightedQuickUnionUF uf = new WeightedQuickUnionUF(N);
    StdOut.println();
    StdOut.println( uf.isConnectedAll());
    StdOut.println( uf.CntRoot());
    uf.print();StdOut.println();
    uf.union(0, 1);
    uf.union(0, 1);
    uf.union(0, 3);
    uf.union(2, 3);
    uf.print();
    StdOut.println();
    StdOut.println("Only One root? " + uf.isConnectedAll());
    StdOut.println("Count Roots " + uf.CntRoot());
    StdOut.println("Max component " + uf.maxInSameComponent(0));*/

    /*
    Q4
    Union-by-size. Develop a union-find implementation that uses the same basic strategy as weighted quick-union
    but keeps track of tree height and always links the shorter tree to the taller one.
    Prove a lgN upper bound on the height of the trees for N sites with your algorithm.
    */

    int N = 6;
    WeightedQuickUnionUF uf = new WeightedQuickUnionUF(N);
    StdOut.println();
    StdOut.println(uf.isConnectedAll());
    StdOut.println(uf.CntRoot());
    uf.print();
    StdOut.println();
    uf.unionByHeight(0, 1);
    uf.unionByHeight(0, 1);
    uf.unionByHeight(2, 2);
    uf.unionByHeight(3, 2);
    uf.unionByHeight(4, 3);
    uf.unionByHeight(5, 2);
    uf.print();
    StdOut.println();
    StdOut.println("Only One root? " + uf.isConnectedAll());
    StdOut.println("Count Roots " + uf.CntRoot());
    StdOut.println("Max component " + uf.maxInSameComponent(0));
    StdOut.println("Haight " + uf.height[5]);
  }
예제 #26
0
 public boolean isFull(int i, int j) {
   if (i < 1 || i > N) throw new IndexOutOfBoundsException("row index i out of bounds");
   if (j < 1 || j > N) throw new IndexOutOfBoundsException("column index j out of bounds");
   return isOpen(i, j) && wquf.connected(0, N * i + j);
 }
예제 #27
0
 // special case N = 1, N = 1 union with neighboring sites
 private void specialUnion(int i, int j, int pos) {
   if (N == 1) { // if N=1 then union the only node with
     uf.union(pos, top); // virtual top and bottom
     uf.union(pos, bottom);
     uf2.union(pos, top);
   }
   if (N == 2) {
     if (i == 1) { // if first row then union with virtual
       uf.union(pos, top); // top and the node below if open
       uf2.union(pos, top);
       if (isOpen(i + 1, j)) {
         uf.union(pos, getPos(i + 1, j));
         uf2.union(pos, getPos(i + 1, j));
       }
     }
     if (i == 2) { // if second row then union with virtual
       uf.union(pos, bottom); // bottom and node above it if open
       uf2.union(pos, bottom);
       if (isOpen(i - 1, j)) {
         uf.union(pos, getPos(i - 1, j));
         uf2.union(pos, getPos(i - 1, j));
       }
     }
   }
 }
 /**
  * check if the matrix can percolates or not.
  *
  * @return boolean true or false
  */
 public boolean percolates() {
   return wQUFHelper.connected(top, bottom);
 }
예제 #29
0
 // checks if site (row i, column j) full
 public boolean isFull(int i, int j) {
   validateIndices(i, j);
   return isOpen(i, j) && uf2.connected(getPos(i, j), top);
 }
예제 #30
0
 // checks if system percolates
 public boolean percolates() {
   return uf.connected(top, bottom);
 }