Simple model of peacock tail evolution

Genetic code model

Assume that a single peacock feather is associated with a segment of genetic code of length 100. Choose some initial genetic code:

InitialGeneticCode = Table[RandomInteger[{0,3}],{n,50}]

Create an initial population with each individual having the same genetic subsequence.

InitialPopulationSize = 250;
InitialPopulation = Table[InitialGeneticCode,{n,InitialPopulationSize}];

Assume nm mutations occur randomly with probability r

Mutation[gc_,nm_,r_]:=Module[{mc,n,m},
n=Length[gc]; mc=gc;
For[m=1, m≤nm,m++,
     If[ Random[]<r,
       mc[[ RandomInteger[{1,n}] ]] = RandomInteger[{0,3}] ] ];
Return[mc]]

Asexual reproduction of initial population allowing for mutations

Reproduction[p_,nm_,r_] := Module[{np,n},
np={};
n=Length[p];
For[k=1,k≤n,k++,
  AppendTo[np,p[[k]]];
  AppendTo[np,Mutation[p[[k]],nm,r]] ];
Return[np] ]

First offsprings from the initial population

FirstOffsprings=Reproduction[InitialPopulation,10,0.1];

Select population survivors that have ‘tail length’ larger than average of population

NaturalSelection[p_]:=Module[{np,av,TailLengths,NrIndividuals,GeneticCodeLength},
np={};
NrIndividuals = Length[p];
GeneticCodeLength = Length[p[[1]]];
TailLengths = Table[0,{k,1,NrIndividuals}];
For[k=1,k≤NrIndividuals,k++,
For[j=1,j≤GeneticCodeLength,j++,
TailLengths[[k]] = TailLengths[[k]]+p[[k,j]] ] ];
av=N[Sum[TailLengths[[k]],{k,1,Length[TailLengths]}]/Length[TailLengths]];
For[k=1,k≤Length[p],k++,
   If[TailLengths[[k]]>av,
    AppendTo[np,p[[k]]];
]];
Return[np];
];

Survivors from first offsprings

FirstGeneration=NaturalSelection[FirstOffsprings];

Length[FirstGeneration]

Translate genetic code to peacock tail feathers

Construct a single feather from the genetic code. Allow for some randomness in the transcription of the genetic code into a feather shape.

Feather[gc_]:=Module[{f={{0,0}},nf=1,n=Length[gc],θ=π/4.},
For[i=2,i≤n,i++,
       If[gc[[i]]==0,
                 θ=θ-Random[]π/36.,              AppendTo[f,f[[nf]]+ gc[[i]] {Cos[θ],Sin[θ]} ];
nf = nf + 1;
 ]];
Return[f]
]

tColor={Pink,Yellow,Cyan};

Beak[gc_]:=Module[{oldP={0,0},f={},newP,nf=1,n=Length[gc],θ=π/4.,l=1,c},
For[i=2,i≤n,i++,
       If[gc[[i]]==0,
                 θ=θ-π/16.;l=0.95*l,
c=Part[tColor,gc[[i]]];
newP =oldP + l*{Cos[θ],Sin[θ]};              AppendTo[f,{c ,Disk[oldP,Norm[oldP-newP]]}];
oldP=newP;
nf = nf + 1;
 ]];
Return[f]
]

b0=Beak[InitialGeneticCode];

Graphics[b0]

Construct a tail from nf feathers

Tail[gc_,nf_]:=Module[{f,t},
     f=Feather[gc];
     t = Table[Feather[InitialGeneticCode],{n,1,nf}];
     Return[Graphics[Map[Line[#]&,t]]];
];

Evolution in action over many generations

Evolve[p_,nGen_,nm_,r_]:=Module[{k,oldp,newp},
    oldp=p;
    For[k=1,k≤nGen,k++,
newp=NaturalSelection[Reproduction[oldp,nm,r]]; Print[Length[newp]," individuals in generation ",k];
oldp=newp; ];
  Return[newp];
];

EvolvedPopulation100=Evolve[InitialPopulation,10,10,0.8];

Length[EvolvedPopulation100]