您的位置:首页 > 其它

普林斯顿算法课第一周作业

2015-01-27 13:49 260 查看

Programming Assignment 1: Percolation

作业网址如下: http://coursera.cs.princeton.edu/algs4/assignments/percolation.html
正文
--------------------------------------------------------------
第一章的作业需要制作两个类

第一个Percolation包含五个方法,主要是用来打开渗漏的格子。

第二个类PercolationStats 同样有五个方法,用来找出N*N格子中,能够产生渗漏的阈值概率的95%置信区间。

先说一下大概的想法和原理。

官网上提供有这道题目的思路,就是在创建格子的过程中首先要在顶层和底层各加一层,

这样的话在测试是否渗漏时直接测试(0,1)和(N+1,1)就好了

首先来说下第一个类:

官网的API已经写好:

public class Percolation {
public Percolation(int N)               // create N-by-N grid, with all sites blocked
public void open(int i, int j)          // open site (row i, column j) if it is not open already
public boolean isOpen(int i, int j)     // is site (row i, column j) open?
public boolean isFull(int i, int j)     // is site (row i, column j) full?
public boolean percolates()             // does the system percolate?

public static void main(String[] args   // test client (optional)
}


1.构造函数 public Percolation(int N)

运用了虚拟节点的方法,把坐标(i,j)转化为(i*N+J),这样能更直观的找到坐标点的位置。

可以直接使用quick-find 和quick-union。

为了实现这个目标,调用WeightedQuickUnionUF创建了一个((N+1)*(N)+N+1)的一位数组。

第零排和第N+1排用来判断是否渗漏,而第零列被整体抛弃。

这样的做法是浪费了一定的存储空间,若非为了查找坐标方便,采用N*N+2个格子也是足够用的。

2.public void open(int i, int j)

判断该点是否打开,如果打开则结束。未打开则与上下左右四个点连接。

3.public boolean isOpen(int i, int j)

只需要返回该点的开闭状态值;

4.public boolean isFull(int i, int j)

判断该点是否与顶部联通。

5.public boolean percolates()

判断是否渗漏

也就是检查(0,1)和(N+1,1);

注意:题目中提到了一个回流问题(如图)



由于底部的一排是联通的,那么所有与底部相连的点将会出现“灌水”。

为了解决这个问题,就要再建立一个不包含最底层的格子。在isFull()中使用该数组进行检查

如果底部的格子确实没有与顶部的虚拟点连通,是不会“灌满”的。
全部代码如下:
public class Percolation {
private WeightedQuickUnionUF uf;
private WeightedQuickUnionUF uf_backwash;
private int N;
//private int count_n=0;//record the number of open site;
private boolean[] ifopen;//an array record if the site is open;

public Percolation(int N) {
if (N<=0) throw new IllegalArgumentException("N is<=0");
this.N = N;
int i;
uf=new WeightedQuickUnionUF((N+1)*(N)+N+1);
uf_backwash=new WeightedQuickUnionUF(N*N+N+1);
ifopen=new boolean[(N+1)*(N)+N+1];
for(i=1;i<=N;i++){
uf.union(0*N+1, 0*N+i);
uf_backwash.union(0*N+1, 0*N+i);
ifopen[0*N+i]=true;
uf.union((N+1)*N+1, (N+1)*N+i);
ifopen[(N+1)*N+i] = true;
}
}// create N-by-N grid, with all sites blocked
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");

if(ifopen[i*N+j]) return;
ifopen[i*N+j]=true;
//count_n++;
if (ifopen[(i-1)*N+j]){
uf.union(i*N+j, (i-1)*N+j);
uf_backwash.union(i*N+j, (i-1)*N+j);
}
if (ifopen[(i+1)*N+j]){
uf.union(i*N+j, (i+1)*N+j);
if (i!=N){
uf_backwash.union(i*N+j, (i+1)*N+j);
}
}
if (j!=1 && ifopen[i*N+j-1]){
uf.union(i*N+j, i*N+j-1);
uf_backwash.union(i*N+j, i*N+j-1);
}
if (j!=N && ifopen[i*N+j+1]){
uf.union(i*N+j, i*N+j+1);
uf_backwash.union(i*N+j, i*N+j+1);
}

}// open site (row i, column j) if it is not already
public boolean isOpen(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 ifopen[i*N+j];
}// is site (row i, column j) open?
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 uf_backwash.connected(i*N+j, 0*N+1) && ifopen[i*N+j];
} // is site (row i, column j) full?
public boolean percolates() {
return uf.connected(0*N+1, (N+1)*N+1);
}// does the system percolate?
public static void main(String[] args){
int N = StdIn.readInt();
Percolation pe=new Percolation(N);
pe.open(1, 1);
pe.open(2, 1);
System.out.println(pe.percolates());
}// test client, optional

}


第二个类:

public class PercolationStats {
public PercolationStats(int N, int T)     // perform T independent experiments on an N-by-N grid
public double mean()                      // sample mean of percolation threshold
public double stddev()                    // sample standard deviation of percolation threshold
public double confidenceLo()              // low  endpoint of 95% confidence interval
public double confidenceHi()              // high endpoint of 95% confidence interval

public static void main(String[] args)    // test client (described below)
}


这个类是用来求取统计概率,想法如下:

初始化一个N*N格子,并处于关闭状态。

每次随机选择一个格子进行开启操作,直到渗漏为止。

记录此时打开格子数与总格子数的比例P

重复N此得到最后的样本平均值。

1.public PercolationStats(int N, int T)

进行T次关于N*N格子的独立重复试验。

进行一次循环,通过Percolation类构造函数,用到了书中给出的类库

StdRandom.uniform(int N) 生成随机数

StdStats.mean(double); 求均值

StdStats.stddev(double);求方差

全部代码如下:
public class PercolationStats {
private double staT[];
private double sta_mean;
private double sta_stddev;
private int N;
public PercolationStats(int N, int T){
staT=new double[T];
this.N=N;
int times=0;
if(N<=0) throw new IllegalArgumentException();
if(T<=0) throw new IllegalArgumentException();
while(times<T){
Percolation pe=new Percolation(N);
int count=0;
while(true){
count++;
while(true){
int x = StdRandom.uniform(N) + 1;
int y = StdRandom.uniform(N) + 1;
if(pe.isOpen(x, y)){
continue;
}else{
pe.open(x, y);
break;
}

}
if(pe.percolates()){
staT[times]=(double)count/((double)N*(double)N);
break;
}
}
times++;
}
this.sta_mean = StdStats.mean(staT);
this.sta_stddev = StdStats.stddev(staT);
}// perform T independent computational experiments on an N-by-N grid
public double mean(){
return this.sta_mean;
}// sample mean of percolation threshold
public double stddev(){
return this.sta_stddev;
} // sample standard deviation of percolation threshold
public double confidenceLo(){
return this.sta_mean-1.96*this.sta_stddev/Math.sqrt(N);
}// returns lower bound of the 95% confidence interval
public double confidenceHi(){
return this.sta_mean+1.96*this.sta_stddev/Math.sqrt(N);
}             // returns upper bound of the 95% confidence interval
public static void main(String[] args){

int N = StdIn.readInt();
int T = StdIn.readInt();
PercolationStats percolationStats = new PercolationStats(N, T);
StdOut.println("mean = " + percolationStats.mean());
StdOut.println("stddev = " + percolationStats.stddev());
StdOut.println("95% confidence interval " + percolationStats.confidenceLo() + ", " + percolationStats.confidenceHi());
} // test client, described below
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: