How to resolve the algorithm Percolation/Bond percolation step by step in the C++ programming language

Published on 7 June 2024 03:52 AM

How to resolve the algorithm Percolation/Bond percolation step by step in the C++ programming language

Table of Contents

Problem Statement

Given an

M × N

{\displaystyle M\times N}

rectangular array of cells numbered

c e l l

[ 0.. M − 1 , 0.. N − 1 ]

{\displaystyle \mathrm {cell} [0..M-1,0..N-1]}

, assume

M

{\displaystyle M}

is horizontal and

N

{\displaystyle N}

is downwards. Each

c e l l

[ m , n ]

{\displaystyle \mathrm {cell} [m,n]}

is bounded by (horizontal) walls

h w a l l

[ m , n ]

{\displaystyle \mathrm {hwall} [m,n]}

and

h w a l l

[ m + 1 , n ]

{\displaystyle \mathrm {hwall} [m+1,n]}

; (vertical) walls

v w a l l

[ m , n ]

{\displaystyle \mathrm {vwall} [m,n]}

and

v w a l l

[ m , n + 1 ]

{\displaystyle \mathrm {vwall} [m,n+1]}

Assume that the probability of any wall being present is a constant

p

{\displaystyle p}

where Except for the outer horizontal walls at

m

0

{\displaystyle m=0}

and

m

M

{\displaystyle m=M}

which are always present. Simulate pouring a fluid onto the top surface (

n

0

{\displaystyle n=0}

) where the fluid will enter any empty cell it is adjacent to if there is no wall between where it currently is and the cell on the other side of the (missing) wall.
The fluid does not move beyond the horizontal constraints of the grid. The fluid may move “up” within the confines of the grid of cells. If the fluid reaches a bottom cell that has a missing bottom wall then the fluid can be said to 'drip' out the bottom at that point. Given

p

{\displaystyle p}

repeat the percolation

t

{\displaystyle t}

times to estimate the proportion of times that the fluid can percolate to the bottom for any given

p

{\displaystyle p}

. Show how the probability of percolating through the random grid changes with

p

{\displaystyle p}

going from

0.0

{\displaystyle 0.0}

to

1.0

{\displaystyle 1.0}

in

0.1

{\displaystyle 0.1}

increments and with the number of repetitions to estimate the fraction at any given

p

{\displaystyle p}

as

t

100

{\displaystyle t=100}

. Use an

M

10 , N

10

{\displaystyle M=10,N=10}

grid of cells for all cases. Optionally depict fluid successfully percolating through a grid graphically. Show all output on this page.

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Percolation/Bond percolation step by step in the C++ programming language

This C++ code simulates a grid of cells with walls and calculates the percolation threshold, which is the probability that there is a path from the top to the bottom of the grid.

Code Structure:

  • Classes and Enums:
    • Grid: Represents the grid of cells, where each cell can have walls, filled paths, or a combination of them.
    • cell_state: An enum representing the possible states of a cell (filled, right wall, bottom wall, right/bottom wall).

Grid Class:

  • Constructor:

    • Initializes the grid with dimensions m (width) and n (height) and a probability p of creating walls.
    • Uses a 2D array of type cell to represent the grid.
    • Iterates through the cells to create random walls based on the given probability.
  • ~Grid: Destructor to free the allocated memory.

  • percolate:

    • Checks if there is a path from the top to the bottom of the grid by iteratively filling cells from the top row.
    • Returns 1 if a path is found, 0 otherwise.
  • show:

    • Prints a visual representation of the grid, showing walls and filled cells.

Main Function:

  • Defines constants M (width), N (height), and C (number of grid simulations for each probability value).

  • Creates a Grid instance with M x N cells and a probability of 0.5.

  • Calls percolate() and show() to check and display the grid.

  • Runs a loop to calculate the percolation threshold for probabilities from 0 to M - 1 in increments of 1.

    • Creates C instances of Grid for each probability.
    • Counts the number of grids that percolate.
    • Calculates and prints the average percolation threshold for each probability.

Source code in the cpp programming language

#include <cstdlib>
#include <cstring>
#include <iostream>
#include <string>

using namespace std;

class Grid {
public:
    Grid(const double p, const int x, const int y) : m(x), n(y) {
        const int thresh = static_cast<int>(RAND_MAX * p);

        // Allocate two addition rows to avoid checking bounds.
        // Bottom row is also required by drippage
        start = new cell[m * (n + 2)];
        cells = start + m;
        for (auto i = 0; i < m; i++) start[i] = RBWALL;
        end = cells;
        for (auto i = 0; i < y; i++) {
            for (auto j = x; --j;)
                *end++ = (rand() < thresh ? BWALL : 0) | (rand() < thresh ? RWALL : 0);
            *end++ = RWALL | (rand() < thresh ? BWALL : 0);
        }
        memset(end, 0u, sizeof(cell) * m);
    }

    ~Grid() {
        delete[] start;
        cells = 0;
        start = 0;
        end = 0;
    }

    int percolate() const {
        auto i = 0;
        for (; i < m && !fill(cells + i); i++);
        return i < m;
    }

    void show() const {
        for (auto j = 0; j < m; j++)
            cout << ("+-");
        cout << '+' << endl;

        for (auto i = 0; i <= n; i++) {
            cout << (i == n ? ' ' : '|');
            for (auto j = 0; j < m; j++) {
                cout << ((cells[i * m + j] & FILL) ? "#" : " ");
                cout << ((cells[i * m + j] & RWALL) ? '|' : ' ');
            }
            cout << endl;

            if (i == n) return;

            for (auto j = 0; j < m; j++)
                cout << ((cells[i * m + j] & BWALL) ? "+-" : "+ ");
            cout << '+' << endl;
        }
    }

private:
    enum cell_state {
        FILL   = 1 << 0,
        RWALL  = 1 << 1,       // right wall
        BWALL  = 1 << 2,       // bottom wall
        RBWALL = RWALL | BWALL // right/bottom wall
    };

    typedef unsigned int cell;

    bool fill(cell* p) const {
        if ((*p & FILL)) return false;
        *p |= FILL;
        if (p >= end) return true; // success: reached bottom row

        return (!(p[0] & BWALL) && fill(p + m)) || (!(p[0] & RWALL) && fill(p + 1))
                ||(!(p[-1] & RWALL) && fill(p - 1)) || (!(p[-m] & BWALL) && fill(p - m));
    }

    cell* cells;
    cell* start;
    cell* end;
    const int m;
    const int n;
};

int main() {
    const auto M = 10, N = 10;
    const Grid grid(.5, M, N);
    grid.percolate();
    grid.show();

    const auto C = 10000;
    cout << endl << "running " << M << "x" << N << " grids " << C << " times for each p:" << endl;
    for (auto p = 1; p < M; p++) {
        auto cnt = 0, i = 0;
        for (; i < C; i++)
            cnt += Grid(p / static_cast<double>(M), M, N).percolate();
        cout << "p = " << p / static_cast<double>(M) << ": " << static_cast<double>(cnt) / i << endl;
    }

    return EXIT_SUCCESS;
}


  

You may also check:How to resolve the algorithm Fivenum step by step in the Delphi programming language
You may also check:How to resolve the algorithm Variadic function step by step in the Maxima programming language
You may also check:How to resolve the algorithm Fibonacci n-step number sequences step by step in the VBA programming language
You may also check:How to resolve the algorithm Greatest common divisor step by step in the Seed7 programming language
You may also check:How to resolve the algorithm Sorting algorithms/Patience sort step by step in the AppleScript programming language