首先说一下做这个作业大概的几个要点:
1、可以不使用官网提供的编译环境进行编程,在eclipse里引入algs4.jar包就可以了,另外使用缺省包。
2、不要使用for语句,不然时间会超出。
3、可以加入虚头节点和虚尾节点减少问题复杂度。
4、在加入虚节点后会出现backwash问题,使用两个QUF。一个QUF包含虚头和虚尾节点,用于判断是否渗透。一个QUF只包含虚头节点,用于对full节点计数。
5、比较坑的一点,自动评分系统仅支持UTF_8下的中文字符。
import edu.princeton.cs.algs4.WeightedQuickUnionUF;
public class Percolation {
private boolean [] arrAysite; //表示节点的连通性
private int n; //方阵的行列数
private int numOpenSites; //联通态节点个数
private WeightedQuickUnionUF topBotWeightedQuickUnionUF; //连接虚头、虚尾节点的QUF
private WeightedQuickUnionUF topWeightedQuickUnionUF; //仅含虚头的QUF
private int virtualTop; //头部虚节点
private int virtualBot; //底部虚节点
public Percolation(int n)
{
numOpenSites = 0;
if (n <= 0)
{
throw new java.lang.IllegalArgumentException("n0");
}
else
{
this.n = n;
virtualTop = 0; //头部虚节点
virtualBot = n*n +1; //底部虚节点
arrAysite = new boolean [n*n +2];
arrAysite[virtualTop] = true;
arrAysite[virtualBot] = true;
topBotWeightedQuickUnionUF = new WeightedQuickUnionUF(n*n +2);
topWeightedQuickUnionUF = new WeightedQuickUnionUF(n*n+1);
}
}
private int rowCol(int row, int col) { //获取(row,col)在数组中的位置
if (row < 1 || row > n || col < 1 || col > n)
{
throw new java.lang.IllegalArgumentException("The scope of is row or colw is wrong");
}
return (row-1)*n + col;
}
public void open(int row, int col)
{
if (!isOpen(row, col))
{
int rowcol = rowCol(row, col);
arrAysite[(row-1)*n +col] = true;
numOpenSites++;
if (row == 1) //第一行元素与虚头节点相连
{
topBotWeightedQuickUnionUF.union(rowcol, virtualTop);
topWeightedQuickUnionUF.union(rowcol, virtualTop);
}
if (row == n) //最后一行元素与虚尾节点相连
{
topBotWeightedQuickUnionUF.union(rowcol, virtualBot);
}
//上
if (row > 1 && isOpen(row-1, col)) {
topBotWeightedQuickUnionUF.union(rowcol, rowCol(row-1, col));
topWeightedQuickUnionUF.union(rowcol, rowCol(row-1, col));
}
//下
if (row < n && isOpen(row+1, col)) {
topBotWeightedQuickUnionUF.union(rowcol, rowCol(row+1, col));
topWeightedQuickUnionUF.union(rowcol, rowCol(row+1, col));
}
//左
if (col > 1 && isOpen(row, col-1)) {
topBotWeightedQuickUnionUF.union(rowcol, rowCol(row, col-1));
topWeightedQuickUnionUF.union(rowcol, rowCol(row, col-1));
}
//右
if (col < n && isOpen(row, col+1)) {
topBotWeightedQuickUnionUF.union(rowcol, rowCol(row, col+1));
topWeightedQuickUnionUF.union(rowcol, rowCol(row, col+1));
}
}
}
public boolean isOpen(int row, int col) //是否为开放态
{
return arrAysite[rowCol(row, col)];
}
public boolean isFull(int row, int col) //是否为联通态
{
return topWeightedQuickUnionUF.connected(rowCol(row, col), virtualTop);
}
public int numberOfOpenSites() //计算联通态数量
{
return numOpenSites;
}
public boolean percolates() //是否渗透
{
return topBotWeightedQuickUnionUF.connected(virtualTop, virtualBot);
}
public static void main(String[] args) // test client (optional)
{
int nn = 5;
Percolation myPercolation = new Percolation(nn);
myPercolation.open(1, 1);
myPercolation.open(1, 3);
myPercolation.open(3, 4);
myPercolation.open(2, 2);
myPercolation.open(2, 4);
System.out.println(myPercolation.percolates());
myPercolation.open(3, 5);
myPercolation.open(5, 5);
myPercolation.open(4, 5);
myPercolation.open(4, 3);
myPercolation.open(4, 1);
myPercolation.open(2, 3);
System.out.println(myPercolation.percolates());
myPercolation.open(5, 3);
myPercolation.open(5, 2);
myPercolation.open(5, 1);
myPercolation.open(3, 1);
System.out.println(myPercolation.percolates());
System.out.println(myPercolation.numberOfOpenSites());
}
}
import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.StdRandom;
import edu.princeton.cs.algs4.StdStats;
public class PercolationStats {
private final double []arryp; //记录p值
private final int trails; //实验次数
public PercolationStats(int n, int trials)
{
Percolation testPercolation;
if (n < 1 || trials < 1) {
throw new java.lang.IllegalArgumentException("The scope of is n or trials is wrong");
}
this.trails = trials;
arryp = new double[trials];
for (int i = 0; i < trials; i++) { //trials次随机测试
testPercolation = new Percolation(n);
while (!testPercolation.percolates()) {
int row = StdRandom.uniform(1, n+1);
int col = StdRandom.uniform(1, n+1);
testPercolation.open(row, col);
}
int nunOS = testPercolation.numberOfOpenSites();
arryp[i] = (double) nunOS/(n*n); //记录p值
}
}
public double mean() //计算p值的平均数
{
return StdStats.mean(arryp);
}
public double stddev() //计算p值的标准偏差
{
return StdStats.stddev(arryp);
}
public double confidenceLo() //可信度最低范围
{
return mean()-1.96*stddev()/Math.sqrt(trails);
}
public double confidenceHi() //可信度最高范围
{
return mean()+1.96*stddev()/Math.sqrt(trails);
}
public static void main(String[] args)
{
int n = 10, trialNum = 1000;
PercolationStats ps = new PercolationStats(n, trialNum);
StdOut.println("grid size :" + n+"*"+n);
StdOut.println("trial times :" + trialNum);
StdOut.println("mean of p :"+ ps.mean());
StdOut.println("standard deviation :"+ps.stddev());
StdOut.println("confidence interval low :"+ps.confidenceLo());
StdOut.println("confidence interval high :"+ps.confidenceHi());
}
}