使用合并-查找数据结构,实现估计渗漏(Percolation)问题阈值的程序。

编写一个程序,通过蒙特卡罗模拟来估计渗滤阈值。

引言:

给定一个由随机分布的绝缘材料和金属材料组成的复合系统:多少材料需要是金属的,以便复合系统是电导体?考虑到地表(或下面的油)有水的多孔景观,在什么条件下水能够通过底部排出(或油喷到表面)?科学家已经定义了一个被称为渗流的抽象过程来模拟这种情况。该模型。我们用一个N×N的网格模型来建立一个渗流系统。每个网站都是开放或封锁。一个完整的网站是一个开放的网站,可以通过一系列相邻的(左,右,上,下)开放网站连接到最上面的一个开放网站。我们说如果底部有一个完整的网站,系统会渗透。换句话说,如果我们填充连接到最上一行的所有打开的站点,并且该过程填满最下一行的一些打开站点,那么系统会渗透。 (对于绝缘/金属材料的例子,开放部位对应于金属材料,使得渗透的体系具有从上到下的金属路径,并且完整的部位导电。对于多孔物质实例,开放部位对应于空的空间水可以通过它流动,使渗透的系统让水充满开放的地点,从上到下流动。)

问题:(如果已经知道题目,可以直接越过此处)

在一个著名的科学问题中,研究人员对以下问题感兴趣:如果网站独立设置为以概率p打开(因此以概率1-p被阻塞),系统渗透的概率是多少?当p等于0时,系统不会渗透;当p等于1时,系统渗透。下面的图显示了20×20随机网格(左)和100×100随机网格(右)的网站空置概率p对渗滤概率

当N足够大时,存在阈值p’,使得当p < p’时,随机N×N网格几乎不渗滤,并且当p> p’时,随机N×N网格几乎总是渗滤。尚未推导出用于确定渗透阈值p’的数学解决方案。你的任务是编写一个计算机程序来估计p’。
程序Percolation实现的API接口如下:

public class Percolation {public Percolation(int N)           // create N-by-N grid, with all sites blockedpublic void open(int i, int j)         // open site (row i, column j) if it is not alreadypublic boolean isOpen(int i, int j)    // is site (row i, column j) open?public boolean isFull(int i, int j)     // is site (row i, column j) full?public boolean percolates()          // does the system percolate?public static void main(String[] args)  // test client, optional
}

按照惯例,行和列索引i和j是1和N之间的整数,其中(1,1)是左上角站点:如果open(),isOpen()或isFull()的任何参数抛出IndexOutOfBoundsException超出了规定的范围。如果N≤0,构造函数应该抛出IllegalArgumentException。构造函数应该花费与N2成正比的时间;所有方法都应该花费不变的时间加上对union(),find(),connected()和count()的联合查找方法的不断调用。
蒙特卡洛模拟。为了估计逾渗阈值,考虑下面的计算实验:
•初始化所有要阻止的站点。
•重复以下操作,直到系统渗漏:
o在所有被封锁的网站中随机选择一个网站(第i行,第j列)。
o打开网站(第i行,第j列)。
•系统渗透时打开的部分网站提供了渗透阈值的估计值。
例如,如果按照下面的快照打开网格,那么我们估计的渗滤阈值是204/400 = 0.51,因为当第204个站点打开时,系统渗透。

通过重复该计算实验T次并平均结果,我们获得更准确的逾渗阈值估计。 设x_t为计算实验t中开放点的分数。 样本平均值μ提供了渗透阈值的估计; 样本标准偏差σ测量阈值的清晰度。

假设T足够大(例如至少30),下面提供渗透阈值的95%置信区间

程序PercolationStats 的API接口:

public class PercolationStats {public PercolationStats(int N, int T)    // perform T independent computational experiments on an N-by-N gridpublic double mean()                // sample mean of percolation thresholdpublic double stddev()               // sample standard deviation of percolation thresholdpublic double confidenceLo()         // returns lower bound of the 95% confidence intervalpublic double confidenceHi()         // returns upper bound of the 95% confidence intervalpublic static void main(String[] args)    // test client, described below
}

此外,还包括一个main()方法,该方法使用两个命令行参数N和T(其中N代表网格大小,T代表实验尝试的次数),在N×N网格上执行T个独立的计算实验(上面讨论),打印出平均值,标准偏差,95% 置信阈值的置信区间。 使用标准库中的标准随机数生成随机数; 使用标准统计来计算样本均值和标准差。

