1. 程式人生 > >Coursera普林斯頓大學演算法Week1: Percolation 滲透

Coursera普林斯頓大學演算法Week1: Percolation 滲透

首先說一下做這個作業大概的幾個要點:

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());
	}
	
}