BioNrd has asked for the wisdom of the Perl Monks concerning the following question:
I have updated the code with some comments. I hope that helps with the interpretation. I am sorry about that. It is clear in my mind...but none of you are in there to figure out what this garbage means.
#Randomly generate a population of plants, and breeds and dies. is the + purpose of this mess... use Data::Dumper; use warnings; $popCt=1; $seed = 20; $germrate = .5; $removal = 15; $iteration = 20; for (1 .. $popCt) { my ($refToArrA, $refToArrB, $refToArrC, $refToArrD) = makeArrays() +; #creates a list of individuals, and chormosomes $counter++; &gener( $refToArrA, $refToArrB, $refToArrC, $refToArrD ); #creates + the storage hash # print Data::Dumper->Dumpxs([\%HoH], [q{*HoH}]); } for (1 .. $iteration) { &births(); &death(); } print Data::Dumper->Dumpxs([\%HoH], [q{*HoH}]); #no work is needed here, this works like I want sub makeArrays { $lower = 10; $upper = 20; my @chroma; my @chromb; my $ranpop; $ranpop = int rand($upper - $lower + 1) + $lower; my @arrA = ( 1 .. $ranpop ); my @arrD = (1 .. $ranpop ); my $limiter = 50; my @holda; my @holdb; while ($ranpop) { my $genea = int rand ($limiter); push(@holda, $genea); my $geneb = int rand ($limiter); push(@holdb, $geneb); $ranpop--; } my @arrB = ( @holda ); my @arrC = ( @holdb ); return \@arrA, \@arrB, \@arrC, \@arrD; } #this is also working sub gener { my ( $refToArrA, $refToArrB, $refToArrC, $refToArrD ) = @_; my @newind = @$refToArrA; my @newchroma = @$refToArrB; my @newchromb = @$refToArrC; my @newholder = @$refToArrD; for my $pop ( 1 .. $popCt ) { $HoH{$counter} = { holder => [@newholder], individual => [ @newind ], chromasome1 => [ @newchroma ], chromasome2 => [ @newchromb ], }; } } sub births { my @holder = @{$HoH{$counter}{'holder'}}; my @ind = @{$HoH{$counter}{'individual'}}; my @chroma = @{$HoH{$counter}{'chromasome1'}}; my @chromb = @{$HoH{$counter}{'chromasome2'}}; my $random = int rand $seed; #randomly generate a number of see +d that will be made in 1 generation my $birth = int $random * $germrate; #only some of those seeds wil +l germinate (survive) for (1 .. $birth) { srand; my $ender = $holder[$#holder]; my $ranmom = (int rand $ender); #Picking the chroma and b from mom and dad to later rec +ombine to make a seedling (offspring/new plant) my $moma = $chroma[$ranmom]; my $momb = $chromb[$ranmom]; my $randad = (int rand $ender); my $dada = $chroma[$randad]; my $dadb = $chromb[$randad]; $ender++; push @ind, $ender; #add new seedling to list push @holder, $ender; #this is explained below #this creates a new seedling, with genetic material from mother and fa +ther plants my $selector = int(rand(2)) + 1; if ($selector == 1) { push @chroma, $dada; push @chromb, $momb; } else { push @chroma, $moma; push @chromb, $dadb; } } #here I update the hash to keep everything straight. $HoH{$counter}{'holder'} = [@holder]; $HoH{$counter}{'chromasome1'} = [@chroma]; $HoH{$counter}{'chromasome2'} = [@chromb]; $HoH{$counter}{'individual'} = [@ind]; } sub death { my @holder = @{$HoH{$counter}{'holder'}}; my @ind = @{$HoH{$counter}{'individual'}}; my @chroma = @{$HoH{$counter}{'chromasome1'}}; my @chromb = @{$HoH{$counter}{'chromasome2'}}; #Randomly select a number of individuals to be removed from the + population my $bottle = int rand $removal; #select a list of individuals from the holder list... #I added this list b/c the ind list tends to get out of order... #and later in the code I needed a list in order...so I guess not sure. for ( 1 .. $bottle ) { ($ranpop = splice(@holder, int rand(@holder), 1)); push @killed, $ranpop; #I now have a list of killed plants } #This is picking the last value in the holder #to then create a new holder list #with the correct number of elements as plants that survive my $lastval = $holder[$#holder]; @holder = (1 .. $lastval); #Here I need to remove the killed plants from the chroma #and chromb lists otherwise they are in the list and do not #have a corresponding individual which was already removed above. #ie. (the list shifts out of place). #I need to maintain IND1-chroma1-chromb1, orentation in the lists tha +t I have. #There maybe a better way to do this...but this is how I tried to atta +ck the problem while (@killed) { my $lastkill = $killed[$#killed]; my $removed = $lastkill - 1; splice (@chroma, $removed, 1); splice (@chromb, $removed, 1); splice (@ind, $removed, 1); #This is where the problem is #the lists somehow get out of sync, and I am splicing in the #wrong place... pop @killed; } $HoH{$counter}{'holder'} = [@holder]; $HoH{$counter}{'chromasome1'} = [@chroma]; $HoH{$counter}{'chromasome2'} = [@chromb]; $HoH{$counter}{'individual'} = [@ind]; }
I think (big assumption) that it all boils down to the splice at the end of sub death. As the population changes (birth and death) the splice point becomes nonvalid for some references, which I am assuming creates the undef.
I have tried other options to try to shift the reference to the end of the ref and pop it or to the front and shift it. I cant get it to work properly no matter what I try.
Thanks for anything anyone can offer!
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: So close...
by moritz (Cardinal) on Nov 07, 2007 at 22:22 UTC | |
|
Re: So close...
by toolic (Bishop) on Nov 07, 2007 at 22:16 UTC | |
|
Re: So close...
by GrandFather (Saint) on Nov 11, 2007 at 08:52 UTC | |
|
Re: So close...
by BioNrd (Monk) on Nov 08, 2007 at 14:39 UTC |