Revision: 36415
Initial Code
Initial URL
Initial Description
Initial Title
Initial Tags
Initial Language
at November 22, 2010 01:05 by StanislavZza
Initial Code
local $| = 1; #forces stdout to flush so the dots show up. #set up parameters.................................. $first = 3; $end = 100; # upper bound on the N to use $max_gen = 1000; # how many generations to run for each $max_pop = 100; # carrying capacity C open(OUT,'>output.txt') or die 'hard'; # this is where the summary output goes open(MISS,'>missing.txt'); # this creates a list of all the 'missing' values for N # first add some column headings print OUT "Start,Generation,PopSize,Last,Demand,Kids,Died,Total\n"; # main loop to generate summary stats and individual report files for each N for ($start = $first ;$start < $end; $start+=2) { #just do the odd numbers sim($start); print "."; } print "\n"; # run the simulation for the given N sub sim { undef %n; #keeps track of what numbers are still in the ecology. Zero out before each run undef %all; #keeps track of any number ever hit $id = $_[0]; # the starting number N is the argument # you need to have a folder called 'sim' to dump the details in open(START,">sim//$id.txt") or die; #set up for windows. If you run Linux change the slashes $generation = 0; #initialize for this run $all{$id} = $n{$id} = 1; # associative arrays will keep track of who was and is alive $last = $start; #keeps track of the biggest number reached for the summary report while($generation < $max_gen) { $generation++; $pop = scalar(keys(%n)); # get the size print OUT "$start,$generation,$pop,$last,"; $kids = $died = 0; #keeps track of reproduction and extinction for this generation foreach $v (keys(%n)) { #go through the population and iterate if ($v % 2 == 0) { # if even divide by two $v /=2; if ($v == 1) { # kill it if it reaches 1 # it will vanish because it doesn't get copied to %n1 $died++; # keep track of how many we lost } else { $all{$v} = $n1{$v} = 1; # %n1 is the temp array for this work } } else { # it's odd, so do (3n+1)/2. Unless we're about to blow up our precision. # have to have a rule about overflow. I'll chose to kill it off as being a hog. if ($v > 1000000000) { # overflow problem $died++; } else { $v = (3*$v + 1)/2; $all{$v} = $n1{$v} = 1; copy($v); # make the mutant--see function below } } } $demand = scalar(keys(%n2)); #save this for reporting %n = %n1; # reset for the next trial. Yes, I should use pointers instead. I know. $npop = scalar(keys(%n)); #now add in the new generation foreach $num (sort(keys(%n2))) { # sorted so that we give the smaller ones priority last if $npop >= $max_pop; # stop when we get to the capacity next if $n{$num}; # already have this one in the population $n{$num} = 1; # add it in $npop++; # increment the total current population $kids++; } $total = scalar(keys(%all)); # count the types who ever lived print OUT "$demand,$kids,$died,$total\n"; # this prints out the whole population for this generation and N into N.txt in the sim folder foreach $key (sort {$a <=> $b} (keys(%n))) { print START "$key,"; } print START "\n"; # all done with that row undef %n1; # wipe our workspace clean undef %n2; } close START; # the sim is done. Print out what integers were missed between 2 and 1000 for($i =2;$i<1000;$i++) { print MISS "$start,$i\n" unless $all{$i} > 0; } } sub copy { #reproduce a number with mutation $t = $_[0] - 2; $all{$t} = $n2{$t}=1; #keep the kids separate, so we can apply the carrying capacity $last = $t if $t > $last; #find the biggest one reproduced }
Initial URL
http://highered.blogspot.com/2010/11/collatz-ecologies.html
Initial Description
See [blog post](http://highered.blogspot.com/2010/11/collatz-ecologies.html)
Initial Title
Collatz Ecology Generator
Initial Tags
Initial Language
Perl