Path Evolution by Natural Selection 
C. Fernando, V. Vasas, E. Szathmary, P. Husbands  
27th Dec 2010

The following analysis compares path evolution with standard natural selection of non-overlapping genotypes.

1. One locus and two alleles

First we model a simple single bypass mutant as in the network at the top of the above diagram. Imagine that the offspring green path is fitter than the parent pink path. 

The probability that during a tournament two different paths will be chosen is P, where x is the outflow weight to the bypass (offspring) node, and (1-x) is the outflow weight to the original parent node.

P = 2x(1-x)

This is also the probability that the winning path will increase in weight to a new value of

Nw = (x(1+L)) /(x(1+L) + (1-x)(1-L) )

due to the weight change rules which multiply the weight of the winning path (higher reward obtaining path) by a factor (1+L) and weaken the weight of the loosing path by a factor (1-L) followed by normalization. For the winning path this gives the difference equation

Xnew = P Nw + (1-P)x

((2 (1+L) (1-x) (x^2))/((1-L) (1-x)+(1+L) x))+x (1-2 (1-x) x)

We now plot the vector field for the winning and the loosing paths for L = 0.1, the standard lambda values used in the simulations.

L = 0.1
Plot[ ((2 (1+L) (1-x) (x^2))/((1-L) (1-x)+(1+L) x))+x (1-2 (1-x) x)-x,{x,0,1}]

Plot[ P( (x(1-L)) /((1-x)(1+L) + x(1-L) ) )+ (1-P)x -x,{x,0,1}]

The winning path (above) always increases in weight to 1.0, and the loosing path (below) always decreases in weight to 0.0, irrespective of the original weights. This is survival of the fittest path. Below we can solve the differential equations for the above competition dynamics.

