Percolation.java
/******************************************************************************
* Compilation: javac-algs4 Percolation.java
* Execution: java-algs4 Percolation < input.txt
* Dependencies: None
*
* This program reads standard input.
*
* - Reads the grid size n of the percolation system.
* - Creates an n-by-n grid of sites (intially all blocked)
* - Reads in a sequence of sites (row i, column j) to open.
*
* After each site is opened, it checks if the system is percolated.
******************************************************************************/
import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.WeightedQuickUnionUF;
public class Percolation {
private int gridLength;
private boolean[] grid; // true:open, false:blocked
private WeightedQuickUnionUF wqu; // with virtual top & bottom
private WeightedQuickUnionUF wqu2; // without virtual bottom
private int virtualTop;
// create n-by-n grid, with all sites blocked
public Percolation(int n) {
if (n <= 0) {
throw new IllegalArgumentException("length must be positive");
}
gridLength = n;
virtualTop = gridLength * gridLength;
grid = new boolean[virtualTop];
// the last two are virtual top & virtual bottom sites
wqu = new WeightedQuickUnionUF(virtualTop + 2);
wqu2 = new WeightedQuickUnionUF(virtualTop + 1);
}
private void validateIndecies(int row, int col) {
if (row <= 0 || row > gridLength)
throw new IndexOutOfBoundsException("row index out of bounds");
if (col <= 0 || col > gridLength)
throw new IndexOutOfBoundsException("col index out of bounds");
}
private int xyTo1D(int row, int col) {
return (row - 1) * gridLength + (col - 1);
}
// open site (row, col) if it is not open already
public void open(int row, int col) {
validateIndecies(row, col);
int self = xyTo1D(row, col);
if (grid[self]) {
return;
}
grid[self] = true;
if (row == 1) {
wqu.union(self, virtualTop);
wqu2.union(self, virtualTop);
}
if (row == gridLength) {
wqu.union(self, virtualTop + 1);
}
int other;
if (row > 1) { // up
other = xyTo1D(row - 1, col);
if (grid[other]) {
wqu.union(self, other);
wqu2.union(self, other);
}
}
if (row < gridLength) { // down
other = xyTo1D(row + 1, col);
if (grid[other]) {
wqu.union(self, other);
wqu2.union(self, other);
}
}
if (col > 1) { // left
other = xyTo1D(row, col - 1);
if (grid[other]) {
wqu.union(self, other);
wqu2.union(self, other);
}
}
if (col < gridLength) { // right
other = xyTo1D(row, col + 1);
if (grid[other]) {
wqu.union(self, other);
wqu2.union(self, other);
}
}
}
// is site (row, col) open?
public boolean isOpen(int row, int col) {
validateIndecies(row, col);
return grid[xyTo1D(row, col)];
}
// is site (row, col) full?
public boolean isFull(int row, int col) {
validateIndecies(row, col);
return wqu2.connected(virtualTop, xyTo1D(row, col));
}
// does the system percolate?
public boolean percolates() {
return wqu.connected(virtualTop, virtualTop + 1);
}
// test client (optional)
public static void main(String[] args) {
/*
Percolation percolation = new Percolation(0);
Percolation percolation = new Percolation(1);
percolation.open(0, 1);
percolation.open(1, 0);
*/
/*
Percolation percolation = new Percolation(2);
percolation.open(1, 1);
percolation.open(1, 2);
for (int i = 1; i <= 2; i++) {
for(int j = 1; j <= 2; j++) {
StdOut.println("" + percolation.isFull(i, j) + " " + percolation.isOpen(i, j));
}
}
StdOut.println("percolation is " + percolation.percolates());
*/
int n = StdIn.readInt();
Percolation percolation = new Percolation(n);
while (!StdIn.isEmpty()) {
int row = StdIn.readInt();
int col = StdIn.readInt();
percolation.open(row, col);
}
StdOut.println("percolation is " + percolation.percolates());
}
}
PercolationStats.java
/******************************************************************************
* Compilation: javac-algs4 PercolationStats.java
* Execution: java-algs4 PercolationStats length trails
* Dependencies: Percolation.java
*
* This program takes the length of grid and trails.
*
******************************************************************************/
import edu.princeton.cs.algs4.StdRandom;
import edu.princeton.cs.algs4.StdStats;
import edu.princeton.cs.algs4.StdOut;
public class PercolationStats {
private int gridLength;
private double[] trailsResult;
private double resultMean;
private double resultStddev;
private double resultconfidenceLo;
private double resultconfidenceHi;
// perform trials independent experiments on an n-by-n grid
public PercolationStats(int n, int trials) {
if (n <= 0) {
throw new IllegalArgumentException("length must be positive");
}
if (trials <= 0) {
throw new IllegalArgumentException("trials must be positive");
}
gridLength = n;
if (gridLength == 1) {
resultMean = 1;
resultStddev = Double.NaN;
resultconfidenceLo = Double.NaN;
resultconfidenceHi = Double.NaN;
}
else {
trailsResult = new double[trials];
for (int i = 0; i < trials; i++) {
trailsResult[i] = oneTrial(gridLength);
}
resultMean = StdStats.mean(trailsResult);
resultStddev = StdStats.stddev(trailsResult);
double diff = (1.96 * resultStddev) / Math.sqrt(trials);
resultconfidenceLo = resultMean - diff;
resultconfidenceHi = resultMean + diff;
}
}
private double oneTrial(int length) {
int openedCount = 0;
Percolation percolation = new Percolation(length);
while (!percolation.percolates()) {
int row = StdRandom.uniform(length) + 1;
int col = StdRandom.uniform(length) + 1;
if (!percolation.isOpen(row, col)) {
percolation.open(row, col);
openedCount++;
}
}
return (double) openedCount / (length * length);
}
// sample mean of percolation threshold
public double mean() {
return resultMean;
}
// sample standard deviation of percolation threshold
public double stddev() {
return resultStddev;
}
// low endpoint of 95% confidence interval
public double confidenceLo() {
return resultconfidenceLo;
}
// high endpoint of 95% confidence interval
public double confidenceHi() {
return resultconfidenceHi;
}
// test client
public static void main(String[] args) {
int length = Integer.parseInt(args[0]);
int trials = Integer.parseInt(args[1]);
PercolationStats percolations = new PercolationStats(length, trials);
StdOut.println("mean = " + percolations.mean());
StdOut.println("stddev = " + percolations.stddev());
StdOut.println("95% confidence interval = "
+ percolations.confidenceLo() + ", "
+ percolations.confidenceHi());
}
}
参考:
http://www.sigmainfy.com/blog/avoid-backwash-in-percolation.html
-eof-