% java PercolationStats 200 100
mean    = 0.5929934999999997
stddev   = 0.00876990421552567
95% confidence interval = 0.5912745987737567, 0.5947124012262428% java PercolationStats 200 100
mean    = 0.592877
stddev   = 0.009990523717073799
95% confidence interval = 0.5909188573514536, 0.5948351426485464% java PercolationStats 2 10000
mean    = 0.666925
stddev   = 0.11776536521033558
95% confidence interval = 0.6646167988418774, 0.6692332011581226% java PercolationStats 2 100000
mean    = 0.6669475
stddev   = 0.11775205263262094
95% confidence interval = 0.666217665216461, 0.6676773347835391

Percolation

public class Percolation {private int matrixLength;private boolean[] matrix;
//  private WeightedQuickUnion wqu;private PathCompressWQU pwqu;private int virtualTop;private int virtualbottom;public Percolation(int N){if (N <= 0) {throw new IllegalArgumentException("length must be positive");}matrixLength = N;virtualTop = matrixLength * matrixLength;virtualbottom = matrixLength * matrixLength + 1;matrix = new boolean[N * N];//      wqu = new WeightedQuickUnion(N * N + 2);pwqu = new PathCompressWQU(N * N + 2);}private void checkValidIndex(int row,int col){if(row <= 0 || row >matrixLength){throw new IndexOutOfBoundsException("row index out of bounds");}if(col <= 0 || col >matrixLength){throw new IndexOutOfBoundsException("col index out of bounds");}}private int rowCol_to_real(int row,int col){return (row - 1) * matrixLength + col - 1;}public void open(int row,int col){checkValidIndex(row, col);                      //检查边界int real = rowCol_to_real(row, col);            //转换成以为坐标if (matrix[real]) {return;                                     //如果已经是打开的,就直接返回}matrix[real] = true;if (row == 1) {                                 //如果是第一行的情况,那么让他连接top的虚拟点
//            wqu.union(real, virtualTop);pwqu.union(real, virtualTop);//System.out.println("Connected Top");}if (row == matrixLength) {                      //如果是最后一行的情况,那么让他连接bottom的虚拟点
//            wqu.union(real, virtualbottom);pwqu.union(real, virtualbottom);//System.out.println("Connected Bottom");}int neighbor;//判断周围的四个点是否是打开的,如果是的话就连接if (row > 1) {                                  // upneighbor = rowCol_to_real(row - 1, col);if (matrix[neighbor]) {
//                wqu.union(real, neighbor);pwqu.union(real, neighbor);}}if (row < matrixLength) {                       // downneighbor = rowCol_to_real(row + 1, col);if (matrix[neighbor]) {
//                wqu.union(real, neighbor);pwqu.union(real, neighbor);}}if (col > 1) {                                  // leftneighbor = rowCol_to_real(row, col - 1);if (matrix[neighbor]) {
//                wqu.union(real, neighbor);pwqu.union(real, neighbor);}}if (col < matrixLength) {                       // rightneighbor = rowCol_to_real(row, col + 1);if (matrix[neighbor]) {
//                wqu.union(real, neighbor);pwqu.union(real, neighbor);}}}public boolean isOpen(int row,int col){             //判断这个点是不是打开的checkValidIndex(row, col);return matrix[rowCol_to_real(row, col)];}public boolean isFull(int row,int col){             //判断这个点是不是和virtualtop连接,也就是是不是开放的,能不能连接到顶端的点checkValidIndex(row, col);
//      return wqu.isConnect(virtualTop, rowCol_to_real(row, col));return pwqu.isConnect(virtualTop, rowCol_to_real(row, col));}public boolean isPercolated(){                      //判断是否渗透
//      return wqu.isConnect(virtualTop, virtualbottom);return pwqu.isConnect(virtualTop, virtualbottom);}}

在这里我们需要考虑一个问题就是当你输入的N=1的时候,更具下面的公式我们就会发现在计算偏差的时候就会出现除0的情况,所以在代码中应该考虑到。

