#!/usr/bin/perl
main();
sub main{
Set_Parameters();
Generate_Population();
$loop_counter = 0;
while($Top < 100){
$loop_counter++;
Score_Flibs();
Identify_Flibs();
Breed();
Mutate();
}
}
sub Set_Parameters{
$score_run = 100;
$target_sequence = "010011";
$periods = length($target_sequence);
$numsyms = 0;
@symbols = split(//g, $target_sequence);
for($i = 0; $i < @symbols; $i++){
if($symbols[$i] > $numsyms){
$numsyms = $symbols[$i];
}
}
$numsyms++;
@e = split(//g, $target_sequence);
$states = 4;
$noflibs = 10;
$BreedingRate = 30;
}
sub Generate_Population{
for($i = 0; $i<$noflibs; $i++){
for($x = 1; $x <= (($numsyms * 2) * $states)/2; $x++){
push(@{flib.$i}, int(rand($numsyms)));
push(@{flib.$i}, int(rand($states)));
}
}
}
sub Score_Flibs{
for($i = 0; $i < $noflibs; $i++){
$Score[$i] = 0;
$State[$i] = 0;
}
for($Outer = 0; $Outer < $score_run; $Outer++){
$CurrentSymbol = $e[$Outer % $periods];
if(($Outer % $periods) < ($periods - 1)){
$NextSymbol = $e[($Outer % $periods) + 1];
}
else
{
$NextSymbol = $e[0];
}
for($Inner = 0; $Inner < $noflibs; $Inner++){
$locus = (($numsyms * 2) * $State[$Inner]) + (2 * $CurrentSymbol);
if(${flib.$Inner}[$locus] == $NextSymbol){
$Score[$Inner]++;
}
$State[$Inner] = ${flib.$Inner}[$locus+1];
}
}
}
sub Identify_Flibs{
$Top = 0;
$Bottom = 100;
for($i = 0; $i < $noflibs; $i++){
if($Top < $Score[$i]){
$Top = $Score[$i];
$TopIndex = $i;
}
if($Bottom > $Score[$i]){
$Bottom = $Score[$i];
$BottomIndex = $i;
}
}
if ($Top > $PreviousScore){
print "$loop_counter $Top ";
for($i = 0; $i < @{flib.$TopIndex}; $i+=2){
print ${flib.$TopIndex}[$i];
print chr(${flib.$TopIndex}[$i+1]+65);
}
print "\n";
$PreviousScore = $Top;
}
}
sub Breed{
if(int(rand(101)) <= $BreedingRate){
$RandomFlib = int(rand($noflibs));
while($RandomFlib == $TopIndex){
$RandomFlib = int(rand($noflibs));
}
$c1 = int(rand((($numsyms * 2) * $states)));
$c2 = int(rand((($numsyms * 2) * $states)));
while($c1 == $c2){
$c2 = int(rand((($numsyms * 2) * $states)));
}
if($c1 > $c2){
$c2 += $c1;
$c1 = $c2 - $c1;
$c2 -= $c1;
}
for($i = 0; $i < $c1; $i++){
${flib.$BottomIndex}[$i] = ${flib.$RandomFlib}[$i];
}
for($i = $c1; $i <= $c2; $i++){
${flib.$BottomIndex}[$i] = ${flib.$TopIndex}[$i];
}
for($i = ($c2 + 1); $i < (($numsyms * 2) * $states); $i++){
${flib.$BottomIndex}[$i] = ${flib.$RandomFlib}[$i];
}
}
}
sub Mutate{
$RandomFlib = int(rand($noflibs));
$RandomLocus = int(rand((($numsyms * 2) * $states)));
if($RandomLocus % 2 == 0){
${flib.$RandomFlib}[$RandomLocus] = int(rand($numsyms));
}
else
{
${flib.$RandomFlib}[$RandomLocus] = int(rand($states));
}
}