普林斯顿算法课第一周作业
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 }
相关文章推荐
- 算法第一周作业
- Coursera普林斯顿算法课第二次作业
- 计科1111—1114班第一周算法分析作业
- 普林斯顿算法课第五周作业
- 普林斯顿算法课第三周作业
- 第一周算法概论作业
- Coursera普林斯顿算法课第三次作业
- 算法课程Leetcode作业第一周技术博客
- 算法第一周作业 求两个数的最大公约数
- 普林斯顿算法课第四周作业
- 算法 第一周课外作业
- 算法分析与设计课程作业第一周#1
- 算法作业_1(2017.2.25第一周)
- 算法设计与应用基础作业第一周
- 普林斯顿算法课第二周作业
- 第一周:最大子列和问题-算法4:在线处理(作业)
- 【信源编码 作业三】基于LZO算法的词典压缩器实现
- 算法分析与设计的作业:“基于FMM的分词系统”
- 第一周编程作业--1求最大公约数和最小公倍数2排序并插入
- 算法作业:证明题(2)-- 8.8