 matrixLength = N;if (matrixLength == 1) {mean = 1;stddev = Double.NaN;confidenceLow = Double.NaN;confidenceHigh = Double.NaN;}

PercolationStats

import java.util.Scanner;public class PercolationStats {private int matrixLength;private double[] threshold;private double mean;                //平均值private double stddev;              //标准偏差private double confidenceLow;   // 最低置信度private double confidenceHigh;    // 高置信度public PercolationStats(int N, int T) {if (N <= 0) {throw new IllegalArgumentException("length must be positive");}if (T <= 0) {throw new IllegalArgumentException("trials must be positive");}matrixLength = N;if (matrixLength == 1) {mean = 1;stddev = Double.NaN;confidenceLow = Double.NaN;confidenceHigh = Double.NaN;}else {threshold = new double[T];for(int i = 0;i < T;++i){Percolation percolation = new Percolation(N);int count = 0;do {int row = (int)(Math.random()*(matrixLength)) + 1;int col = (int)(Math.random()*(matrixLength)) + 1;//System.out.println("row= " + row+" , " + " col= " + col);//System.out.println("count= " + count);if(percolation.isOpen(row, col)){continue;}else{percolation.open(row, col);++count;}} while (!percolation.isPercolated());threshold[i] = (double)count / (matrixLength * matrixLength);}mean = Computemean(threshold,T);stddev = Computestddev(threshold,T);double diff = (1.96 * stddev) / Math.sqrt(T);confidenceLow = mean - diff;confidenceHigh = mean + diff;}}private double Computemean(double[] threshold,int T) {double sum = 0;for(int i =0 ;i < threshold.length;++i){sum += threshold[i];}return sum / T;}private double Computestddev(double[] threshold,int T) {double sum = 0;for(int i =0 ;i < threshold.length;++i){sum += Math.pow(threshold[i]-mean, 2);}return Math.sqrt(sum/ (T - 1));}public double Getmean() {return mean;}// public double Getstddev() {return stddev;}// public double GetconfidenceLow() {return confidenceLow;}// public double GetconfidenceHigh() {return confidenceHigh;}public static void main(String[] args) {System.out.println("Please enter N and T : ");  //Length  and TimesScanner in = new Scanner(System.in);int N = in.nextInt();int T = in.nextInt();PercolationStats percolationStats = new PercolationStats(N,T);System.out.println("The mean of percolationStats is " + percolationStats.Getmean());System.out.println("The stddev of percolationStats is " + percolationStats.Getstddev());System.out.println("The condidence  intervals of percolationStats is " + "[" + percolationStats.GetconfidenceLow() + " , " +  percolationStats.GetconfidenceHigh() + "]");in.close();}}

路径压缩算法


//import java.util.Scanner;public class PathCompressWQU {private int[] id;private int[] sz;private int count;public PathCompressWQU(int N){count=N;id=new int[N];sz=new int[N];for(int i=0;i<N;++i){id[i]=i;sz[i]=1;}}public int getcount(){return count;}public boolean isConnect(int p,int q){return find(p)==find(q);}public int find(int p) {//复杂度为两倍的树的高度h 即2hint temp = p;while(p!=id[p]){p=id[p];}while(temp != id[p]){int tempId = id[temp];id[temp] = id[p];temp = tempId;}return id[p];}public void union(int p,int q){//不计算find的情况下 union的算法复杂度为1int pRoot=find(p);int qRoot=find(q);if(pRoot==qRoot){return;}if(sz[pRoot]<sz[qRoot]){id[pRoot]=qRoot;sz[qRoot]+=sz[pRoot];}else{id[qRoot]=pRoot;sz[pRoot]+=sz[qRoot];}count--;}
/*public static void main(String[] args) {// TODO Auto-generated method stubScanner in=new Scanner(System.in);int N=in.nextInt();PathCompressWQU  pcwqu=new PathCompressWQU(N);while(in.hasNext()){int p=in.nextInt();int q=in.nextInt();if(pcwqu.isConnect(p, q)){System.out.println("p and q had benn in a componment!");continue;}pcwqu.union(p, q);System.out.println(pcwqu.getcount()+" componments" );}in.close();}
*/  }

渗漏(Percolation)问题(java语言实现)相关推荐

  1. Java语言中的数据类型

    Java语言是一种强调数据类型的语言,在声明任何变量时,必须将该变量定义为一种数据类型. Java中的数据类型包括基本类型和对象类型,基本类型总共有8种,其中4种整形.1种字符型.2种浮点型.1种布尔 ...

  2. java语言环境变量_JAVA语言环境变量的设置教程