s = NDSolve[{x'[t]== 2x[t](1-x[t])( (x[t](1-L)) /((1-x[t])(1+L) + x[t](1-L) ) )+ (1- 2x[t](1-x[t]))x[t] -x[t],x[0]==0.9},x,{t,0,1000}]
p1 =Plot[Evaluate[x[t]/.s],{t,0,100},PlotRange->All, PlotStyle-> {Blue,Thick}]

s = NDSolve[{x'[t]== 2x[t](1-x[t])( (x[t](1+L)) /((1-x[t])(1-L) + x[t](1+L) ) )+ (1- 2x[t](1-x[t]))x[t] -x[t],x[0]==0.1},x,{t,0,1000}]
p2 = Plot[Evaluate[x[t]/.s],{t,0,100},PlotRange->All, PlotStyle-> {Red,Thick}]

Show[p1,p2, AxesOrigin->{0,0}, PlotRange-> {0,1}]

It shows how the new winning bypass mutant reaches fixation and the old lower fitness parent path dies out. This is one locus two allele selection dynamics.

2. Two loci each with two alleles

Now let us consider selection at two loci, each with two alleles. An example of this is shown in the diagram below.

This shows two serial mutants. There are four possible paths through the system. Let us call these, A, B,C,D from top to bottom. Let us assume that A > B = D > C in terms of fitness. For example, we may want to maximize the number of unfilled nodes in a path. Let the first bifurcation weight and its mutant be x and (1-x) and the second bifurcation weight and its mutant y and (1-y). Then there exist the following probabilities of traversing each path.

TA = x*y 
TB = x(1-y)
TC = (1-x)(1-y)
TD = (1-x)y

Recall that only non-overlapping parts of a winning and loosing paths undergo weight change. Later we may model a diversity maintenance method which actually punishes overlapping parts between the looser and the winner. 

A winning edge will be strengthened and a loosing edge will be weakened to the same values as previously described, i.e.

Nw = (x(1+L)) /(x(1+L) + (1-x)(1-L) )

Nl = ((1-x)(1-L)) /(x(1+L) + (1-x)(1-L) )

We wish to write a difference equation that gives the  value of x(t+1) in terms of the probability of various path pairs being generated in each generation. The value of x only changes if the following path pairs are traversed... (A & C), (A & D) and (B & C), because only in these cases will the fitness of the two paths be different. If the fitness of the two paths is the same, nothing happens in that generation.

PAC = 2*TA * TC
PAD = 2*TA*TD
PBC = 2*TB*TC

When the other pairs are travered, either fitness is identical and there is no change in weights, e.g. (B & D ), or the paths do not differ at the x edge, e.g when pair (D&C) or (A&B) are taken. Looking at each case in tern, A beats C , A beats D, and B beats C, and so x will always be strengthened or not changed at all in each generation according to the following eqaution.

Xnew = Nw * (PAC + PAD + PBC ) + (1-(PAC + PAD + PBC ))*x

Similarly for weight y... the new value of that weight IF it is changed is given by...

Nwy = (y (1 + L)) /(y (1 + L) + (1 - y) (1 - L) )

And the probabilities of obtaining the path pairs in which y will be changed are..

PAB = 2*TA*TB
PAC = 2*TA*TC
PCD = 2*TC*TD

Ynew = Nwy * (PAB+PAC+PCD ) + (1-(PAB + PAC  + PCD ))*y

Now we can plot the vector field for x(t+1) -  x(t) and y(t+1) - y(t) as a function of x(t) and y(t) for L = 0.1

L = 0.1
Needs["VectorFieldPlots`"]

d[x] = Xnew-x
d[y]= Ynew -y

VectorFieldPlot[{-x+x (1-2 (1-x) x (((1-y))^2)-2 (1-x) x (1-y) y-2 (1-x) x (y^2))+(((1+L) x (2 (1-x) x (((1-y))^2)+2 (1-x) x (1-y) y+2 (1-x) x (y^2)))/((1-L) (1-x)+(1+L) x)),-y+y (1-2 (((1-x))^2) (1-y) y-2 (1-x) x (1-y) y-2 (x^2) (1-y) y)+(((1+L) y (2 (((1-x))^2) (1-y) y+2 (1-x) x (1-y) y+2 (x^2) (1-y) y))/((1-L) (1-y)+(1+L) y))}, {x, 0,1}, {y, 0,1}]

The above vector field plot for dx and dy against x, and y shows that the value of x and y (the two weights under selection in the winning path will tend to 1 over time.

L = 0.1
s = NDSolve[{x'[t]==-x[t]+x[t] (1-2 (1-x[t]) x[t] (((1-y[t]))^2)-2 (1-x[t]) x[t] (1-y[t]) y[t]-2 (1-x[t]) x[t] ((y[t])^2))+(((1+L) x[t] (2 (1-x[t]) x[t] (((1-y[t]))^2)+2 (1-x[t]) x[t] (1-y[t]) y[t]+2 (1-x[t]) x[t] ((y[t])^2)))/((1-L) (1-x[t])+(1+L) x[t])),
y'[t] ==-y[t]+y[t] (1-2 (((1-x[t]))^2) (1-y[t]) y[t]-2 (1-x[t]) x[t] (1-y[t]) y[t]-2 ((x[t])^2) (1-y[t]) y[t])+(((1+L) y[t] (2 (((1-x[t]))^2) (1-y[t]) y[t]+2 (1-x[t]) x[t] (1-y[t]) y[t]+2 ((x[t])^2) (1-y[t]) y[t]))/((1-L) (1-y[t])+(1+L) y[t])), x[0]==0.2,y[0]==0.1},{x,y},{t,0,500}]
p1 =Plot[Evaluate[{x[t], y[t]}/.s],{t,0,500},PlotRange->All, PlotStyle-> {{Blue,Thick},{ Red, Thick}}, AxesOrigin-> {0,0}]

In this two allele model, both edges go to fixation. The above graph shows the fixation of the two fitter alleles at each locus over time. The allele with the lower initial probability takes longer to reach fixation. 

We are also able to plot the frequency of phenotypes over time because we know the probability of the traversal of a path as a function of the x and y values...

TA = x*y 
TB = x (1 - y)
TC = (1 - x) (1 - y)
TD = (1 - x) y

This gives the following phenotypic dynamics.

L = 0.1
s = NDSolve[{x'[t]==-x[t]+x[t] (1-2 (1-x[t]) x[t] (((1-y[t]))^2)-2 (1-x[t]) x[t] (1-y[t]) y[t]-2 (1-x[t]) x[t] ((y[t])^2))+(((1+L) x[t] (2 (1-x[t]) x[t] (((1-y[t]))^2)+2 (1-x[t]) x[t] (1-y[t]) y[t]+2 (1-x[t]) x[t] ((y[t])^2)))/((1-L) (1-x[t])+(1+L) x[t])),
y'[t] ==-y[t]+y[t] (1-2 (((1-x[t]))^2) (1-y[t]) y[t]-2 (1-x[t]) x[t] (1-y[t]) y[t]-2 ((x[t])^2) (1-y[t]) y[t])+(((1+L) y[t] (2 (((1-x[t]))^2) (1-y[t]) y[t]+2 (1-x[t]) x[t] (1-y[t]) y[t]+2 ((x[t])^2) (1-y[t]) y[t]))/((1-L) (1-y[t])+(1+L) y[t])), x[0]==0.2,y[0]==0.1},{x,y},{t,0,500}]
p1 =Plot[Evaluate[{x[t]*y[t], x[t]*(1-y[t]), (1-x[t])*(1-y[t]), (1-x[t])*y[t]}/.s],{t,0,500},PlotRange->All, PlotStyle-> {{Purple,Thick},{Green,Thick}, { Blue, Thick},{Orange,Thick}} , AxesOrigin-> {0,0}]

We observe that whilst the fittest path (purple) goes to fixation, and the other paths become extinct, the dynamics of the intermediate fitness paths (B and D) are not monotonic. In fact, B and D actually increase for a brief period. This is because the intermediate fitness paths are partially benefited by the fitness obtained by the fittest path A.

2. Two loci each with two alleles and linkage disequilibrium.

XOR Fitness function: 10 = 01 = MAX, 11 = 00 = MIN.

TA =x*y
TB = x(1-y)
TC = (1-x)(1-z)
TD = (1-x)z

The new value of the weight of a winning edge is the same as before.

Nw = (x(1+L)) /(x(1+L) + (1-x)(1-L) )

Path pair traversal probabilities are...

PAB = 2*TA *TB
PAC = 2*TA*TC
PBD = 2*TB*TD
PCD = 2*TC*TD

The new X is weakened to Nlx with probability PAC and strengthened to Nwx with probability PBD, and is unchanged with probability (1-(Nlx+Nwx))

Nwx = (x(1+L)) /(x(1+L) + (1-x)(1-L) ) 

Nlx = ((x)(1-L)) /(x(1-L) + (1-x)(1+L) )

Xnew = Nlx * (PAC ) + Nwx *( PBD) + (1-(PAC+PBD))*x

Y looses with probability PAB

Nly = ((y)(1-L)) /(y(1-L) + (1-y)(1+L) )

Ynew = Nly * (PAB ) + (1-(PAB))*y

Z looses with probability PCD

Nlz = ((z)(1-L)) /(z(1-L) + (1-z)(1+L) )

Znew = Nlz * (PCD) + (1-(PCD))*z

L = 0.1
Needs["VectorFieldPlots`"]

d[x] = Xnew-x
d[y]= Ynew -y
d[z]= Ynew -z

VectorFieldPlot3D[{-x+((2 (1-L) (1-x) (x^2) y (1-z))/((1+L) (1-x)+(1-L) x))+((2 (1+L) (1-x) (x^2) (1-y) z)/((1-L) (1-x)+(1+L) x))+x (1-2 (1-x) x y (1-z)-2 (1-x) x (1-y) z),-y+((2 (1-L) (x^2) (1-y) (y^2))/((1+L) (1-y)+(1-L) y))+y (1-2 (x^2) (1-y) y),((2 (1-L) (x^2) (1-y) (y^2))/((1+L) (1-y)+(1-L) y))+y (1-2 (x^2) (1-y) y)-z }, {x, 0,1}, {y, 0,1}, {z, 0,1}]

L = 0.1
s = NDSolve[{x'[t]==-x[t]+((2 (1-L) (1-x[t]) ((x[t])^2) y[t] (1-z[t]))/((1+L) (1-x[t])+(1-L) x[t]))+((2 (1+L) (1-x[t]) ((x[t])^2) (1-y[t]) z[t])/((1-L) (1-x[t])+(1+L) x[t]))+x[t] (1-2 (1-x[t]) x[t] y[t] (1-z[t])-2 (1-x[t]) x[t] (1-y[t]) z[t]),
y'[t]==-y[t]+((2 (1-L) ((x[t])^2) (1-y[t]) ((y[t])^2))/((1+L) (1-y[t])+(1-L) y[t]))+y[t] (1-2 ((x[t])^2) (1-y[t]) y[t]), 
z'[t]==-z[t]+ ((2 (1-L) ((x[t])^2) (1-y[t]) ((y[t])^2))/((1+L) (1-y[t])+(1-L) y[t]))+y [t](1-2 ((x[t])^2) (1-y[t]) y[t])

, x[0]==0.6,y[0]==0.5, z[0] == 0.5},{x,y,z},{t,0,1000}]
p1 =Plot[Evaluate[{x[t], y[t], z[t]}/.s],{t,0,1000},PlotRange->All, PlotStyle-> {{Blue,Thick},{ Red, Thick, Dashed}, {Green, Thick, Dashed}}, AxesOrigin-> {0,0}]
p1 =Plot[Evaluate[{x[t]*y[t], x[t](1-y[t]), (1-x[t])*(1-z[t]), (1-x[t])*z[t]} /.s],{t,0,1000},PlotStyle-> {{Purple,Thick},{Green,Thick}, { Blue, Thick},{Orange,Thick}}, AxesOrigin-> {0,0}]


L = 0.1
s = NDSolve[{x'[t]==-x[t]+((2 (1-L) (1-x[t]) ((x[t])^2) y[t] (1-z[t]))/((1+L) (1-x[t])+(1-L) x[t]))+((2 (1+L) (1-x[t]) ((x[t])^2) (1-y[t]) z[t])/((1-L) (1-x[t])+(1+L) x[t]))+x[t] (1-2 (1-x[t]) x[t] y[t] (1-z[t])-2 (1-x[t]) x[t] (1-y[t]) z[t]),
y'[t]==-y[t]+((2 (1-L) ((x[t])^2) (1-y[t]) ((y[t])^2))/((1+L) (1-y[t])+(1-L) y[t]))+y[t] (1-2 ((x[t])^2) (1-y[t]) y[t]), 
z'[t]==-z[t]+ ((2 (1-L) ((x[t])^2) (1-y[t]) ((y[t])^2))/((1+L) (1-y[t])+(1-L) y[t]))+y [t](1-2 ((x[t])^2) (1-y[t]) y[t])

, x[0]==0.4,y[0]==0.5, z[0] == 0.5},{x,y,z},{t,0,1000}]
p1 =Plot[Evaluate[{x[t], y[t], z[t]}/.s],{t,0,1000},PlotRange->All, PlotStyle-> {{Blue,Thick},{ Red, Thick, Dashed}, {Green, Thick, Dashed}}, AxesOrigin-> {0,0}]
p1 =Plot[Evaluate[{x[t]*y[t], x[t](1-y[t]), (1-x[t])*(1-z[t]), (1-x[t])*z[t]} /.s],{t,0,1000},PlotStyle-> {{Purple,Thick},{Green,Thick}, { Blue, Thick},{Orange,Thick}}, AxesOrigin-> {0,0}]

The two wining and equal paths 01 and 10 have the highest frequency. Which one has a higher frequency depends on the initial condition x[0].

Now consider the possibility that the phenotype 10 is fitter than the phenotype 01
The only difference in the equations will be in the change of x. 

X looses with probabilty PAC, and now wins with probability PBC + PBD. The others are unchanged.

PBC = 2*TB*TC

Xnew = Nlx * (PAC ) + Nwx *( PBD + PBC) + (1-(PAC+PBD+ PBC))*x

d[x] = Xnew-x
d[y]= Ynew -y
d[z]= Ynew -z

VectorFieldPlot3D[{-x+((2 (1-L) (1-x) (x^2) y (1-z))/((1+L) (1-x)+(1-L) x))+x (1-2 (1-x) x (1-y) (1-z)-2 (1-x) x y (1-z)-2 (1-x) x (1-y) z)+(((1+L) x (2 (1-x) x (1-y) (1-z)+2 (1-x) x (1-y) z))/((1-L) (1-x)+(1+L) x)),((2 (1-L) (x^2) (1-y) (y^2))/((1+L) (1-y)+(1-L) y))+y (1-2 (x^2) (1-y) y)-z }, {x, 0,1}, {y, 0,1}, {z, 0,1}]

L = 0.1
s = NDSolve[{x'[t]==-x[t]+((2 (1-L) (1-x[t]) ((x[t])^2) y[t] (1-z[t]))/((1+L) (1-x[t])+(1-L) x[t]))+x [t](1-2 (1-x[t]) x[t] (1-y[t]) (1-z[t])-2 (1-x[t]) x[t] y[t] (1-z[t])-2 (1-x[t]) x[t] (1-y[t]) z[t])+(((1+L) x[t] (2 (1-x[t]) x[t] (1-y[t]) (1-z[t])+2 (1-x[t]) x[t] (1-y[t]) z[t]))/((1-L) (1-x[t])+(1+L) x[t])),
y'[t]==-y[t]+((2 (1-L) ((x[t])^2) (1-y[t]) ((y[t])^2))/((1+L) (1-y[t])+(1-L) y[t]))+y[t] (1-2 ((x[t])^2) (1-y[t]) y[t]), 
z'[t]==-z[t]+ ((2 (1-L) ((x[t])^2) (1-y[t]) ((y[t])^2))/((1+L) (1-y[t])+(1-L) y[t]))+y [t](1-2 ((x[t])^2) (1-y[t]) y[t])

, x[0]==0.1,y[0]==0.3, z[0] == 0.5},{x,y,z},{t,0,1000}]
p1 =Plot[Evaluate[{x[t], y[t], z[t]}/.s],{t,0,1000},PlotRange->All, PlotStyle-> {{Green,Thick},{ Red, Thick, Dashed}, {Blue, Thick, Dashed}}, AxesOrigin-> {0,0}]
p1 =Plot[Evaluate[{x[t]*y[t], x[t](1-y[t]), (1-x[t])*(1-z[t]), (1-x[t])*z[t]} /.s],{t,0,1000},PlotStyle-> {{Purple,Thick},{Green,Thick}, { Blue, Thick},{Orange,Thick}}, AxesOrigin-> {0,0}]

From a fully connected network, weight change alone is sufficient to establish linkage disequilibrium to make 10 more frequent than 01.

L = 0.1
s = NDSolve[{x'[t]==-x[t]+((2 (1-L) (1-x[t]) ((x[t])^2) y[t] (1-z[t]))/((1+L) (1-x[t])+(1-L) x[t]))+x [t](1-2 (1-x[t]) x[t] (1-y[t]) (1-z[t])-2 (1-x[t]) x[t] y[t] (1-z[t])-2 (1-x[t]) x[t] (1-y[t]) z[t])+(((1+L) x[t] (2 (1-x[t]) x[t] (1-y[t]) (1-z[t])+2 (1-x[t]) x[t] (1-y[t]) z[t]))/((1-L) (1-x[t])+(1+L) x[t])),
y'[t]==-y[t]+((2 (1-L) ((x[t])^2) (1-y[t]) ((y[t])^2))/((1+L) (1-y[t])+(1-L) y[t]))+y[t] (1-2 ((x[t])^2) (1-y[t]) y[t]), 
z'[t]==0

, x[0]==0.1,y[0]==0.0, z[0] == 0.5},{x,y,z},{t,0,1000}]
p1 =Plot[Evaluate[{x[t], y[t], z[t]}/.s],{t,0,1000},PlotRange->All, PlotStyle-> {{Blue,Thick},{ Red, Thick, Dashed}, {Green, Thick, Dashed}}, AxesOrigin-> {0,0}]
p1 =Plot[Evaluate[{x[t]*y[t], x[t](1-y[t]), (1-x[t])*(1-z[t]), (1-x[t])*z[t]} /.s],{t,0,1000},PlotStyle-> {{Purple,Thick},{Green,Thick}, { Blue, Thick},{Orange,Thick}}, AxesOrigin-> {0,0}]