Data commit

This commit is contained in:
Ingy döt Net 2023-07-01 11:58:00 -04:00
parent 7387c8f97b
commit cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions

View file

@ -0,0 +1,3 @@
---
from: http://rosettacode.org/wiki/Percolation/Mean_cluster_density
note: Percolation Simulations

View file

@ -0,0 +1,23 @@
{{Percolation Simulation}}
Let <math>c</math> be a 2D boolean square matrix of <math>n \times n</math> values of either <tt>1</tt> or <tt>0</tt> where the
probability of any value being <tt>1</tt> is <math>p</math>, (and of <tt>0</tt> is therefore <math>1-p</math>).
We define a ''cluster'' of <tt>1</tt>'s as being a group of <tt>1</tt>'s connected vertically or
horizontally (i.e., using the [[wp:Von Neumann neighborhood|Von Neumann neighborhood rule]]) and bounded by either <math>0</math> or by the limits of the matrix.
Let the number of such clusters in such a randomly constructed matrix be <math>C_n</math>.
Percolation theory states that <math>K(p)</math> (the mean cluster density) will satisfy <math>K(p) = C_n / n^2</math> as <math>n</math> tends to infinity. For <math>p = 0.5</math>, <math>K(p)</math> is found numerically to approximate <math>0.065770</math>...
;Task
Show the effect of varying <math>n</math> on the accuracy of simulated <math>K(p)</math> for <math>p = 0.5</math> and
for values of <math>n</math> up to at least <math>1000</math>.
Any calculation of <math>C_n</math> for finite <math>n</math> is subject to randomness, so an approximation should be
computed as the average of <math>t</math> runs, where <math>t</math> &ge; <math>5</math>.
For extra credit, graphically show clusters in a <math>15\times 15</math>, <math>p=0.5</math> grid.
Show your output here.
;See also
* [http://mathworld.wolfram.com/s-Cluster.html s-Cluster] on Wolfram mathworld.

View file

@ -0,0 +1,57 @@
UInt32 seed = 0
F nonrandom()
:seed = 1664525 * :seed + 1013904223
R (:seed >> 16) / Float(FF'FF)
V nn = 15
V tt = 5
V pp = 0.5
V NotClustered = 1
V Cell2Char = #abcdefghijklmnopqrstuvwxyz
V NRange = [4, 64, 256, 1024, 4096]
F newGrid(n, p)
R (0 .< n).map(i -> (0 .< @n).map(i -> Int(nonrandom() < @@p)))
F walkMaze(&grid, m, n, idx) -> N
grid[n][m] = idx
I n < grid.len - 1 & grid[n + 1][m] == NotClustered
walkMaze(&grid, m, n + 1, idx)
I m < grid[0].len - 1 & grid[n][m + 1] == NotClustered
walkMaze(&grid, m + 1, n, idx)
I m > 0 & grid[n][m - 1] == NotClustered
walkMaze(&grid, m - 1, n, idx)
I n > 0 & grid[n - 1][m] == NotClustered
walkMaze(&grid, m, n - 1, idx)
F clusterCount(&grid)
V walkIndex = 1
L(n) 0 .< grid.len
L(m) 0 .< grid[0].len
I grid[n][m] == NotClustered
walkIndex++
walkMaze(&grid, m, n, walkIndex)
R walkIndex - 1
F clusterDensity(n, p)
V grid = newGrid(n, p)
R clusterCount(&grid) / Float(n * n)
F print_grid(grid)
L(row) grid
print(L.index % 10, end' ) )
L(cell) row
print( Cell2Char[cell], end' )
print()
V grid = newGrid(nn, 0.5)
print(Found clusterCount(&grid) clusters in this nn by nn" grid\n")
print_grid(grid)
print()
L(n) NRange
V sum = 0.0
L 0 .< tt
sum += clusterDensity(n, pp)
V sim = sum / tt
print(t = #. p = #.2 n = #4 sim = #.5.format(tt, pp, n, sim))

View file

@ -0,0 +1,105 @@
#include <iostream>
#include <random>
#include <string>
#include <vector>
#include <iomanip>
std::random_device random;
std::mt19937 generator(random());
std::uniform_real_distribution<double> distribution(0.0F, 1.0F);
class Grid {
public:
Grid(const int32_t size, const double probability) {
create_grid(size, probability);
count_clusters();
}
int32_t cluster_count() const {
return clusters;
}
double cluster_density() const {
return (double) clusters / ( grid.size() * grid.size() );
}
void display() const {
for ( uint64_t row = 0; row < grid.size(); ++row ) {
for ( uint64_t col = 0; col < grid.size(); ++col ) {
uint64_t value = grid[row][col];
char ch = ( value < GRID_CHARACTERS.length() ) ? GRID_CHARACTERS[value] : '?';
std::cout << " " << ch;
}
std::cout << std::endl;
}
}
private:
void count_clusters() {
clusters = 0;
for ( uint64_t row = 0; row < grid.size(); ++row ) {
for ( uint64_t col = 0; col < grid.size(); ++col ) {
if ( grid[row][col] == CLUSTERED ) {
clusters += 1;
identify_cluster(row, col, clusters);
}
}
}
}
void identify_cluster(const uint64_t row, const uint64_t col, const uint64_t count) {
grid[row][col] = count;
if ( row < grid.size() - 1 && grid[row + 1][col] == CLUSTERED ) {
identify_cluster(row + 1, col, count);
}
if ( col < grid.size() - 1 && grid[row][col + 1] == CLUSTERED ) {
identify_cluster(row, col + 1, count);
}
if ( col > 0 && grid[row][col - 1] == CLUSTERED ) {
identify_cluster(row, col - 1, count);
}
if ( row > 0 && grid[row - 1][col] == CLUSTERED ) {
identify_cluster(row - 1, col, count);
}
}
void create_grid(int32_t grid_size, double probability) {
grid.assign(grid_size, std::vector<int32_t>(grid_size, 0));
for ( int32_t row = 0; row < grid_size; ++row ) {
for ( int32_t col = 0; col < grid_size; ++col ) {
if ( distribution(generator) < probability ) {
grid[row][col] = CLUSTERED;
}
}
}
}
int32_t clusters;
std::vector<std::vector<int32_t>> grid;
inline static const int CLUSTERED = -1;
inline static const std::string GRID_CHARACTERS = ".ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
};
int main() {
const int32_t size = 15;
const double probability = 0.5;
const int32_t test_count = 5;
Grid grid(size, probability);
std::cout << "This " << size << " by " << size << " grid contains "
<< grid.cluster_count() << " clusters:" << std::endl;
grid.display();
std::cout << "\n p = 0.5, iterations = " << test_count << std::endl;
std::vector<int32_t> grid_sizes = { 10, 100, 1'000, 10'000 };
for ( int32_t grid_size : grid_sizes ) {
double sumDensity = 0.0;
for ( int32_t test = 0; test < test_count; test++ ) {
Grid grid(grid_size, probability);
sumDensity += grid.cluster_density();
}
double result = sumDensity / test_count;
std::cout << " n = " << std::setw(5) << grid_size
<< ", simulations K = " << std::fixed << result << std::endl;
}
}

View file

@ -0,0 +1,77 @@
#include <stdio.h>
#include <stdlib.h>
int *map, w, ww;
void make_map(double p)
{
int i, thresh = RAND_MAX * p;
i = ww = w * w;
map = realloc(map, i * sizeof(int));
while (i--) map[i] = -(rand() < thresh);
}
char alpha[] = "+.ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
#define ALEN ((int)(sizeof(alpha) - 3))
void show_cluster(void)
{
int i, j, *s = map;
for (i = 0; i < w; i++) {
for (j = 0; j < w; j++, s++)
printf(" %c", *s < ALEN ? alpha[1 + *s] : '?');
putchar('\n');
}
}
void recur(int x, int v) {
if (x >= 0 && x < ww && map[x] == -1) {
map[x] = v;
recur(x - w, v);
recur(x - 1, v);
recur(x + 1, v);
recur(x + w, v);
}
}
int count_clusters(void)
{
int i, cls;
for (cls = i = 0; i < ww; i++) {
if (-1 != map[i]) continue;
recur(i, ++cls);
}
return cls;
}
double tests(int n, double p)
{
int i;
double k;
for (k = i = 0; i < n; i++) {
make_map(p);
k += (double)count_clusters() / ww;
}
return k / n;
}
int main(void)
{
w = 15;
make_map(.5);
printf("width=15, p=0.5, %d clusters:\n", count_clusters());
show_cluster();
printf("\np=0.5, iter=5:\n");
for (w = 1<<2; w <= 1<<14; w<<=2)
printf("%5d %9.6f\n", w, tests(5, .5));
free(map);
return 0;
}

View file

@ -0,0 +1,90 @@
import std.stdio, std.algorithm, std.random, std.math, std.array,
std.range, std.ascii;
alias Cell = ubyte;
alias Grid = Cell[][];
enum Cell notClustered = 1; // Filled cell, but not in a cluster.
Grid initialize(Grid grid, in double prob, ref Xorshift rng) nothrow {
foreach (row; grid)
foreach (ref cell; row)
cell = Cell(rng.uniform01 < prob);
return grid;
}
void show(in Grid grid) {
immutable static cell2char = " #" ~ letters;
writeln('+', "-".replicate(grid.length), '+');
foreach (row; grid) {
write('|');
row.map!(c => c < cell2char.length ? cell2char[c] : '@').write;
writeln('|');
}
writeln('+', "-".replicate(grid.length), '+');
}
size_t countClusters(bool justCount=false)(Grid grid)
pure nothrow @safe @nogc {
immutable side = grid.length;
static if (justCount)
enum Cell clusterID = 2;
else
Cell clusterID = 1;
void walk(in size_t r, in size_t c) nothrow @safe @nogc {
grid[r][c] = clusterID; // Fill grid.
if (r < side - 1 && grid[r + 1][c] == notClustered) // Down.
walk(r + 1, c);
if (c < side - 1 && grid[r][c + 1] == notClustered) // Right.
walk(r, c + 1);
if (c > 0 && grid[r][c - 1] == notClustered) // Left.
walk(r, c - 1);
if (r > 0 && grid[r - 1][c] == notClustered) // Up.
walk(r - 1, c);
}
size_t nClusters = 0;
foreach (immutable r; 0 .. side)
foreach (immutable c; 0 .. side)
if (grid[r][c] == notClustered) {
static if (!justCount)
clusterID++;
nClusters++;
walk(r, c);
}
return nClusters;
}
double clusterDensity(Grid grid, in double prob, ref Xorshift rng) {
return grid.initialize(prob, rng).countClusters!true /
double(grid.length ^^ 2);
}
void showDemo(in size_t side, in double prob, ref Xorshift rng) {
auto grid = new Grid(side, side);
grid.initialize(prob, rng);
writefln("Found %d clusters in this %d by %d grid:\n",
grid.countClusters, side, side);
grid.show;
}
void main() {
immutable prob = 0.5;
immutable nIters = 5;
auto rng = Xorshift(unpredictableSeed);
showDemo(15, prob, rng);
writeln;
foreach (immutable i; iota(4, 14, 2)) {
immutable side = 2 ^^ i;
auto grid = new Grid(side, side);
immutable density = nIters
.iota
.map!(_ => grid.clusterDensity(prob, rng))
.sum / nIters;
writefln("n_iters=%3d, p=%4.2f, n=%5d, sim=%7.8f",
nIters, prob, side, density);
}
}

View file

@ -0,0 +1,37 @@
(define-constant BLACK (rgb 0 0 0.6))
(define-constant WHITE -1)
;; sets pixels to clusterize to WHITE
;; returns bit-map vector
(define (init-C n p )
(plot-size n n)
(define C (pixels->int32-vector )) ;; get canvas bit-map
(pixels-map (lambda (x y) (if (< (random) p) WHITE BLACK )) C)
C )
;; random color for new cluster
(define (new-color)
(hsv->rgb (random) 0.9 0.9))
;; make-region predicate
(define (in-cluster C x y)
(= (pixel-ref C x y) WHITE))
;; paint all adjacents to (x0,y0) with new color
(define (make-cluster C x0 y0)
(pixel-set! C x0 y0 (new-color))
(make-region in-cluster C x0 y0))
;; task
(define (make-clusters (n 400) (p 0.5))
(define Cn 0)
(define C null)
(for ((t 5)) ;; 5 iterations
(plot-clear)
(set! C (init-C n p))
(for* ((x0 n) (y0 n))
#:when (= (pixel-ref C x0 y0) WHITE)
(set! Cn (1+ Cn))
(make-cluster C x0 y0)))
(writeln 'n n 'Cn Cn 'density (// Cn (* n n) 5) )
(vector->pixels C)) ;; to screen

View file

@ -0,0 +1,42 @@
USING: combinators formatting generalizations kernel math
math.matrices random sequences ;
IN: rosetta-code.mean-cluster-density
CONSTANT: p 0.5
CONSTANT: iterations 5
: rand-bit-matrix ( n probability -- matrix )
dupd [ random-unit > 1 0 ? ] curry make-matrix ;
: flood-fill ( x y matrix -- )
3dup ?nth ?nth 1 = [
[ [ -1 ] 3dip nth set-nth ] [
{
[ [ 1 + ] 2dip ]
[ [ 1 - ] 2dip ]
[ [ 1 + ] dip ]
[ [ 1 - ] dip ]
} [ flood-fill ] map-compose 3cleave
] 3bi
] [ 3drop ] if ;
: count-clusters ( matrix -- Cn )
0 swap dup dim matrix-coordinates flip concat [
first2 rot 3dup ?nth ?nth 1 = [ flood-fill 1 + ]
[ 3drop ] if
] with each ;
: mean-cluster-density ( matrix -- mcd )
[ count-clusters ] [ dim first sq / ] bi ;
: simulate ( n -- avg-mcd )
iterations swap [ p rand-bit-matrix mean-cluster-density ]
curry replicate sum iterations / ;
: main ( -- )
{ 4 64 256 1024 4096 } [
[ iterations p ] dip dup simulate
"iterations = %d p = %.1f n = %4d sim = %.5f\n" printf
] each ;
MAIN: main

View file

@ -0,0 +1,98 @@
package main
import (
"fmt"
"math/rand"
"time"
)
var (
n_range = []int{4, 64, 256, 1024, 4096}
M = 15
N = 15
)
const (
p = .5
t = 5
NOT_CLUSTERED = 1
cell2char = " #abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
)
func newgrid(n int, p float64) [][]int {
g := make([][]int, n)
for y := range g {
gy := make([]int, n)
for x := range gy {
if rand.Float64() < p {
gy[x] = 1
}
}
g[y] = gy
}
return g
}
func pgrid(cell [][]int) {
for n := 0; n < N; n++ {
fmt.Print(n%10, ") ")
for m := 0; m < M; m++ {
fmt.Printf(" %c", cell2char[cell[n][m]])
}
fmt.Println()
}
}
func cluster_density(n int, p float64) float64 {
cc := clustercount(newgrid(n, p))
return float64(cc) / float64(n) / float64(n)
}
func clustercount(cell [][]int) int {
walk_index := 1
for n := 0; n < N; n++ {
for m := 0; m < M; m++ {
if cell[n][m] == NOT_CLUSTERED {
walk_index++
walk_maze(m, n, cell, walk_index)
}
}
}
return walk_index - 1
}
func walk_maze(m, n int, cell [][]int, indx int) {
cell[n][m] = indx
if n < N-1 && cell[n+1][m] == NOT_CLUSTERED {
walk_maze(m, n+1, cell, indx)
}
if m < M-1 && cell[n][m+1] == NOT_CLUSTERED {
walk_maze(m+1, n, cell, indx)
}
if m > 0 && cell[n][m-1] == NOT_CLUSTERED {
walk_maze(m-1, n, cell, indx)
}
if n > 0 && cell[n-1][m] == NOT_CLUSTERED {
walk_maze(m, n-1, cell, indx)
}
}
func main() {
rand.Seed(time.Now().Unix())
cell := newgrid(N, .5)
fmt.Printf("Found %d clusters in this %d by %d grid\n\n",
clustercount(cell), N, N)
pgrid(cell)
fmt.Println()
for _, n := range n_range {
M = n
N = n
sum := 0.
for i := 0; i < t; i++ {
sum += cluster_density(n, p)
}
sim := sum / float64(t)
fmt.Printf("t=%3d p=%4.2f n=%5d sim=%7.5f\n", t, p, n, sim)
}
}

View file

@ -0,0 +1,63 @@
{-# language FlexibleContexts #-}
import Data.List
import Data.Maybe
import System.Random
import Control.Monad.State
import Text.Printf
import Data.Set (Set)
import qualified Data.Set as S
type Matrix = [[Bool]]
type Cell = (Int, Int)
type Cluster = Set (Int, Int)
clusters :: Matrix -> [Cluster]
clusters m = unfoldr findCuster cells
where
cells = S.fromList [ (i,j) | (r, i) <- zip m [0..]
, (x, j) <- zip r [0..], x]
findCuster s = do
(p, ps) <- S.minView s
return $ runState (expand p) ps
expand p = do
ns <- state $ extract (neigbours p)
xs <- mapM expand $ S.elems ns
return $ S.insert p $ mconcat xs
extract s1 s2 = (s2 `S.intersection` s1, s2 S.\\ s1)
neigbours (i,j) = S.fromList [(i-1,j),(i+1,j),(i,j-1),(i,j+1)]
n = length m
showClusters :: Matrix -> String
showClusters m = unlines [ unwords [ mark (i,j)
| j <- [0..n-1] ]
| i <- [0..n-1] ]
where
cls = clusters m
n = length m
mark c = maybe "." snd $ find (S.member c . fst) $ zip cls syms
syms = sequence [['a'..'z'] ++ ['A'..'Z']]
------------------------------------------------------------
randomMatrices :: Int -> StdGen -> [Matrix]
randomMatrices n = clipBy n . clipBy n . randoms
where
clipBy n = unfoldr (Just . splitAt n)
randomMatrix n = head . randomMatrices n
tests :: Int -> StdGen -> [Int]
tests n = map (length . clusters) . randomMatrices n
task :: Int -> StdGen -> (Int, Double)
task n g = (n, result)
where
result = mean $ take 10 $ map density $ tests n g
density c = fromIntegral c / fromIntegral n**2
mean lst = sum lst / genericLength lst
main = newStdGen >>= mapM_ (uncurry (printf "%d\t%.5f\n")) . res
where
res = mapM task [10,50,100,500]

View file

@ -0,0 +1 @@
congeal=: |.@|:@((*@[*>.)/\.)^:4^:_

View file

@ -0,0 +1,12 @@
6 trials 3
0.1111111 0.1111111 0.2222222 0.1111111 0.1111111 0.3333333
6 trials 10
0.16 0.12 0.09 0.1 0.1 0.03
6 trials 30
0.05666667 0.1033333 0.08222222 0.07444444 0.08333333 0.07666667
6 trials 100
0.069 0.0678 0.0666 0.0677 0.0653 0.0739
6 trials 300
0.06563333 0.06663333 0.06713333 0.06727778 0.06658889 0.06664444
6 trials 1000
0.066079 0.066492 0.065847 0.065943 0.066318 0.065998

View file

@ -0,0 +1,13 @@
mean=: +/%#
mean 8 trials 3
0.1805556
mean 8 trials 10
0.0875
mean 8 trials 30
0.07486111
mean 8 trials 100
0.0690625
mean 8 trials 300
0.06749861
mean 8 trials 1000
0.06616738

View file

@ -0,0 +1 @@
thru=: <./ + i.@(+*)@-~

View file

@ -0,0 +1,16 @@
(idclust 0.5 > 0 ?@$~ 15 15) {'.', 'A' thru&.(a.&i.) 'Z'
A.......B..C...
AAAA...D..E.F..
A..A.G.D.D.FFF.
AA..H..DDD.FF.I
AAA...J...FFF..
..AAAA.A.K...AA
LL.A...A..A.AAA
.L.A..AAA.AAAAA
..AA.AAA.AAA.A.
AA.AAAAAA....A.
A.AAAA.AAAA.AA.
AAA...AAA.AAAAA
..AA..A.A...AAA
.M.A.AA.AA..AA.
.MM..A.N..O..A.

View file

@ -0,0 +1,11 @@
congeal=: |.@|:@((*@[*>.)/\.)^:4^:_
idclust=: $ $ [: (~. i.])&.(0&,)@,@congeal ] * 1 + i.@$
K=: (%&#~ }.@~.)&,
experiment=: K@ idclust@: > 0 ?@$~ ,~
trials=: 0.5&experiment"0@#
mean=:+/ % #
thru=: <./ + i.@(+*)@-~

View file

@ -0,0 +1,49 @@
M=: (* 1+i.@$)?15 15$2
M
0 2 3 4 0 6 0 8 0 10 11 12 0 0 15
0 0 18 19 20 0 22 0 0 0 0 0 28 29 0
31 32 0 34 35 36 37 38 0 0 0 42 0 0 45
0 0 48 49 0 51 0 0 54 55 0 57 58 0 0
61 62 63 64 0 0 67 0 69 0 71 72 0 74 0
0 0 78 79 0 0 82 0 84 85 86 87 88 0 0
0 92 0 94 0 0 0 0 99 100 101 0 103 0 105
106 107 108 0 0 111 0 0 114 115 116 0 0 0 0
0 0 0 124 125 126 127 0 0 0 0 0 133 134 135
0 0 138 0 0 141 0 143 144 145 0 0 0 0 150
0 152 153 154 0 0 0 158 0 160 0 162 163 164 165
0 167 168 169 170 0 172 173 0 175 176 177 0 0 180
181 182 183 0 0 186 0 188 189 190 191 192 0 194 195
196 197 198 0 200 201 202 0 0 205 0 207 0 0 0
211 212 213 0 0 0 217 218 0 220 221 0 0 224 0
congeal M
0 94 94 94 0 6 0 8 0 12 12 12 0 0 15
0 0 94 94 94 0 94 0 0 0 0 0 29 29 0
32 32 0 94 94 94 94 94 0 0 0 116 0 0 45
0 0 94 94 0 94 0 0 116 116 0 116 116 0 0
94 94 94 94 0 0 82 0 116 0 116 116 0 74 0
0 0 94 94 0 0 82 0 116 116 116 116 116 0 0
0 108 0 94 0 0 0 0 116 116 116 0 116 0 105
108 108 108 0 0 141 0 0 116 116 116 0 0 0 0
0 0 0 141 141 141 141 0 0 0 0 0 221 221 221
0 0 213 0 0 141 0 221 221 221 0 0 0 0 221
0 213 213 213 0 0 0 221 0 221 0 221 221 221 221
0 213 213 213 213 0 221 221 0 221 221 221 0 0 221
213 213 213 0 0 218 0 221 221 221 221 221 0 221 221
213 213 213 0 218 218 218 0 0 221 0 221 0 0 0
213 213 213 0 0 0 218 218 0 221 221 0 0 224 0
(~.@, i. ])congeal M
0 1 1 1 0 2 0 3 0 4 4 4 0 0 5
0 0 1 1 1 0 1 0 0 0 0 0 6 6 0
7 7 0 1 1 1 1 1 0 0 0 8 0 0 9
0 0 1 1 0 1 0 0 8 8 0 8 8 0 0
1 1 1 1 0 0 10 0 8 0 8 8 0 11 0
0 0 1 1 0 0 10 0 8 8 8 8 8 0 0
0 12 0 1 0 0 0 0 8 8 8 0 8 0 13
12 12 12 0 0 14 0 0 8 8 8 0 0 0 0
0 0 0 14 14 14 14 0 0 0 0 0 15 15 15
0 0 16 0 0 14 0 15 15 15 0 0 0 0 15
0 16 16 16 0 0 0 15 0 15 0 15 15 15 15
0 16 16 16 16 0 15 15 0 15 15 15 0 0 15
16 16 16 0 0 17 0 15 15 15 15 15 0 15 15
16 16 16 0 17 17 17 0 0 15 0 15 0 0 0
16 16 16 0 0 0 17 17 0 15 15 0 0 18 0

View file

@ -0,0 +1,22 @@
M=:0.4>?6 6$0
M
1 0 0 0 0 0
0 0 0 1 0 0
0 0 0 1 0 0
1 1 0 0 0 0
0 0 0 1 0 1
1 1 0 1 1 0
M*p:i.$M
2 0 0 0 0 0
0 0 0 29 0 0
0 0 0 53 0 0
67 71 0 0 0 0
0 0 0 107 0 113
127 131 0 139 149 0
congeal M*p:i.$M
2 0 0 0 0 0
0 0 0 53 0 0
0 0 0 53 0 0
71 71 0 0 0 0
0 0 0 149 0 113
131 131 0 149 149 0

View file

@ -0,0 +1 @@
idclust=: $ $ [: (~. i.])&.(0&,)@,@congeal ] * 1 + i.@$

View file

@ -0,0 +1,14 @@
idclust M
1 0 0 0 0 0
0 0 0 2 0 0
0 0 0 2 0 0
3 3 0 0 0 0
0 0 0 4 0 5
6 6 0 4 4 0
(idclust M) {'.ABCDEFG'
A.....
...B..
...B..
CC....
...D.E
FF.DD.

View file

@ -0,0 +1 @@
K=: (%&#~ }.@~.)&,

View file

@ -0,0 +1,2 @@
K idclust M
0.1666667

View file

@ -0,0 +1 @@
experiment=: K@ idclust@: > 0 ?@$~ ,~

View file

@ -0,0 +1,4 @@
0.4 experiment 6
0.1666667
0.4 experiment 6
0.1944444

View file

@ -0,0 +1 @@
trials=: 0.5&experiment"0@#

View file

@ -0,0 +1,103 @@
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
public final class PercolationMeanCluster {
public static void main(String[] aArgs) {
final int size = 15;
final double probability = 0.5;
final int testCount = 5;
Grid grid = new Grid(size, probability);
System.out.println("This " + size + " by " + size + " grid contains " + grid.clusterCount() + " clusters:");
grid.display();
System.out.println(System.lineSeparator() + " p = 0.5, iterations = " + testCount);
List<Integer> gridSizes = List.of( 10, 100, 1_000, 10_000 );
for ( int gridSize : gridSizes ) {
double sumDensity = 0.0;
for ( int test = 0; test < testCount; test++ ) {
grid = new Grid(gridSize, probability);
sumDensity += grid.clusterDensity();
}
double result = sumDensity / testCount;
System.out.println(String.format("%s%5d%s%.6f", " n = ", gridSize, ", simulation K = ", result));
}
}
}
final class Grid {
public Grid(int aSize, double aProbability) {
createGrid(aSize, aProbability);
countClusters();
}
public int clusterCount() {
return clusterCount;
}
public double clusterDensity() {
return (double) clusterCount / ( grid.length * grid.length );
}
public void display() {
for ( int row = 0; row < grid.length; row++ ) {
for ( int col = 0; col < grid.length; col++ ) {
int value = grid[row][col];
char ch = ( value < GRID_CHARACTERS.length() ) ? GRID_CHARACTERS.charAt(value) : '?';
System.out.print(" " + ch);
}
System.out.println();
}
}
private void countClusters() {
clusterCount = 0;
for ( int row = 0; row < grid.length; row++ ) {
for ( int col = 0; col < grid.length; col++ ) {
if ( grid[row][col] == CLUSTERED ) {
clusterCount += 1;
identifyCluster(row, col, clusterCount);
}
}
}
}
private void identifyCluster(int aRow, int aCol, int aCount) {
grid[aRow][aCol] = aCount;
if ( aRow < grid.length - 1 && grid[aRow + 1][aCol] == CLUSTERED ) {
identifyCluster(aRow + 1, aCol, aCount);
}
if ( aCol < grid[0].length - 1 && grid[aRow][aCol + 1] == CLUSTERED ) {
identifyCluster(aRow, aCol + 1, aCount);
}
if ( aCol > 0 && grid[aRow][aCol - 1] == CLUSTERED ) {
identifyCluster(aRow, aCol - 1, aCount);
}
if ( aRow > 0 && grid[aRow - 1][aCol] == CLUSTERED ) {
identifyCluster(aRow - 1, aCol, aCount);
}
}
private void createGrid(int aGridSize, double aProbability) {
grid = new int[aGridSize][aGridSize];
for ( int row = 0; row < aGridSize; row++ ) {
for ( int col = 0; col < aGridSize; col++ ) {
if ( random.nextDouble(1.0) < aProbability ) {
grid[row][col] = CLUSTERED;
}
}
}
}
private int[][] grid;
private int clusterCount;
private static ThreadLocalRandom random = ThreadLocalRandom.current();
private static final int CLUSTERED = -1;
private static final String GRID_CHARACTERS = ".ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
}

View file

@ -0,0 +1,51 @@
using Printf, Distributions
newgrid(p::Float64, r::Int, c::Int=r) = rand(Bernoulli(p), r, c)
function walkmaze!(grid::Matrix{Int}, r::Int, c::Int, indx::Int)
NOT_CLUSTERED = 1 # const
N, M = size(grid)
dirs = [[1, 0], [-1, 0], [0, 1], [0, -1]]
# fill cell
grid[r, c] = indx
# check for each direction
for d in dirs
rr, cc = (r, c) .+ d
if checkbounds(Bool, grid, rr, cc) && grid[rr, cc] == NOT_CLUSTERED
walkmaze!(grid, rr, cc, indx)
end
end
end
function clustercount!(grid::Matrix{Int})
NOT_CLUSTERED = 1 # const
walkind = 1
for r in 1:size(grid, 1), c in 1:size(grid, 2)
if grid[r, c] == NOT_CLUSTERED
walkind += 1
walkmaze!(grid, r, c, walkind)
end
end
return walkind - 1
end
clusterdensity(p::Float64, n::Int) = clustercount!(newgrid(p, n)) / n ^ 2
function printgrid(G::Matrix{Int})
LETTERS = vcat(' ', '#', 'A':'Z', 'a':'z')
for r in 1:size(G, 1)
println(r % 10, ") ", join(LETTERS[G[r, :] .+ 1], ' '))
end
end
G = newgrid(0.5, 15)
@printf("Found %i clusters in this %i×%i grid\n\n", clustercount!(G), size(G, 1), size(G, 2))
printgrid(G)
println()
const nrange = 2 .^ (4:2:12)
const p = 0.5
const nrep = 5
for n in nrange
sim = mean(clusterdensity(p, n) for _ in 1:nrep)
@printf("nrep = %2i p = %.2f dim = %-13s sim = %.5f\n", nrep, p, "$n × $n", sim)
end

View file

@ -0,0 +1,80 @@
// version 1.2.10
import java.util.Random
val rand = Random()
const val RAND_MAX = 32767
lateinit var map: IntArray
var w = 0
var ww = 0
const val ALPHA = "+.ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
const val ALEN = ALPHA.length - 3
fun makeMap(p: Double) {
val thresh = (p * RAND_MAX).toInt()
ww = w * w
var i = ww
map = IntArray(i)
while (i-- != 0) {
val r = rand.nextInt(RAND_MAX + 1)
if (r < thresh) map[i] = -1
}
}
fun showCluster() {
var k = 0
for (i in 0 until w) {
for (j in 0 until w) {
val s = map[k++]
val c = if (s < ALEN) ALPHA[1 + s] else '?'
print(" $c")
}
println()
}
}
fun recur(x: Int, v: Int) {
if ((x in 0 until ww) && map[x] == -1) {
map[x] = v
recur(x - w, v)
recur(x - 1, v)
recur(x + 1, v)
recur(x + w, v)
}
}
fun countClusters(): Int {
var cls = 0
for (i in 0 until ww) {
if (map[i] != -1) continue
recur(i, ++cls)
}
return cls
}
fun tests(n: Int, p: Double): Double {
var k = 0.0
for (i in 0 until n) {
makeMap(p)
k += countClusters().toDouble() / ww
}
return k / n
}
fun main(args: Array<String>) {
w = 15
makeMap(0.5)
val cls = countClusters()
println("width = 15, p = 0.5, $cls clusters:")
showCluster()
println("\np = 0.5, iter = 5:")
w = 1 shl 2
while (w <= 1 shl 13) {
val t = tests(5, 0.5)
println("%5d %9.6f".format(w, t))
w = w shl 1
}
}

View file

@ -0,0 +1,10 @@
(*Calculate C_n / n^2 for n=1000, 2000, ..., 10 000*)
In[1]:= Table[N[Max@MorphologicalComponents[
RandomVariate[BernoulliDistribution[.5], {n, n}],
CornerNeighbors -> False]/n^2], {n, 10^3, 10^4, 10^3}]
(*Find the average*)
In[2]:= % // MeanAround
(*Show a 15x15 matrix with each cluster given an incrementally higher number, Colorize instead of MatrixForm creates an image*)
In[3]:= MorphologicalComponents[RandomChoice[{0, 1}, {15, 15}], CornerNeighbors -> False] // MatrixForm

View file

@ -0,0 +1,70 @@
import random, sequtils, strformat
const
N = 15
T = 5
P = 0.5
NotClustered = 1
Cell2Char = " #abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
NRange = [4, 64, 256, 1024, 4096]
type Grid = seq[seq[int]]
proc newGrid(n: Positive; p: float): Grid =
result = newSeqWith(n, newSeq[int](n))
for row in result.mitems:
for cell in row.mitems:
if rand(1.0) < p: cell = 1
func walkMaze(grid: var Grid; m, n, idx: int) =
grid[n][m] = idx
if n < grid.high and grid[n + 1][m] == NotClustered:
grid.walkMaze(m, n + 1, idx)
if m < grid[0].high and grid[n][m + 1] == NotClustered:
grid.walkMaze(m + 1, n, idx)
if m > 0 and grid[n][m - 1] == NotClustered:
grid.walkMaze(m - 1, n, idx)
if n > 0 and grid[n - 1][m] == NotClustered:
grid.walkMaze(m, n - 1, idx)
func clusterCount(grid: var Grid): int =
var walkIndex = 1
for n in 0..grid.high:
for m in 0..grid[0].high:
if grid[n][m] == NotClustered:
inc walkIndex
grid.walkMaze(m, n, walkIndex)
result = walkIndex - 1
proc clusterDensity(n: int; p: float): float =
var grid = newGrid(n, p)
result = grid.clusterCount() / (n * n)
proc print(grid: Grid) =
for n, row in grid:
stdout.write n mod 10, ") "
for cell in row:
stdout.write ' ', Cell2Char[cell]
stdout.write '\n'
when isMainModule:
randomize()
var grid = newGrid(N, 0.5)
echo &"Found {grid.clusterCount()} clusters in this {N} by {N} grid\n"
grid.print()
echo ""
for n in NRange:
var sum = 0.0
for _ in 1..T:
sum += clusterDensity(n, P)
let sim = sum / T
echo &"t = {T} p = {P:4.2f} n = {n:4} sim = {sim:7.5f}"

View file

@ -0,0 +1,72 @@
$fill = 'x';
$D{$_} = $i++ for qw<DeadEnd Up Right Down Left>;
sub deq { defined $_[0] && $_[0] eq $_[1] }
sub perctest {
my($grid) = @_;
generate($grid);
my $block = 1;
for my $y (0..$grid-1) {
for my $x (0..$grid-1) {
fill($x, $y, $block++) if $perc[$y][$x] eq $fill
}
}
($block - 1) / $grid**2;
}
sub generate {
my($grid) = @_;
for my $y (0..$grid-1) {
for my $x (0..$grid-1) {
$perc[$y][$x] = rand() < .5 ? '.' : $fill;
}
}
}
sub fill {
my($x, $y, $block) = @_;
$perc[$y][$x] = $block;
my @stack;
while (1) {
if (my $dir = direction( $x, $y )) {
push @stack, [$x, $y];
($x,$y) = move($dir, $x, $y, $block)
} else {
return unless @stack;
($x,$y) = @{pop @stack};
}
}
}
sub direction {
my($x, $y) = @_;
return $D{Down} if deq($perc[$y+1][$x ], $fill);
return $D{Left} if deq($perc[$y ][$x-1], $fill);
return $D{Right} if deq($perc[$y ][$x+1], $fill);
return $D{Up} if deq($perc[$y-1][$x ], $fill);
return $D{DeadEnd};
}
sub move {
my($dir,$x,$y,$block) = @_;
$perc[--$y][ $x] = $block if $dir == $D{Up};
$perc[++$y][ $x] = $block if $dir == $D{Down};
$perc[ $y][ --$x] = $block if $dir == $D{Left};
$perc[ $y][ ++$x] = $block if $dir == $D{Right};
($x, $y)
}
my $K = perctest(15);
for my $row (@perc) {
printf "%3s", $_ for @$row;
print "\n";
}
printf "𝘱 = 0.5, 𝘕 = 15, 𝘒 = %.4f\n\n", $K;
$trials = 5;
for $N (10, 30, 100, 300, 1000) {
my $total = 0;
$total += perctest($N) for 1..$trials;
printf "𝘱 = 0.5, trials = $trials, 𝘕 = %4d, 𝘒 = %.4f\n", $N, $total / $trials;
}

View file

@ -0,0 +1,69 @@
(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">grid</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">w</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ww</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">make_grid</span><span style="color: #0000FF;">(</span><span style="color: #004080;">atom</span> <span style="color: #000000;">p</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">ww</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">w</span><span style="color: #0000FF;">*</span><span style="color: #000000;">w</span>
<span style="color: #000000;">grid</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ww</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">ww</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">grid</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">-(</span><span style="color: #7060A8;">rnd</span><span style="color: #0000FF;">()<</span><span style="color: #000000;">p</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">alpha</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"+.ABCDEFGHIJKLMNOPQRSTUVWXYZ"</span><span style="color: #0000FF;">&</span>
<span style="color: #008000;">"abcdefghijklmnopqrstuvwxyz"</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">show_cluster</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">ww</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">gi</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">grid</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]+</span><span style="color: #000000;">2</span>
<span style="color: #000000;">grid</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">gi</span><span style="color: #0000FF;"><=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">alpha</span><span style="color: #0000FF;">)?</span><span style="color: #000000;">alpha</span><span style="color: #0000FF;">[</span><span style="color: #000000;">gi</span><span style="color: #0000FF;">]:</span><span style="color: #008000;">'?'</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">join_by</span><span style="color: #0000FF;">(</span><span style="color: #000000;">grid</span><span style="color: #0000FF;">,</span><span style="color: #000000;">w</span><span style="color: #0000FF;">,</span><span style="color: #000000;">w</span><span style="color: #0000FF;">,</span><span style="color: #008000;">""</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">recur</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">v</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">>=</span><span style="color: #000000;">1</span> <span style="color: #008080;">and</span> <span style="color: #000000;">x</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">ww</span> <span style="color: #008080;">and</span> <span style="color: #000000;">grid</span><span style="color: #0000FF;">[</span><span style="color: #000000;">x</span><span style="color: #0000FF;">]==-</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">grid</span><span style="color: #0000FF;">[</span><span style="color: #000000;">x</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">v</span>
<span style="color: #000000;">recur</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">-</span><span style="color: #000000;">w</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">v</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">recur</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">v</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">recur</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">v</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">recur</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">+</span><span style="color: #000000;">w</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">v</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">count_clusters</span><span style="color: #0000FF;">()</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">cls</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">ww</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">grid</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]=-</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">cls</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #000000;">recur</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">cls</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">cls</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">tests</span><span style="color: #0000FF;">(</span><span style="color: #004080;">int</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">atom</span> <span style="color: #000000;">p</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">n</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">make_grid</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">k</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">count_clusters</span><span style="color: #0000FF;">()/</span><span style="color: #000000;">ww</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">k</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">n</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">main</span><span style="color: #0000FF;">()</span>
<span style="color: #000000;">w</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">15</span>
<span style="color: #000000;">make_grid</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0.5</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"width=15, p=0.5, %d clusters:\n"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">count_clusters</span><span style="color: #0000FF;">())</span>
<span style="color: #000000;">show_cluster</span><span style="color: #0000FF;">()</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\np=0.5, iter=5:\n"</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">w</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">4</span>
<span style="color: #008080;">while</span> <span style="color: #000000;">w</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">4096</span> <span style="color: #008080;">do</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%5d %9.6f\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">w</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">tests</span><span style="color: #0000FF;">(</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0.5</span><span style="color: #0000FF;">)})</span>
<span style="color: #000000;">w</span> <span style="color: #0000FF;">*=</span> <span style="color: #000000;">4</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #000000;">main</span><span style="color: #0000FF;">()</span>
<!--

View file

@ -0,0 +1,63 @@
from __future__ import division
from random import random
import string
from math import fsum
n_range, p, t = (2**n2 for n2 in range(4, 14, 2)), 0.5, 5
N = M = 15
NOT_CLUSTERED = 1 # filled but not clustered cell
cell2char = ' #' + string.ascii_letters
def newgrid(n, p):
return [[int(random() < p) for x in range(n)] for y in range(n)]
def pgrid(cell):
for n in range(N):
print( '%i) ' % (n % 10)
+ ' '.join(cell2char[cell[n][m]] for m in range(M)))
def cluster_density(n, p):
cc = clustercount(newgrid(n, p))
return cc / n / n
def clustercount(cell):
walk_index = 1
for n in range(N):
for m in range(M):
if cell[n][m] == NOT_CLUSTERED:
walk_index += 1
walk_maze(m, n, cell, walk_index)
return walk_index - 1
def walk_maze(m, n, cell, indx):
# fill cell
cell[n][m] = indx
# down
if n < N - 1 and cell[n+1][m] == NOT_CLUSTERED:
walk_maze(m, n+1, cell, indx)
# right
if m < M - 1 and cell[n][m + 1] == NOT_CLUSTERED:
walk_maze(m+1, n, cell, indx)
# left
if m and cell[n][m - 1] == NOT_CLUSTERED:
walk_maze(m-1, n, cell, indx)
# up
if n and cell[n-1][m] == NOT_CLUSTERED:
walk_maze(m, n-1, cell, indx)
if __name__ == '__main__':
cell = newgrid(n=N, p=0.5)
print('Found %i clusters in this %i by %i grid\n'
% (clustercount(cell), N, N))
pgrid(cell)
print('')
for n in n_range:
N = M = n
sim = fsum(cluster_density(n, p) for i in range(t)) / t
print('t=%3i p=%4.2f n=%5i sim=%7.5f'
% (t, p, n, sim))

View file

@ -0,0 +1,97 @@
#lang racket
(require srfi/14) ; character sets
; much faster than safe fixnum functions
(require
racket/require ; for fancy require clause below
(filtered-in
(lambda (name) (regexp-replace #rx"unsafe-" name ""))
racket/unsafe/ops)
; these aren't in racket/unsafe/ops
(only-in racket/fixnum for/fxvector in-fxvector fxvector-copy))
; ...(but less safe). if in doubt use this rather than the one above
; (require racket/fixnum)
(define t (make-parameter 5))
(define (build-random-grid p M N)
(define p-num (numerator p))
(define p-den (denominator p))
(for/fxvector #:length (fx* M N) ((_ (in-range (* M N))))
(if (< (random p-den) p-num) 1 0)))
(define letters
(sort (char-set->list (char-set-intersection
char-set:letter
; char-set:ascii
)) char<?))
(define n-letters (length letters))
(define cell->char
(match-lambda
(0 #\space) (1 #\.)
(c (list-ref letters (modulo (- c 2) n-letters)))))
(define (draw-percol-grid M N . gs)
(for ((r N))
(for ((g gs))
(define row-str
(list->string
(for/list ((idx (in-range (* r M) (* (+ r 1) M))))
(cell->char (fxvector-ref g idx)))))
(printf "|~a| " row-str))
(newline)))
(define (count-clusters! M N g)
(define (gather-cluster! k c)
(when (fx= 1 (fxvector-ref g k))
(define k-r (fxquotient k M))
(define k-c (fxremainder k M))
(fxvector-set! g k c)
(define-syntax-rule (gather-surrounds range? k+)
(let ((idx k+))
(when (and range? (fx= 1 (fxvector-ref g idx)))
(gather-cluster! idx c))))
(gather-surrounds (fx> k-r 0) (fx- k M))
(gather-surrounds (fx> k-c 0) (fx- k 1))
(gather-surrounds (fx< k-c (fx- M 1)) (fx+ k 1))
(gather-surrounds (fx< k-r (fx- N 1)) (fx+ k M))))
(define-values (rv _c)
(for/fold ((rv 0) (c 2))
((pos (in-range (fx* M N)))
#:when (fx= 1 (fxvector-ref g pos)))
(gather-cluster! pos c)
(values (fx+ rv 1) (fx+ c 1))))
rv)
(define (display-sample-clustering p)
(printf "Percolation cluster sample: p=~a~%" p)
(define g (build-random-grid p 15 15))
(define g+ (fxvector-copy g))
(define g-count (count-clusters! 15 15 g+))
(draw-percol-grid 15 15 g g+)
(printf "~a clusters~%" g-count))
(define (experiment p n t)
(printf "Experiment: ~a ~a ~a\t" p n t) (flush-output)
(define sum-Cn
(for/sum ((run (in-range t)))
(printf "[~a" run) (flush-output)
(define g (build-random-grid p n n))
(printf "*") (flush-output)
(define Cn (count-clusters! n n g))
(printf "]") (flush-output)
Cn))
(printf "\tmean K(p) = ~a~%" (real->decimal-string (/ sum-Cn t (sqr n)) 6)))
(module+ main
(t 10)
(for ((n (in-list '(4000 1000 750 500 400 300 200 100 15))))
(experiment 1/2 n (t)))
(display-sample-clustering 1/2))
(module+ test
(define grd (build-random-grid 1/2 1000 1000))
(/ (for/sum ((g (in-fxvector grd)) #:when (zero? g)) 1) (fxvector-length grd))
(display-sample-clustering 1/2))

View file

@ -0,0 +1,66 @@
my @perc;
my $fill = 'x';
enum Direction <DeadEnd Up Right Down Left>;
my $𝘒 = perctest(15);
.fmt("%-2s").say for @perc;
say "𝘱 = 0.5, 𝘕 = 15, 𝘒 = $𝘒\n";
my $trials = 5;
for 10, 30, 100, 300, 1000 -> $𝘕 {
my $𝘒 = ( [+] perctest($𝘕) xx $trials ) / $trials;
say "𝘱 = 0.5, trials = $trials, 𝘕 = $𝘕, 𝘒 = $𝘒";
}
sub infix:<deq> ( $a, $b ) { $a.defined && ($a eq $b) }
sub perctest ( $grid ) {
generate $grid;
my $block = 1;
for ^$grid X ^$grid -> ($y, $x) {
fill( [$x, $y], $block++ ) if @perc[$y; $x] eq $fill
}
($block - 1) / $grid²;
}
sub generate ( $grid ) {
@perc = ();
@perc.push: [ ( rand < .5 ?? '.' !! $fill ) xx $grid ] for ^$grid;
}
sub fill ( @cur, $block ) {
@perc[@cur[1]; @cur[0]] = $block;
my @stack;
my $current = @cur;
loop {
if my $dir = direction( $current ) {
@stack.push: $current;
$current = move $dir, $current, $block
}
else {
return unless @stack;
$current = @stack.pop
}
}
sub direction( [$x, $y] ) {
( Down if @perc[$y + 1][$x] deq $fill ) ||
( Left if @perc[$y][$x - 1] deq $fill ) ||
( Right if @perc[$y][$x + 1] deq $fill ) ||
( Up if @perc[$y - 1][$x] deq $fill ) ||
DeadEnd
}
sub move ( $dir, @cur, $block ) {
my ( $x, $y ) = @cur;
given $dir {
when Up { @perc[--$y; $x] = $block }
when Down { @perc[++$y; $x] = $block }
when Left { @perc[$y; --$x] = $block }
when Right { @perc[$y; ++$x] = $block }
}
[$x, $y]
}
}

View file

@ -0,0 +1,55 @@
package require Tcl 8.6
proc determineClusters {w h p} {
# Construct the grid
set grid [lrepeat $h [lrepeat $w 0]]
for {set i 0} {$i < $h} {incr i} {
for {set j 0} {$j < $w} {incr j} {
lset grid $i $j [expr {rand() < $p ? -1 : 0}]
}
}
# Find (and count) the clusters
set cl 0
for {set i 0} {$i < $h} {incr i} {
for {set j 0} {$j < $w} {incr j} {
if {[lindex $grid $i $j] == -1} {
incr cl
for {set q [list $i $j];set k 0} {$k<[llength $q]} {incr k} {
set y [lindex $q $k]
set x [lindex $q [incr k]]
if {[lindex $grid $y $x] != -1} continue
lset grid $y $x $cl
foreach dx {1 0 -1 0} dy {0 1 0 -1} {
set nx [expr {$x+$dx}]
set ny [expr {$y+$dy}]
if {
$nx >= 0 && $ny >= 0 && $nx < $w && $ny < $h &&
[lindex $grid $ny $nx] == -1
} then {
lappend q $ny $nx
}
}
}
}
}
}
return [list $cl $grid]
}
# Print a sample 15x15 grid
lassign [determineClusters 15 15 0.5] n g
puts "15x15 grid, p=0.5, with $n clusters"
puts "+[string repeat - 15]+"
foreach r $g {puts |[join [lmap x $r {format %c [expr {$x==0?32:64+$x}]}] ""]|}
puts "+[string repeat - 15]+"
# Determine the densities as the grid size increases
puts "p=0.5, iter=5"
foreach n {5 30 180 1080 6480} {
set tot 0
for {set i 0} {$i < 5} {incr i} {
lassign [determineClusters $n $n 0.5] nC
incr tot $nC
}
puts "n=$n, K(p)=[expr {$tot/5.0/$n**2}]"
}

View file

@ -0,0 +1,82 @@
import "random" for Random
import "/fmt" for Fmt
var rand = Random.new()
var RAND_MAX = 32767
var list = []
var w = 0
var ww = 0
var ALPHA = "+.ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
var ALEN = ALPHA.count - 3
var makeList = Fn.new { |p|
var thresh = (p * RAND_MAX).truncate
ww = w * w
var i = ww
list = List.filled(i, 0)
while (i != 0) {
i = i - 1
var r = rand.int(RAND_MAX+1)
if (r < thresh) list[i] = -1
}
}
var showCluster = Fn.new {
var k = 0
for (i in 0...w) {
for (j in 0...w) {
var s = list[k]
k = k + 1
var c = (s < ALEN) ? ALPHA[1 + s] : "?"
System.write(" %(c)")
}
System.print()
}
}
var recur // recursive
recur = Fn.new { |x, v|
if (x >= 0 && x < ww && list[x] == -1) {
list[x] = v
recur.call(x - w, v)
recur.call(x - 1, v)
recur.call(x + 1, v)
recur.call(x + w, v)
}
}
var countClusters = Fn.new {
var cls = 0
for (i in 0...ww) {
if (list[i] == -1) {
cls = cls + 1
recur.call(i, cls)
}
}
return cls
}
var tests = Fn.new { |n, p|
var k = 0
for (i in 0...n) {
makeList.call(p)
k = k + countClusters.call() / ww
}
return k / n
}
w = 15
makeList.call(0.5)
var cls = countClusters.call()
System.print("width = 15, p = 0.5, %(cls) clusters:")
showCluster.call()
System.print("\np = 0.5, iter = 5:")
w = 1 << 2
while (w <= (1 << 13)) {
var t = tests.call(5, 0.5)
Fmt.print("$5d $9.6f", w, t)
w = w << 1
}

View file

@ -0,0 +1,29 @@
const X=-1; // the sentinal that marks an untouched cell
var C,N,NN,P;
fcn createC(n,p){
N,P=n,p; NN=N*N;
C=NN.pump(List.createLong(NN),0); // vector of ints
foreach n in (NN){ C[n]=X*(Float.random(1)<=P) } // X is the sentinal
}
fcn showCluster{
alpha:="-ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz";
foreach n in ([0..NN,N]){ C[n,N].pump(String,alpha.get).println() }
}
fcn countClusters{
clusters:=0;
foreach n in (NN){
if(X!=C[n]) continue;
fcn(n,v){
if((0<=n<NN) and C[n]==X){
C[n]=v;
self.fcn(n-N,v); self.fcn(n-1,v); self.fcn(n+1,v); self.fcn(n+N,v);
}
}(n,clusters+=1);
}
clusters
}
fcn tests(N,n,p){
k:=0.0;
foreach z in (n){ createC(N,p); k+=countClusters().toFloat()/NN; }
k/n
}

View file

@ -0,0 +1,6 @@
createC(15,0.5);
println("width=%d, p=%.1f, %d clusters:".fmt(N,P,countClusters()));
showCluster();
println("p=0.5, 5 iterations:");
w:=4; do(6){ println("%5d %9.6f".fmt(w,tests(w, 5, 0.5))); w*=4; }