Union-Find 并查集算法
解决动态连通性一类问题的一种算法
使用场景:
网络连接判断
变量名等同性
社交网络
例如
实现:
Quick-find
Quick-Union
Weighted quick-union
Weighted quick-union with path compression
蒙特卡洛模拟
也称为计算机随机模拟方法,是一种基于”随机数”的计算方法。特点是,可以在随机采样上计算得到近似结果,随着采样的增多,得到的结果是正确结果的概率逐渐加大
例子,蒙特卡罗方法求π。就是画一个正方形和内切圆,随机撒点,数一下点落在园内和正方形内的数量之比,就是二者面积之比π/4。
渗透模型
n*n 个点组成的网格,每个点是 Open 或 Closed 状态。假如最底部的点和最顶端的点连通,就说明这个网格系统是渗透的。
比如图中黑色表示 Closed 状态,白色表示 Open,蓝色表示与顶部连通。所以左图是渗透的,右图不是:
应用场景:
判断由绝缘体和金属材料组成的一个物体什么情况可以导电
判断一块多空地形,什么情况可以让水或者油渗透过去
问题
假设每个点是 Open 状态的概率是 p,计算整个系统是渗透的概率。
图片为 20*20、100*100 网格的概率分布:
计算方法概述
利用蒙特卡洛模拟
* 初始化 n*n 全为 Blocked 的网格系统
* 随机 Open 一个点,重复执行,直到整个系统变成渗透的为止
* 上述过程重复 T 次,计算平均值、标准差、96% 置信区间
用 Union-Find 算法判断连通性
增加两个虚拟节点,将问题简化为判断两个虚拟节点之间是否连通
增加一个只有顶端虚拟节点的并查集,避免 backwash(其它方法参考:http://www.sigmainfy.com/blog/avoid-backwash-in-percolation.html)
代码
Percolation.java
/******************************************************************************
* Compilation: javac-algs4 Percolation.java
* Execution: java-algs4 Percolation < input.txt
* Dependencies: None
*
* This program reads standard input.
*
* - Reads the grid size n of the percolation system.
* - Creates an n-by-n grid of sites (intially all blocked)
* - Reads in a sequence of sites (row i, column j) to open.
*
* After each site is opened, it checks if the system is percolated.
******************************************************************************/
import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.WeightedQuickUnionUF;