模型 | 系统化 | 开放的格子 | 闭合的格子 | 连通 |
---|---|---|---|---|
电学 | 电学材料 | 导体 | 绝缘体 | 导电 |
液体流通 | 材料 | 无液体 | 有液体 | 渗漏 |
社交关系 | 人群 | 人 | 空 | 有共同好友 |
9.2 连通的概率
取决于方格为空的概率 p。
PercolatesOrNot当N很大时,理论证实存在一个陡峭的临界点p*。
- p > p*: 基本确信连通
- p < p*: 基本确信不连通
问题: p的值是多少?
9.3 蒙特卡罗模拟(Monte Carlo simulation)
- 初始化一个有N * N个方格的正方形,其中所有方格均是闭合的(blocked)
- 不断随机选取方格,让其开放(open),直到顶部和底部连通停止
- 通过开放的方格数估计p*
9.4 通过动态连通性(Dynamic Connectivity)方法估计连通阈值(percolation threshold)
怎么检测一个 N * N的系统是连通的呢?
- 为每个方格创建一个实例节点,编号从0到N-1
- 如果开放的方格之间有“通路”,说明它们处于同一个分量(Component)(此处参见上一篇文章)
- 当且仅当顶部方格和底部方格支架有通路时,系统连通(暴力算法调用N ^ 2次connected()方法)
一个小技巧:创建两个虚拟的节点,分别连接顶部所有节点和底部所有节点。
-
当虚拟顶部节点和底部节点连通时,整个系统连通(这种情况只需要调用1次connected()方法)
怎么模拟开放一个新节点?
改变此节点的状态;该节点和相邻的节点中(共4个)开放的节点相连
连通阈值(percolation threshold)
连通阈值p* 是多少?
根据大量的仿真实验得出p* 大约为0.592746。
好的算法是 可以 对科学问题得出较为精确的答案。
9.5 编程作业(Programming Assignment - Percolation)
其中要求实现Percolation.java
和 PercolationStats.java
两个文件。
实现这两个文件之后,打包提交到系统中,系统会对两个文件进行详尽的测试,之后给出分数。
Percolation.java
的 API
具体方法的作用
public class Percolation | |
---|---|
public Percolation(int n) | 创建一个有 n * n 个节点的阵列,每个节点都是封闭的 |
public void open(int row, int col) | 如果节点(row, col)未打开,将其打开 |
public boolean isFull(int row, int col) | 判断节点(row, col)是否是满的(即与顶部连通) |
public int numberOfOpenSites() | 已经打开的节点数量 |
public boolean percolates() | 整个系统是否连通 |
PercolationStats.java
的 API
具体方法的作用
public class PercolationStats | |
---|---|
public PercolationStats(int n, int trials) | 在 n * n 个节点的阵列上进行trial次独立重复实验 |
public double mean() | 测试用例连通阈值(percolation threshold)的平均值 |
public double stddev() | 连通阈值的平均差 |
public double confidenceLo() | 计算结果95%置信区间的左边界 |
public double confidenceHi() | 计算结果95%置信区间的右边界 |
通过这些方法能解决的问题
- 方格为空的概率p的值
- 渗析模型(Percolation)中连通阈值(percolation threshold)95%置信区间的范围
- 测试结果的平均差从而得知计算的稳定性
...
关于作业,此处不再详述,因为后面会给出代码,代码中有详细的注释。
可参见参考网址中课程作业的地址,其中有详细要求,作业代码的实现也一并在参考网址中给出。
10. 本节课的言外之意
逐渐实现一个可用的算法步骤:
- 对问题建模
- 找出一个能解决它的算法
- 这个算法足够快吗?内存占用如何?
- 如果答案是否的话,找出原因
- 找到解决方法
- 不断迭代上述步骤,直到满足要求
参考网址
[1] 课程作业 (Assignment - Percolation)
[2] 作业的一个实现
[3] 课件下载(Lecture Slides)
网友评论