Coursera Algorithms Percolation解题记录

简述

第一周作业:
https://www.coursera.org/learn/algorithms-part1/programming/Lhp5z/percolation
首先按照指导安装algs4,之后自动下载的DrJava用的很不顺手,就换成使用IDEA了。编程时记得把algs4.jar加入依赖项,之后修改运行启动参数进行调试即可。
这里写图片描述

这里写图片描述

Percolation.java要完成的工作是构建一个N * N的方格编写相应方法查看渗漏情况,PercolationStats.java则是要求给定方格大小量n与测试次数trials通过模拟得到渗漏漏阈值范围,说明中也给出了计算方法。
这里写图片描述

回流问题

回流问题是指因为我们虚拟了顶部结点与底部结点,所以导致底部任一结点渗漏成功的话底部所有结点都会认为渗漏成功,原因是通过底部虚拟结点形成了回流。解决方法是准备两个WeightedQuickUnionUF,一个有顶部、底部虚拟结点,一个只有顶部虚拟结点,判断结点是否渗漏时用第二个没底部的结构来判断,防止因回流问题导致误判。

实现

//Percolation.java
import edu.princeton.cs.algs4.WeightedQuickUnionUF;

public class Percolation {
    private WeightedQuickUnionUF uf1, uf2;
    private int n, openedNum = 0;
    private boolean[] blocked;

    public Percolation(int n) {               // create n-by-n grid, with all sites blocked
        if (n <= 0) {
            throw new IllegalArgumentException("n:" + n + " is invalid.");
        }
        this.n = n;
        //uf1、uf2初始化省略,防止直接粘贴。
        uf1 = ...;
        uf2 = ...;   //防止底部回流问题,放一没底部虚拟结点的结构。
        blocked = new boolean[n * n];
        for (int i = 0; i < blocked.length; i++) {
            blocked[i] = true;
        }

        //初始化顶部、底部结点联通性。
        for (int i = 0; i < n; i++) {
            uf1.union(i, n * n);
            uf2.union(i, n * n);

            uf1.union((n - 1) * n + i, n * n + 1);
        }
    }

    private void union(int p, int q) {
        uf1.union(p, q);
        uf2.union(p, q);
    }

    public void open(int row, int col) {    // open site (row, col) if it is not open already
        validate(row, col);
        row--;
        col--;
        int key = row * n + col;
        if (!blocked[key]) {
            return;
        }
        blocked[key] = false;
        openedNum++;


        //left, up, right, down.
        if (col > 0 && !blocked[key - 1]) {
            union(key, key - 1);
        }
        if (row > 0 && !blocked[key - n]) {
            union(key, key - n);
        }
        if (col < n - 1 && !blocked[key + 1]) {
            union(key, key + 1);
        }
        if (row < n - 1 && !blocked[key + n]) {
            union(key, key + n);
        }
    }

    private void validate(int row, int col) {
        if (row <= 0 || row > n || col <= 0 || col > n) {
            throw new IndexOutOfBoundsException("row:" + row + " or col:" + col + " is invalid.");
        }
    }

    public boolean isOpen(int row, int col) { // is site (row, col) open?
        validate(row, col);
        return !blocked[(row - 1) * n + (col - 1)];
    }

    public boolean isFull(int row, int col) {  // is site (row, col) full?
        validate(row, col);
        int key = (row - 1) * n + (col - 1);
        return (uf2.connected(key, n * n) && !blocked[key]);  //与顶部虚拟结点连通并且该结点是打开状态。
    }

    public int numberOfOpenSites() {       // number of open sites
        return openedNum;
    }

    public boolean percolates() {            // does the system percolate?
        return n == 1 ? !blocked[0] : uf1.connected(n * n, n * n + 1);
    }

    public static void main(String[] args) {   // test client (optional)
//        Percolation p = new Percolation(8);
//        p.open(1, 3);
////        p.open(2, 6);
//        p.open(3, 3);
//        System.out.println(p.isFull(3, 3));
    }
}


//PercolationStats.java
import edu.princeton.cs.algs4.StdRandom;
import edu.princeton.cs.algs4.StdStats;

/**
 * Created by tp730 on 4/27/2017.
 */
public class PercolationStats {
    private double stddev = Double.NaN;
    private double mean = Double.NaN;
    private double confidenceLo = Double.NaN;
    private double confidenceHi = Double.NaN;

    public PercolationStats(int n, int trials) {   // perform trials independent experiments on an n-by-n grid
        if (n <= 0 || trials <= 0){
            throw new IllegalArgumentException("n:" + n + " or trials:" + trials + " is invalid.");
        }
        double[] trailsResult = new double[trials];
        for(int i = 0; i < trailsResult.length; i++){
            trailsResult[i] = generateRandomPercolationModel(n);
        }
        this.mean = StdStats.mean(trailsResult);
        this.stddev = StdStats.stddev(trailsResult);
        this.confidenceLo = mean - 1.96 * stddev / Math.sqrt(trials);
        this.confidenceHi = mean + 1.96 * stddev / Math.sqrt(trials);
    }

    private double generateRandomPercolationModel(int n) {
        Percolation p = new Percolation(n);
        double openCount = 0;
        while(!p.percolates()){
            int row = StdRandom.uniform(n) + 1;
            int col = StdRandom.uniform(n) + 1;
            if (!p.isOpen(row, col)){
                p.open(row, col);
                openCount++;
            }
        }
        return openCount / (n * n);
    }

    public double mean(){                          // sample mean of percolation threshold
        return this.mean;
    }
    public double stddev(){                        // sample standard deviation of percolation threshold
        return this.stddev;
    }
    public double confidenceLo(){                  // low  endpoint of 95% confidence interval
        return this.confidenceLo;
    }
    public double confidenceHi(){                  // high endpoint of 95% confidence interval
        return this.confidenceHi;
    }

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

猜你喜欢

转载自blog.csdn.net/tp7309/article/details/70879407
今日推荐