2016 Update
This commit is contained in:
parent
948b86eafa
commit
dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions
|
|
@ -1,5 +1,5 @@
|
|||
{{Percolation Simulation}}
|
||||
Given an <math>M \times N</math> rectangular array of cells numbered <math>\mathrm{cell}[0..M-1, 0..N-1]</math>assume <math>M</math> is horizontal and <math>N</math> is downwards. Each <math>\mathrm{cell}[m, n]</math> is bounded by (horizontal) walls <math>\mathrm{hwall}[m, n]</math> and <math>\mathrm{hwall}[m+1, n]</math>; (vertical) walls <math>\mathrm{vwall}[m, n]</math> and <math>\mathrm{vwall}[m, n+1]</math>
|
||||
Given an <math>M \times N</math> rectangular array of cells numbered <math>\mathrm{cell}[0..M-1, 0..N-1]</math>, assume <math>M</math> is horizontal and <math>N</math> is downwards. Each <math>\mathrm{cell}[m, n]</math> is bounded by (horizontal) walls <math>\mathrm{hwall}[m, n]</math> and <math>\mathrm{hwall}[m+1, n]</math>; (vertical) walls <math>\mathrm{vwall}[m, n]</math> and <math>\mathrm{vwall}[m, n+1]</math>
|
||||
|
||||
Assume that the probability of any wall being present is a constant <math>p</math> where
|
||||
: <math>0.0 \le p \le 1.0</math>
|
||||
|
|
@ -21,3 +21,4 @@ Use an <math>M=10, N=10</math> grid of cells for all cases.
|
|||
Optionally depict fluid successfully percolating through a grid graphically.
|
||||
|
||||
Show all output on this page.
|
||||
<br><br>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,103 @@
|
|||
#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;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue