Programming Assignment 1: Percolation

Percolation

实现Percolation模型。
用蒙特卡罗模拟估计渗滤阈值的值。

关于backwash问题:有了一个虚拟底层位置,如果网格已经渗透了。这时判断其中一个位置(与底部相连,并且底部是打开的,与虚拟底层位置相连)是否满(即与虚拟顶层位置是相连的),那么不管这个位置是不是真的满,结果总会是满的。因为网格已经渗透了,那么虚拟顶层位置与虚拟底层位置总是相连的,而这个位置与虚拟顶层位置是相连的,这时候再判断它是不是满(与虚拟顶层位置相连),结果当然总是为真。
回流问题

这里提供了两种方法解决backwash,即回流问题

Percolation with top virtual site

即带有虚拟位置的网格。
同时需要建立两个WeightedQuickUnionUF 对象,一个同时有虚拟顶层位置和虚拟底层位置,这样判断是否渗透很容易。另一个只有虚拟顶层位置,这就避免了回流问题,用来判断是否满。
由于建立了两个WeightedQuickUnionUF 对象,所以 内存使用没有完全过关,得到了97分。

Percolation.java

import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.WeightedQuickUnionUF;

/**
 * The {@code Percolation} class provides methods for calculating the Percolation. 
 * <p>
 * Creates two WeightedQuickUnionUF objects to solve the backwash problem.
 * 
 * @author zhangyu
 * @date 2017.2.27
 */
public class Percolation 
{
   
   
    private int size; // size of created grid
    private int[] status; // record the status of each site
    private WeightedQuickUnionUF grid;
    private WeightedQuickUnionUF gridNoVBottom;

    /**
     * Initializes two WeightedQuickUnionUF object. One has two 
     * virtual sites, and the other one has only one top site. 
     * Set state of each site blocked.
     * 
     * @param  n size of created grid
     * @throws IllegalArgumentException if n < 1
     */
    public Percolation(int n)
    {
        if (n < 1) throw new IllegalArgumentException("Grid size out of range");
        size = n;
        status = new int[n * n];
        for (int i = 0; i < n * n; i++) status[i] = 0;
        grid = new WeightedQuickUnionUF(n*n + 2);
        gridNoVBottom = new WeightedQuickUnionUF(n*n + 1);
    }

    /**
     * open site (row, col) if it is not open already.
     * 
     * @param row abscissa of the grid 
     * @param col ordinate of the grid
     */
    public void open(int row, int col)
    {
        int idx = xyTo1D(row, col);

        validate(row, col);
        status[idx] = 1;
        if (1 == row) // connect to the virtual site
        {
            grid.union(idx, size * size);
            gridNoVBottom.union(idx, size * size);
        }
        if (size == row) grid.union(idx, size*size + 1);

        int[] xDiff = {-1, 1, 0, 0};
        int[] yDiff = {
  
  0, 0, -1, 1};

        for (int i = 0; i < 4; i++)
        {
            int adjX = row + xDiff[i];
            int adjY = col + yDiff[i];

            if (adjX > 0 && adjX <= size)
            {
                if (adjY > 0 && adjY <= size)
                {
                    int adjPosIdx = xyTo1D(adjX, adjY);
                    if (1 == status[adjPosIdx])
                    {
                        grid.union(idx, adjPosIdx);
                        gridNoVBottom.union(idx, adjPosIdx);
                    }
                }
            }
        }
    }

    /**
     * Determine whether the site (row, col) is open.
     * 
     * @param row abscissa of the grid 
     * @param col ordinate of the grid
     * @return true if the site (row, col) is open;
     *         false otherwise
     */
    public boolean isOpen(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值