Coursera普林斯頓大學演算法Week1: Percolation 滲透
阿新 • • 發佈:2018-12-30
首先說一下做這個作業大概的幾個要點:
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()); } }