Java 有加权和未加权快速联合查找问题
底部的TLDR 我在学校被分配了一个编程项目来建立一个渗流模型,我遇到了一个问题,这个问题让我有些困惑。首先,我们应该构建一个api来运行渗流模拟Java 有加权和未加权快速联合查找问题,java,weighted,union-find,Java,Weighted,Union Find,底部的TLDR 我在学校被分配了一个编程项目来建立一个渗流模型,我遇到了一个问题,这个问题让我有些困惑。首先,我们应该构建一个api来运行渗流模拟 public class Percolation{ private int grid[][]; public int size; QuickFindUF unionFind; //WeightedQuickUnionUF unionFind; public Percolation(int n) { if(n<1){
public class Percolation{
private int grid[][];
public int size;
QuickFindUF unionFind;
//WeightedQuickUnionUF unionFind;
public Percolation(int n)
{
if(n<1){
throw new IllegalArgumentException ("grid must be larger than 0");
}
grid=new int[n][n];
size=n;
unionFind=new QuickFindUF(size*size);
//unionFind=new WeightedQuickUnionUF(size*size);
//initially set all to blocked
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
grid[i][j]=1;
}
}
}
public void open(int x, int y)
{
grid[x][y]=0;
//Check below to see if you can
//if you are not on the bottom row
if(y>0)
{
if(grid[x][y]==0 && grid[x][y-1]==0){unionFind.union(x+y*size,x+(y-1)*size);}
}
//check to see to the right (x->)
if(x<size-1){
if(grid[x][y]==0 && grid[x+1][y]==0){unionFind.union(x+y*size,x+1+y*size);}
}
//check if can union to the left
if(x>0)
{
if(grid[x][y]==0 && grid[x-1][y]==0){unionFind.union(x+y*size,x-1+y*size);}
}
//check for above
if(y<size-1){
if(grid[x][y]==0 && grid[x][y+1]==0){unionFind.union(x+y*size,x+(y+1)*size);}
}
}
public boolean isOpen(int x, int y)
{
if(x>=size || y>=size){return false;}
if(grid[x][y]==0){return true;}
return false;
}
public boolean isFull(int x, int y)
{
if(x>=size || y>=size){return false;}//if input is out of bounds
for(int i=0;i<size;i++){
if(unionFind.connected(x+y*size,i+((size-1)*size)))
return true;
}
return false;
}
public boolean percolates()
{
for(int i=0;i<size;i++){
for(int j=0;j<size;j++){
if(unionFind.connected(i,(size-1)*size+j)){
//System.out.println(i+" "+((size-1)*size+j));
return true;
}
}
}
return false;
}
}
现在,这本书善意地提供了和。所有与我交谈过的同学都在安排PercolationStats课程的时间时得到了预期的结果,我们被指示进行该课程,但我的结果非常好。这是课程
class PercolationStats{
private Percolation perc;
private double[] array;
private int expCount;
public PercolationStats(int gridSize, int numOfExperiments){
if(gridSize <= 0 || numOfExperiments <=0)
throw new IllegalArgumentException("gridSize and numOfExperiments needs to be more than 0");
array=new double[numOfExperiments];
expCount=numOfExperiments;
for(int i=0;i<numOfExperiments;i++){
perc=new Percolation(gridSize);
int count=0;
while(!perc.percolates()){
int x=StdRandom.uniform(gridSize),y=StdRandom.uniform(gridSize);
if(!perc.isOpen(x,y)){
perc.open(x,y);
count++;
}
}
array[i]=(double) count/(gridSize*gridSize);
}
}
public double mean(){
return StdStats.mean(array);
}
public double stddev(){
return StdStats.stddev(array);
}
public double confidenceLo(){
return mean() - ((1.96 * stddev()) / Math.sqrt(expCount));
}
public double confidenceHi(){
return mean()+((1.96 * stddev()) / Math.sqrt(expCount));
}
public static void main(String[] args){
Stopwatch timer=new Stopwatch();
PercolationStats percStats=new PercolationStats(200,100);
System.out.println("mean: "+ percStats.mean() +"stddev: "+percStats.stddev()+" confidence Lo: "+percStats.confidenceLo()+" confidence hi: "+percStats.confidenceHi());
System.out.println(timer.elapsedTime());
percStats=new PercolationStats(200,100);
System.out.println("mean: "+ percStats.mean() +"stddev: "+percStats.stddev()+" confidence Lo: "+percStats.confidenceLo()+" confidence hi: "+percStats.confidenceHi());
percStats=new PercolationStats(2,100000);
System.out.println("mean: "+ percStats.mean() +"stddev: "+percStats.stddev()+" confidence Lo: "+percStats.confidenceLo()+" confidence hi: "+percStats.confidenceHi());
}
}
当我在Percstats200100上用QuickFindUF运行它时,大约需要7秒,如果我在同样的200100上用WeightedQuickUnionUF运行它,大约需要50多秒??我很确定加权快速联合应该更快,这不仅仅是因为我的可怕的最坏情况随机数生成器不走运的问题。我运行了很多次,结果还是一样的,我在这里盯着代码看了很长一段时间,不明白为什么我的代码是如此错误
TLDR
正确的结果,错误的时间。由于某些原因,较慢的api速度较快,我不明白为什么。QuickFindUF比加权QuickUnionUf快。大约快7-8倍。我做错了什么?哈哈,我是个笨蛋。我在网上看到其他人正在使用虚拟陀螺,所以我添加了一个,现在它工作正常:P