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)); }
// 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); } }
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); } }
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(); } }
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()); }
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; }
// 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); } }
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); } }
// 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; }
// 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)); }
// 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; }
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(""); } }
// 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)); } }
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; }
// 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)); } } }
// 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)); } }
public boolean percolates() { return uf.connected(topRowGroup, bottomRowGroup); }
/** * @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)); }
/** * 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)); } }
/** * 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]); }
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); }
// 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); }
// 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); }
// checks if system percolates public boolean percolates() { return uf.connected(top, bottom); }