    本文主要向大家介绍了JAVA语言环境变量的设置教程,通过具体的内容向大家展示,希望对大家学习JAVA语言有所帮助. 安装JDK到目录,我这里是C:\Java 右键点击计算机属性 在系统变量里面建 JA ...

  3. java语言的实现机制_JAVA语言之Java NIO的工作机制和实现原理介绍

    本文主要向大家介绍了JAVA语言之Java NIO的工作机制和实现原理介绍,通过具体的内容向大家展示,希望对大家学习JAVA语言有所帮助. 前言 本文只简单介绍NIO的原理实现和基本工作流程 I/O和 ...

  4. Java语言的基础知识9

    第十一章(线程) 1.通过String name=Thread.currentThread().getName();来获取当前线程的名称. 2.多次启动一个线程或者启动一个已经运行的线程是非法的,会抛 ...

  5. 重塑云上的 Java 语言

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 Photo @  Toa Heftiba 文 |郁磊 音乐无国界, ...

  6. 四川大学java试题_四川大学2013年计算机(软件)学院Java语言程序设计期末考试试题B卷...

    四川大学期末考试试题(闭卷) (2013 -2014学年第1学期) 课程号:课程名称: Java语言程序设计(B 卷)任课教师: 适用专业年级:学号:姓名: 一.单项选择题(本大题共20小题,每小题2 ...

  7. “坑爹”排行榜:Java语言最违反常识的功能点TOP 10

    来自:互联网全栈架构 作为一门面向对象的编程语言,Java凭借其简单易用.功能强大的特点受到了广大编程爱好者的青睐,伴随着开源社区的推波助澜,Java语言更是席卷全球,势不可挡,在世界各地都有Java ...

  8. Java语言中的生僻知识

    最近有一首名叫<生僻字>的流行歌曲火遍大江南北,创作者给佶屈聱牙的生僻字,配上了优美明快的旋律,竟然让歌曲变得琅琅上口.悦耳动听起来,平时不太常见的拒人于千里之外的这些汉字也不再那么陌生, ...

  9. java语言仅支持单重继承_java语言程序设计基础篇习题_复习题_第十一章

    java语言程序设计基础篇习题_复习题_第十一章 11.1 下面说法是真是假?一个子类是父类的子集. 11.2 使用什么关键字来定义一个子类 11.3 什么是单一继承?什么是多重继承?java支持多重 ...

最新文章

  1. 设计模式————单例模式
  2. Nodejs的http模块
  3. leetcode 155. 最小栈
  4. mysql find()方法_Mysql find_in_set()函数使用方法
  5. 04_机器学习概述,什么是机器学习,应用场景,数据来源与类型,网上可用的数据集、常用数据集数据的结构组成、特征工程是什么、意义、特征抽取、sklearn特征抽取API、文本特征抽取(学习笔记)
  6. SQL -- 多表查询
  7. Ubuntu系统常用命令
  8. C 语言的数据类型宽度扩展
  9. k8s部署jar包_K8S部署SpringBoot应用_都超的博客-CSDN博客_k8s springboot
  10. 窗口间的通信(消息互发与数据传递)
  11. FishC笔记—26 讲 字典:当索引不好用时2
  12. 窗口大小不规范,教你怎么写默认窗口
  13. [问题已处理]- kubernetes报错error creating overlay mount to xx merged- no such file or directory
  14. rust怎么上邮轮_实拍沉入海底的泰坦尼克号:被海水腐蚀严重,船体将于10年后消失...
  15. 更改浏览器默认的网址
  16. SEO是做什么的,每天需要做什么
  17. unity种四种光源
  18. 杰森xbl_每日新闻摘要:Google杀死了230万个不良广告,微软宣布XBL游戏栈等等
  19. Linux上一款强大的GIF录制软件,Peek
  20. 浅谈虚拟机的垃圾回收

热门文章

  1. 017利用颅内和头皮脑电图进行癫痫预测的卷积神经网络2018
  2. 最快速度找到内存泄漏
  3. flac转换成mp3,4种方法教会你
  4. Android按back键不退出当前Activity
  5. 直线模组常用的驱动模式有哪些?
  6. 小米红米Note4X(高配版)线刷兼救砖_解账户锁_纯净刷机包_教程
  7. html web 表单
  8. Nginx的模块与工作原理
  9. python学习第九天
  10. 天津最新建筑施工八大员之(安全员)考试真题及答案解析