Algorithms_Percolation

改进

经过几轮提交,改进一下几点:

  • 重复代码提取为private方法
  • 整个scope中反复使用的变量定义为private final
  • 使用的常量定义为常量private static final

经过论坛中提示,修改的几点:

  • 实例化两个WeightedQuickUnionUF:A用来记录上下结点和方块节点的连接关系、B用来记录上节点和方块节点的连接关系
  • 因为在判断isFull时,是判断某节点是否和方块中第一排节点相连。如果用A,由于底部一排节点和下虚节点相连,如下图,当判断下图p点isFull时,可以通过下虚节点找到第一排。所以需要用B。
    在这里插入图片描述
/Percolation///
import edu.princeton.cs.algs4.WeightedQuickUnionUF;

public class Percolation {
    private boolean[][] open;
    private int count;
    private final WeightedQuickUnionUF wquuf1; // t & b
    private final WeightedQuickUnionUF wquuf2; // only top
    private final int len;


    public Percolation(int n) {
        if (n <= 0) throw new IllegalArgumentException();
        open = new boolean[n + 1][n + 1];
        wquuf1 = new WeightedQuickUnionUF(n * n + 2); // n*n+2 -> top & bottom virtual point
        wquuf2 = new WeightedQuickUnionUF(n * n + 1); // n*n+1 -> top virtual point
        len = n; // n

        for (int i = 0; i <= n; i++) {
            for (int j = 0; j <= n; j++) {
                open[i][j] = false;
            }
        }

        // 初始绑定虚节点
        for (int i = 0; i < n; i++) {
            union(i, n * n);
            wquuf1.union((n - 1) * n + i, n * n + 1);
        }
    }

    private void validate(int row, int col) {
        if (row < 1 || row > len || col < 1 || col > len) {
            throw new IllegalArgumentException();
        }
    }

    private void union(int p, int q) {
        wquuf1.union(p, q);
        wquuf2.union(p, q);
    }

    private int dConvertor(int row, int col) {
        return (row - 1) * len + (col - 1);
    }

    public void open(int row, int col) {
        this.validate(row, col);
        if (open[row][col]) {
            return;
        }
        open[row][col] = true;
        count++;

        int tp = dConvertor(row, col); // this point in wquuf
        int cp;  // connected point in wquuf

        if ((row - 1) >= 1 && open[row - 1][col]) {
            cp = dConvertor(row - 1, col);
            union(tp, cp);
        }

        if ((row + 1) <= len && open[row + 1][col]) {
            cp = dConvertor(row + 1, col);
            union(tp, cp);
        }

        if ((col - 1) >= 1 && open[row][col - 1]) {
            cp = dConvertor(row, col - 1);
            union(tp, cp);
        }

        if ((col + 1) <= len && open[row][col + 1]) {
            cp = dConvertor(row, col + 1);
            union(tp, cp);
        }
    }

    public boolean isOpen(int row, int col) {
        this.validate(row, col);

        return open[row][col];
    }

    public boolean isFull(int row, int col) {
        this.validate(row, col);

        if (!open[row][col]) return false; //如果不是open肯定不是full
        return wquuf2.find(len * len) == wquuf2.find(dConvertor(row, col));

    }

    public int numberOfOpenSites() {
        return count;
    }

    public boolean percolates() {
        return wquuf1.find(len * len) == wquuf1.find(len * len + 1);
    }


}

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

public class PercolationStats {
    private static final double CONFIDENCE_95 = 1.96;
    private final double[] xt;
    
    // perform independent trials on an n-by-n grid
    public PercolationStats(int n, int trials) {
        if (n <= 0 || trials <= 0) throw new IllegalArgumentException();
        int x, y;
        xt = new double[trials];
        for (int i = 0; i < trials; i++) {
            Percolation percolation = new Percolation(n);
            while (!percolation.percolates()) {
                x = StdRandom.uniform(1, n + 1);
                y = StdRandom.uniform(1, n + 1);
                percolation.open(x, y);
            }
            xt[i] = (double) percolation.numberOfOpenSites() / n / n;
        }
    }

    // sample mean of percolation threshold
    public double mean() {
        // StdOut.println(Arrays.toString(xt));
        return StdStats.mean(xt);
    }

    // sample standard deviation of percolation threshold
    public double stddev() {
        if (xt.length == 1) return Double.NaN;
        return StdStats.stddev(xt);
    }

    // low endpoint of 95% confidence interval
    public double confidenceLo() {
        return this.mean() - CONFIDENCE_95 / Math.sqrt(xt.length);
    }


    // high endpoint of 95% confidence interval
    public double confidenceHi() {
        return this.mean() + CONFIDENCE_95 / Math.sqrt(xt.length);
    }

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

        PercolationStats percolationStats = new PercolationStats(Integer.parseInt(args[0]),
                                                                 Integer.parseInt(args[1]));

        StdOut.printf("mean                    = %.6f\n", percolationStats.mean());
        StdOut.printf("stddev                  = %.17f\n", percolationStats.stddev());
        StdOut.printf("95%% confidence interval = [%.15f, %.15f]\n",
                      percolationStats.confidenceLo(), percolationStats.confidenceHi());


    }


}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值