算法导论第四版学习——习题一Percolation

题目正文:

http://coursera.cs.princeton.edu/algs4/assignments/percolation.html

作业难点:

1、backwash(倒灌)的判断,如果不使用另一个WeightedUnionFind对象,要在要求的时间和空间范围内实现是很困难的

和论坛里的学生一样,尝试只只使用上部的虚拟节点,下部判断联通使用循环+break,提交后不满足时间复杂度要求

你也可以不考虑backwash这种情况,因为backwash对连通性并没有直接影响

2、UnionFind数据结构是一维的,但是输入数据是二维的,不用说,这需要两个维度的转换

3、输入数据的下标是1到N,所以必须好好测试边界情况,这点可以用测试数据greeting57.txt测试

作业技巧:

1、一般来说避免不必要的计算,把某些固定的值缓存起来可以提高运行效率,比如计算mean和stddev

2、计算PercolationStats时,需要在未打开的site中按概率P取site打开

这一点其实用random一个站点,判断site已打开再循环找下一个site,直到找到未打开site,就可以满足要求了

应该有更有效率的方法,比如将所有site的下标按一维存储,每次将取出的site下标和最后一位互换,下次random时候取uniform(1,N-1),避免无效尝试,以此类推。

代码参考:

(这是我自己亲测100分的答案,不代表写得最好,请在自己实在完成不了的时候再看,不然的话做这个题目的意义一点都没有)

 1 import edu.princeton.cs.algs4.WeightedQuickUnionUF;
 2 
 3 
 4 public class Percolation {
 5     private WeightedQuickUnionUF firstUnionFind;
 6     private WeightedQuickUnionUF secondUnionFind;
 7     private int row = 0;
 8     private boolean[][] site;
 9 
10     public Percolation(int n) // create n-by-n grid, with all sites blocked
11      {
12         if (n <= 0) {
13             throw new IllegalArgumentException();
14         }
15 
16         firstUnionFind = new WeightedQuickUnionUF((n * n) + 2);
17         secondUnionFind = new WeightedQuickUnionUF((n * n) + 1);
18         row = n;
19         site = new boolean[n][n];
20     }
21 
22     public void open(int i, int j) // open site (row i, column j) if it is not open already
23      {
24         if ((i < 1) || (i > row) || (j < 1) || (j > row)) {
25             throw new IndexOutOfBoundsException();
26         }
27         site[i - 1][j - 1] = true;
28         int self = (((i - 1) * row) + j) - 1;
29         int up = self - row;
30         int down = self + row;
31         int left = self - 1;
32         int right = self + 1;
33 
34         if (i == 1) {
35             firstUnionFind.union(row * row, self);
36             secondUnionFind.union(row * row, self);
37         }
38         if (i == row) {
39             firstUnionFind.union(row * row+1, self);
40         }
41 
42         if ((i != 1) && isOpen(i - 1, j)) {
43             firstUnionFind.union(up, self);
44             secondUnionFind.union(up, self);
45         }
46 
47         if ((i != row) && isOpen(i + 1, j)) {
48             firstUnionFind.union(down, self);
49             secondUnionFind.union(down, self);
50         }
51 
52         if ((j != 1) && isOpen(i, j - 1)) {
53             firstUnionFind.union(left, self);
54             secondUnionFind.union(left, self);
55         }
56 
57         if ((j != row) && isOpen(i, j + 1)) {
58             firstUnionFind.union(right, self);
59             secondUnionFind.union(right, self);
60         }
61     }
62 
63     public boolean isOpen(int i, int j) // is site (row i, column j) open?
64      {
65         if ((i < 1) || (i > row) || (j < 1) || (j > row)) {
66             throw new IndexOutOfBoundsException();
67         }
68         return site[i - 1][j - 1];
69     }
70 
71     public boolean isFull(int i, int j) // is site (row i, column j) full?
72      {
73         if ((i < 1) || (i > row) || (j < 1) || (j > row)) {
74             throw new IndexOutOfBoundsException();
75         }
76         int self = (((i - 1) * row) + j) - 1;
77         return secondUnionFind.connected(row * row, self);
78     }
79 
80     public boolean percolates() // does the system percolate?
81      {
82         return firstUnionFind.connected(row * row + 1, row * row);
83     }
84 
85     public static void main(String[] args) // test client (optional)
86      {
87     }
88 }
Percolation
 1 import edu.princeton.cs.algs4.StdOut;
 2 import edu.princeton.cs.algs4.StdRandom;
 3 import edu.princeton.cs.algs4.StdStats;
 4 
 5 
 6 public class PercolationStats {
 7     private int trys = 0;
 8     private double[] successTrials;
 9     private double mean = 0;
10     private double stddev = 0;
11 
12     public PercolationStats(int n, int trials) // perform trials independent experiments on an n-by-n grid
13      {
14         if ((n <= 0) || (trials <= 0)) {
15             throw new IllegalArgumentException();
16         }
17 
18         trys = trials;
19         successTrials = new double[trys];
20 
21         for (int i = 0; i < trials; i++) {
22             successTrials[i] = 0;
23 
24             Percolation percolationTries = new Percolation(n);
25 
26             while (!percolationTries.percolates()) {
27                 int a = StdRandom.uniform(1, n + 1);
28                 int b = StdRandom.uniform(1, n + 1);
29 
30                 while (percolationTries.isOpen(a, b)) {
31                     a = StdRandom.uniform(1, n + 1);
32                     b = StdRandom.uniform(1, n + 1);
33                 }
34 
35                 percolationTries.open(a, b);
36                 successTrials[i]++;
37             }
38 
39             successTrials[i] = successTrials[i] / (n * n);
40         }
41         mean = StdStats.mean(successTrials);
42         stddev =  StdStats.stddev(successTrials);
43     }
44 
45     public double mean() // sample mean of percolation threshold
46     {
47         return mean;
48     }
49 
50     public double stddev() // sample standard deviation of percolation threshold
51     {
52         return stddev;
53     }
54 
55     public double confidenceLo() // low  endpoint of 95% confidence interval
56     {
57         return mean - ((1.96 * stddev) / Math.sqrt(trys));
58     }
59 
60     public double confidenceHi() // high endpoint of 95% confidence interval
61     {
62         return mean + ((1.96 * stddev) / Math.sqrt(trys));
63     }
64 
65     public static void main(String[] args) // test client (described below)
66      {
67         int n = Integer.parseInt(args[0]);
68         int trials = Integer.parseInt(args[1]);
69         PercolationStats percolationStatsCase = new PercolationStats(n, trials);
70         StdOut.printf("%-24s", "mean");
71         StdOut.printf("= %.16f\n", percolationStatsCase.mean());
72         StdOut.printf("%-24s", "stddev");
73         StdOut.printf("= %.18f\n", percolationStatsCase.stddev());
74         StdOut.printf("%-24s", "95% confidence interval");
75         StdOut.printf("= %.16f, %.16f\n", percolationStatsCase.confidenceLo(),
76             percolationStatsCase.confidenceHi());
77     }
78 }
PercolationStats

 

posted @ 2016-09-25 09:28  EnPFighter  阅读(3141)  评论(0编辑  收藏  举报