Percolation/Site percolation: Difference between revisions
Content added Content deleted
m (correct C code to match requirements) |
(→Tcl: Added implementation) |
||
Line 428: | Line 428: | ||
1.0: 1.0}</pre> |
1.0: 1.0}</pre> |
||
Note the abrupt change in percolation at around p = 0.6. These abrupt changes are [http://mathworld.wolfram.com/PercolationThreshold.html expected]. |
Note the abrupt change in percolation at around p = 0.6. These abrupt changes are [http://mathworld.wolfram.com/PercolationThreshold.html expected]. |
||
=={{header|Tcl}}== |
|||
{{works with|Tcl|8.6}} |
|||
<lang tcl>package require Tcl 8.6 |
|||
oo::class create SitePercolation { |
|||
variable cells w h |
|||
constructor {width height probability} { |
|||
set w $width |
|||
set h $height |
|||
for {set cells {}} {[llength $cells] < $h} {lappend cells $row} { |
|||
for {set row {}} {[llength $row] < $w} {lappend row $cell} { |
|||
set cell [expr {rand() < $probability}] |
|||
} |
|||
} |
|||
} |
|||
method print {out} { |
|||
array set map {0 "#" 1 " " -1 .} |
|||
puts "+[string repeat . $w]+" |
|||
foreach row $cells { |
|||
set s "|" |
|||
foreach cell $row { |
|||
append s $map($cell) |
|||
} |
|||
puts [append s "|"] |
|||
} |
|||
set outline [lrepeat $w "-"] |
|||
foreach index $out { |
|||
lset outline $index "." |
|||
} |
|||
puts "+[join $outline {}]+" |
|||
} |
|||
method percolate {} { |
|||
for {set work {}; set i 0} {$i < $w} {incr i} { |
|||
if {[lindex $cells 0 $i]} {lappend work 0 $i} |
|||
} |
|||
try { |
|||
my Fill $work |
|||
return {} |
|||
} trap PERCOLATED x { |
|||
return [list $x] |
|||
} |
|||
} |
|||
method Fill {queue} { |
|||
while {[llength $queue]} { |
|||
set queue [lassign $queue y x] |
|||
if {$y >= $h} {throw PERCOLATED $x} |
|||
if {$y < 0 || $x < 0 || $x >= $w} continue |
|||
if {[lindex $cells $y $x]<1} continue |
|||
lset cells $y $x -1 |
|||
lappend queue [expr {$y+1}] $x [expr {$y-1}] $x |
|||
lappend queue $y [expr {$x-1}] $y [expr {$x+1}] |
|||
} |
|||
} |
|||
} |
|||
# Demonstrate one run |
|||
puts "Sample percolation, 15x15 p=0.6" |
|||
SitePercolation create bp 15 15 0.6 |
|||
bp print [bp percolate] |
|||
bp destroy |
|||
puts "" |
|||
# Collect statistics |
|||
apply {{} { |
|||
puts "Percentage of tries that percolate, varying p" |
|||
set tries 100 |
|||
for {set pint 0} {$pint <= 10} {incr pint} { |
|||
set p [expr {$pint * 0.1}] |
|||
set tot 0 |
|||
for {set i 0} {$i < $tries} {incr i} { |
|||
set bp [SitePercolation new 15 15 $p] |
|||
if {[$bp percolate] ne ""} { |
|||
incr tot |
|||
} |
|||
$bp destroy |
|||
} |
|||
puts [format "p=%.2f: %2.1f%%" $p [expr {$tot*100./$tries}]] |
|||
} |
|||
}}</lang> |
|||
{{out}} |
|||
<pre> |
|||
Sample percolation, 15x15 p=0.6 |
|||
+...............+ |
|||
|..####...#.#.#.| |
|||
|.###..........#| |
|||
|..###....#..#..| |
|||
|#..#..##.#..#.#| |
|||
|......#.....##.| |
|||
|.#...#..#..##..| |
|||
|.#......#.....#| |
|||
|######..#...#..| |
|||
| # #...#.#.###| |
|||
|# ##..#....## #| |
|||
| ##...#.### ##| |
|||
| #.###.# # # #| |
|||
|# ### ##### #| |
|||
| #### ## # # | |
|||
| # ## ## | |
|||
+---------------+ |
|||
Percentage of tries that percolate, varying p |
|||
p=0.00: 0.0% |
|||
p=0.10: 0.0% |
|||
p=0.20: 0.0% |
|||
p=0.30: 0.0% |
|||
p=0.40: 0.0% |
|||
p=0.50: 7.0% |
|||
p=0.60: 56.0% |
|||
p=0.70: 93.0% |
|||
p=0.80: 100.0% |
|||
p=0.90: 100.0% |
|||
p=1.00: 100.0% |
|||
</pre> |