## ga1_v2-3.sci

```//**************************************************************
// File:ga1_v2-3.sci
// Authors: Gerd Doeben-Henisch
// Version Start: January-18, 2010
// Version Last: July-3-2013, 15:28h
//
//******************************************************************
// Idea: Implements a simple GA according to Goldberg (1989)
//
// Attention: In Goldberg (1989) you will find only the demonstration of the program. The source code
// of this program is completely independ and original. It changes often according to discussions in
// the lectures. You are allowed to use this source code for non-commercial applications.
//
//*************************************************
// Helpful scilab-functions from the scilab libraries
//
// nancumsum ? This function returns the cumulative sum of the values of a matrix
// tabul ? frequency of values of a matrix or vector
// variance ? variance of the values of a vector or matrix
// strange ? range
// stdevf ? standard deviation
// bin2dec := translate a binary string of '1','0' into a decimal number
//
// SW-STRUCTURE
//
// All data are organized in a dynamic table. Left hand the actual genes, in the  middle
// supporting parameters and to the right intermediate modifications of the genes from the left side.
//
// POP FORMAT
// l := length of strings
// p := number of cells between string <1...l> and <l+p+1, ..., l+p+l>
// Pos 1-l := String
// Pos l+1 := Decimal Value of binary string
// Pos l+2 := Fitness for l+1 and l+p
// Pos l+3 := Percentage of overall fitness
// Pos l+4 := Expected count according to fitness
// Pos l+5 := Realized count
// Pos l+6 := 2nd Decimal value of a compund fitness

// Variable for overall Fitness

FITNESS_ALL = 0

// Variable for average Fitness

AFITNESS = 0

//********************************************************
// LIST OF ALL FUNCTIONS
//********************************************************
//
// [POPX]=popgen(n,l) : Generates a random popluation of n elements with length l
// [r]=randInt0(max) : Integer random numbers [0,max]
// [r]=randInt1(max) : Integer randim numbers [1,max]
// [D]= vec2dec(v,l) : Convert a vector v with length l and '1','0' into a decimal number
// [POP]=bin22dec(POP,l,show) : Convert ll strings of length l and '1','0' of a POP into a deci,mal at l+1
// [F]= fitness1(D) : Simpl fitness function F=D^2, D as integer
// [POP]=fitnessComp1(POP,l,show) : Compute fitness values for all strings at l+2 using fitness1
// [FITNESS_ALL]=fitness(POP,l,show) : Summing up all fitness value in column l+2
// [MFITNESS]=maxfitness(POP,l,show) : Find the biggest fitness value
// [POP,AFITNESS]=rfitness(POP,l, FITNESS_ALL,show) : Relative size of each fitness value
// [POP]= newPop0(POP,l,p,n,show) : Select only the positiv members without a '0' at l+p
// [POP]=strcpyLRR(POP,l,p,j,r) : Make a copy of a string from row_old to row_new: L --> R
// [POP]=crossmatch(POP,l,p,j,x) : Mixes the right sides of two strings from x to l
// [POP]= crossoverPrep(POP,l,p,n,show) : Preparing crossover
// [POP]= crossover(POP,l,p,n,show) : doing crossover
// [POP]= mutation(POP,l,p,n) : Doing mutation
// [MAXFIT]= maxfit02(l,n) : Maximal fitness number of a population with length l and member number n
// POP,MFITNESS, FITNESS_ALL]=popFit(POP,l,p,n,show) : Fitness of a population
// [PERC]=popFitPerc(POP,l,p,n,show) : Fitness of a population as percentage of the maximal fitness
//
//****************************************************************
//Function to generate automatically a population with random values
// Input:
// l := length of strings
// n := size of population (should be even on account of crossover!)
// Output:
// A population according to the above defined format
//

function[POPX]=popgen(n,l)

//Generate a matrix with only '0's

POPX = zeros(n,l)
MaxCells = n*l

// Distribute randomly '1's

for i=1:n
for j=1:l
if( rand() < 0.5 ) then POPX(i,j) = 0, else POPX(i,j) = 1, end
end
end

endfunction

//***************************************************
//Function to generate random numbers as integers [0,max]

function [r]=randInt0(max)

r = round(max*rand())

endfunction

//***************************************************
//Function to generate random numbers as integers [1,max]

function [r]=randInt1(max)

r = round((max-1)*rand()) +1

endfunction

//***************************************************
// Translate strings with binaries '0', '1' as decimal numbers
//
// v = vector of binaries from a POP-matrix (left part)
// D := decimal computed out of binaries
// l := length of strings

function[D]= vec2dec(v,l)

str=string(v(1:l))
for i=2:l, str(1)=str(1)+str(i)
end
D=bin2dec(str(1))

endfunction

//*****************************************************
// Convert binary strings with length l in a population POP into decimals at position l+1
//

function [POP]=bin22dec(POP,l,show)

[n,c]=size(POP)

for j=1:n,
v=POP(j,:),
[POP(j,l+1)]= vec2dec(v),end
endfunction

//***************************************************
// Simple fitness-function f=(x^2)
//
// D := decimal computed out of binaries

function[F]= fitness1(D)

F=D^2

endfunction

//************************************************
// Compute in a POP fitness in l+2 with some fitness function fitness1
//

function [POP]=fitnessComp1(POP,l,show)

[n,c]=size(POP)

for i=1:n,
[POP(i,l+2)]= fitness1(POP(i,l+1))
end

if show==1 then disp('fitnessComp1='), disp(POP), end

endfunction

//***************************************************
//Function to compute the overall fitness of a matrix POP
// Sum up all the l+2-th positions
// l := length of fitness strings

function[FITNESS_ALL]=fitness(POP,l,show)

FITNESS_ALL=sum(POP(:,l+2))

if show==1 then disp('FITNESS_ALL='), disp(FITNESS_ALL), end

endfunction

//***************************************************
//Function to compute the maximal individual fitness of a matrix POP
// Compute all the l+2-th positions
// l := length of fitness strings

function[MFITNESS]=maxfitness(POP,l,show)

// Extracts column l+2 and selects the maximal values

MFITNESS = max(POP([:],l+2))

if show==1 then disp('MAX-FITNESS='), disp(MFITNESS), end

endfunction

//***************************************************
//Function to compute the relative fitness of a string
// along with the average fitness
// Compute all the l+3-th positions
// l := length of fitness strings
// n:= number of members in population POP

function[POP,AFITNESS]=rfitness(POP,l,n, FITNESS_ALL,show)

[r,c]=size(POP);
for j=1:r
POP(j,l+3)=POP(j,l+2)/FITNESS_ALL
end

AFITNESS=FITNESS_ALL/r

for j=1:n
POP(j,l+4)=POP(j,l+3)*n
POP(j,l+5)=round(POP(j,l+4))
end

if show==1 then disp('rfitness='), disp(POP), end

endfunction

//***************************************************
//  newMember_old()

// l := length of fitness strings
// n :=  number of individuals in POP

function[POP]=newMember_old(POP,l,n,show)

//Check for sum of proposals

r2 = sum(POP(:,l+5))

//Two cases:
//r2>n or r2<n

if r2>n then
if show==1 then
disp('newMember r2>n'),disp('r2='), disp(r2)
end

while (r2>n)
z=round(rand()*n)
if z==0 then z=1,end //if
if POP(z,l+5) >2 then
POP(z,l+5) = POP(z,l+5)-1
end
r2=sum(POP(:,l+5))
end//while r2

if show==1 then
disp('newMember r2'), disp(r2)
end

elseif r2<n then
if show==1 then
disp('newMember r2<n'),disp('r2='), disp(r2)
end
while r2<n
z=round(rand()*n)
if z==0 then z=1,end //if
if POP(z,l+5) <1 then
POP(z,l+5) = POP(z,l+5)+1
end
r2=sum(POP(:,l+5))
end//while r2

end//if
if show==1 then
disp('newMember='),disp(POP)
end
endfunction
//**********************************************************
// Translates rfitness into integer parts
//

function[POP]=newMember(POP,l,n)

[r,c]=size(POP);

for j=1:r
POP(j,l+4)=POP(j,l+3)*n
POP(j,l+5)=round(POP(j,l+4))
end

//Check for sum of proposals

//r2=sum(POP(:,[p:p]))

endfunction

//***************************************************
// Select only those strings which are not zero at l+p!
// l := length of string
// p := number of parameters (=5)
// r2 := memory of position for new strings

function[POP]= newPop0(POP,l,p,n,show)

POPNEW=POP //Make a copy of POP

// Aranging the values according to size and limit
y=l+p,[M,k]=gsort(POP(:,[y:y]))

// M has the values from max to min
// k has the index of the values into POP
// Now one can copy the strings from POP-L to POPNEW-R as long as the sum s<n

s=0
j=0
r2=0 //Index into the new matrix POPNEW
while (s<n)&(j<n)
j=j+1, //Index into M
s=s+POP(k(j),y)

if POP(k(j),l+p) == 0 then r2=r2+1,POPNEW(r2,:)=POP(k(j),:),
else
m=POP(k(j),l+p),
for i=1:m,
r2=r2+1,POPNEW(r2,:)=POP(k(j),:),end //End of m
end //End of if

if show==1 then
disp('newPop0 r2='), disp(r2),disp(POPNEW)
end

end // End of while

//Attention, this procedures allows to extend POPNEW and the POP beyond n=4.

POP=POPNEW

if show==1 then
disp('newPop0 r2='), disp(r2),disp(POPNEW)
end

if r2 >n then
r3=r2-n
for i=1:r3
POP(n+i,:)=[]
end
end

if show==1 then
disp('newPop0='), disp(POP)
end

endfunction

//***************************************************
// Select only those strings which are not zero at l+p!
// l := length of string
// p := number of parameters (=5)
// r2 := memory of position for new strings

function[POP]= newPop0_old(POP,l,p,n,show)

POPNEW=POP

r2=0
j=1
while (j<n)
if POP(j,l+p) == 0 then j=j+1,end

if POP(j,l+p)>0 then m=POP(j,l+p),
for k=1:m,
r2=r2+1,POPNEW(r2,:)=POP(j,:),end

if show==1 then
disp('newPop0 r2='), disp(r2),disp(POPNEW)
end
end
j=j+1
end

POP=POPNEW

if show==1 then
disp('newPop0='), disp(POP)
end

endfunction

//***************************************************
// Make a copy of a string from row_old to row_new: L --> R
// where the copy starts at position l+p+1
// l := length of string
// j := row_old
// p := number of parameters (P=5)

function[POP]=strcpyLR(POP,l,p,j)

[r,c]=size(POP);
// Making a copy

for i=1:l
POP(j,l+p+i) = POP(j,i)
end

endfunction

//***************************************************
// Make a copy of a string from row_old to row_new: L --> R
//
// where the copy starts at position l+p+1
// l := length of string
// r := row_old
// j := row new
// p := number of parameters (P=5)

function[POP]=strcpyLRR(POP,l,p,j,r)

for i=1:l
POP(j,l+p+i) = POP(r,i)
end

endfunction

//***************************************************
// Prepare the crossover operations within a population POP
//
// Go through all rows j=1:n
// Get a random number r [1,l-1] != j to select a candidate
// copy the left r-th candidate to the right of POP(j)
//
// l := length of string
// n := number of members in POP

function[POP]= crossoverPrep(POP,l,p,n,show)

//Select candidates for all rows 1:n

for j=1:n

//Select randomly a candidate-line at r

r=j

while (r == j)
r = round((n-1) * rand())
if r==0 then r=1, end
end //while

if show==1 then
disp('j=')
disp(j)
disp('r=')
disp(r)
end

// Copy candidate from right at r to the left at j

POP=strcpyLRR(POP,l,p,j,r)
end //for

if show==1 then
disp('crossoverPrep=')
disp(POP)
end

endfunction

//**************************************************
// [POP]=crossmatch(POP,l,p,j,x)
//
// Match two strings during crossover from cut point x to l
//
// j := row of strings in POP
// p := number of parameters between strings left and right (actually  p=5)
// l := length of strings
// x := cut point within string x in [1,l-1]

function [POP]=crossmatch(POP,l,p,j,x)

Dif=l-x
for y=1:Dif
POP(j,x+y)=POP(j,l+p+x+y)
end

endfunction

//***************************************************
// Apply a crossover operation onto two  strings at intersection x
//
// The strings are assumed to be randomly paired
// One is at the left [1,l,], the other is at the right [l+p+i]
// For every row j=1:n
// one generates a random number x in [1,l-1]
// and then one copies all elements from right l+p+x
// to the left x
//
// p := number of parameters between strings left and right (actually  p=5)
// l := length of strings ( actually l=5)
// n := number of elements in POP (actually n=4)

function[POP]= crossover(POP,l,p,n,show)

for j=1:n

//Look for some cut point
x=0
while (x<1) or (x>(l-1))
x = round((l-1) * rand())

end

if show==1 then printf('crossover x = %d\n',x),end

// Mix two strings from the cut point to the right
[POP]=crossmatch(POP,l,p,j,x)

end//for

endfunction
//***************************************************
// Apply a mutation operation onto one randomly selected string
// Select randomly a point in the string and replace it's
// value by it's inverse '1' --> '0', '0' --> '1'

function[POP]= mutation(POP,l,p,n,show)

// Find a point in a string

c = round(l * rand())
if c == 0 then c=1  // This does not change anything
end

// Find a row in the table

r = round(n * rand())
if r == 0 then r=1  // This does not change anything
end

// replace the value

if(POP(r,c) == 1) then POP(r,c) = 0,
else POP(r,c) = 1
end

printf('mutation point at row = %d col = %d\n',r,c)

endfunction

//***************************************************
// Print the content of a matrix
//
// d := depth of matrix 'downwards'
// w := width of  matrix from left to right

function[M]= mshow(M,d,w)

for j=1:d,// printf('\n j= %3.1d : ',j)
for i=1:w, //printf(' %3.1d ',M(j,i))
end
//printf('\n')
end

endfunction

//***************************************************
// Translate strings with binaries '0', '1' as decimal numbers
//
// v = vector of binaries from a POP-matrix (left part)
// l := length of string
// D := decimal computed out of binaries

function[D]= vec22dec(v,l1,l2)

str=string(v(l1:l2))
for i=2:l2-l1+1, str(1)=str(1)+str(i)
end
D=bin2dec(str(1))

endfunction

//***************************************************
// Translate strings with binaries '0', '1' and n-many compartments as decimal numbers
//
// v = vector of binaries from a POP-matrix (left part)
// l := length of string
// b := number of bins for one number
// D := Array of decimals

function[D]= vec222dec(v,l,b,show)

D=[]
k=1

for j=1:b:l+1-b
if show==1 then printf('j = %d ',j),end

str=string(v(j:j+b-1))
for i=2:b, str(1)=str(1)+str(i)
end //i

if show==1 then printf('k = %d ',k),end

D(k)=bin2dec(str(1))

if show==1 then printf('D(k) = %d\n',D(k)),end

k=k+1

end //j

endfunction

//***************************************************
// maxfit01 builds a string of length l and computes the decimal value
//
// l := length of string
// MF := decimal computed out of binaries

function[MF]= maxfit01(l)

FitString=""
v=ones(1,l)
str=string(v)
for i=1:l, FitString = FitString + str(i)
end
MF=bin2dec(FitString)

endfunction

//***************************************************
// maxfi02 computes with maxfit01 the decimal value of a string with length l and
// then compares the maximal value according to the fitness function y=x^2
// multiplied by the number n of strings in a population
//
// l := length of string
// MF := decimal computed out of binaries

function[MAXFIT]= maxfit02(l,n)

MAXFIT=n*(maxfit01(l)^2)

endfunction

//***************************************************
// Fitness-function f for a world W which is realized as a table t:D --> R
// IF (d,r) in t then f(d1,d2)=100, ELSE f(d1,d2)=0
//
// d1,d2 := decimal values of population POP
// W := a world organized as a table
// n := number of elements in W
// F := fitness value

function[F]= fitness2(d1,d2,W)

[r,c]=size(W)
upper =10
goal = upper*2

i=1
while i < r+1,
if W(i,1) == d1 & W(i,2) == d2 then F=goal, i=r+1,
else F=round(upper * rand()), i=i+1,
end //if
end//while

endfunction

//***************************************************
// Fitness-function f for a world W which is realized as a table t:D --> R
// IF (d,r) in t then f(d1,d2)=goal, ELSE f(d1,d2)=random(upper)
//
// D := Array of pairs of decimal values
// W := a world organized as a table
// F := fitness value

function[F,goal]= fitness3(D,W)

[r,c]=size(W)
[r2,c2]=size(D)
F2=[]

upper =10  // range of numbers for non-goals [0,upper]
goal = upper*2

j=1 //Index for D
for i=1:r //Look to every pair in W
if W(i,1) == D(j) & W(i,2) == D(j+1) then F2(i)=goal,
else F2(i)=round(upper * rand()),
end //if
j=j+2
end // for i

F=sum(F2)

endfunction

//*************************************************************
// Function to compute only the fitness of a population
//
// Input:
// p := number of parameters between strings left and right (actually  p=5)
// l := length of strings
// n := number of elements in POP
// Output
// POP := a population
// MFITNESS := Maximal Fitness of each individual
// FITNES_ALL := Sum of all fitnss values

function[POP,MFITNESS, FITNESS_ALL]=popFit(POP,l,p,n,show)

MFITNESS=0
FITNESS_ALL=0

[POP]=bin22dec(POP,l,show) //Convert binary string into integer

[POP]=fitnessComp1(POP,l,show)  // Compute fitness value with fitness1

[FITNESS_ALL]=fitness(POP,l,show) //Sum up all fitness values

[MFITNESS]=maxfitness(POP,l,show)// Find max fitness value

endfunction

//*************************************************************
// Function to compute the fitness of a population as percentage
// of the maximal possible value
//
// Input:
// p := number of parameters between strings left and right (actually  p=5)
// l := length of strings
// n := number of elements in POP
// Output
// POP := a population
// MFITNESS := Maximal Fitness of each individual
// FITNES_ALL := Sum of all fitnss values

function [PERC]=popFitPerc(POP,l,p,n,show)

[POP,MFITNESS, FITNESS_ALL]=popFit(POP,l,p,n,show)
[MAXFIT]= maxfit02(l,n)
PERC=100 * (FITNESS_ALL/MAXFIT)

endfunction

//*************************************************************
// Function to compute  the maximal fitness of an individuum
// for several populations
//
// Input:
// p := number of parameters between strings left and right (actually  p=5)
// l := length of strings
// n := number of elements in POP
// run := number of choices
// Output
// POP := a population
// MFITNESS := Maximal Fitness of each individual
// MFITNESSX := Array with maximal fitness

function[POP,MEAN, MFITNESSX]=popFitX(l,p,n,run)

MAXFITUP = ((2^l)^2)

for k=1:run
[POP]=popgen(n,l+p)

for j=1:n, v=POP(j,:),  [POP(j,l+1)]= vec2dec(v,l)
end

for i=1:n,[POP(i,l+2)]= fitness1(POP(i,l+1))
end

[MFITNESSX(k)]=maxfitness(POP,l)

end

for k=1:run
MFITNESSX(k)=MFITNESSX(k)/(MAXFITUP/100)
end
MEAN = mean(MFITNESSX)

// Show graphical results

//clf(), xdel,

//plot2d([1:1:run], MFITNESSX)

endfunction

//*************************************************************
// Function to compute  the maximal fitness of an individuum
// for several populations
// for increasing n
//
// Input:
// p := number of parameters between strings left and right (actually  p=5)
// l := length of strings
// n := number of elements in POP
// run := number of choices
// Output
// POP := a population
// MFITNESS := Maximal Fitness of each individual
// MFITNESSX := Array with maximal fitness

function[MEAN, MEANX]=popFitXN(l,p,m,run)

for i=1:m

[POP,MEAN, MFITNESSX]=popFitX(l,p,i,run)

MEANX(i) = MEAN

end

MEAN = mean(MEANX)

// Show graphical results

clf(), xdel,

plot2d([1:1:m], MEANX)

endfunction

//*************************************************************
// Function to compute  the maximal fitness of a population
// for several generations
//
// Input:
// p := number of parameters between strings left and right (actually  p=5)
// l := length of strings
// n := number of elements in POP
// run := number of generations
// Output
// POP := a population
// FITNESS_ALL := Maximal Fitness of a population
// FITNESS_ALLX := Array with maximal fitness
// MEAN := Mean value of array

function[STD,MEAN, FITNESS_ALLX]=popMaxFitX(l,p,n,run)

MAXFITUP = ((2^l)^2)*n

for k=1:run
[POP]=popgen(n,l+p)

for j=1:n, v=POP(j,:),  [POP(j,l+1)]= vec2dec(v,l)
end

for i=1:n,[POP(i,l+2)]= fitness1(POP(i,l+1))
end

[FITNESS_ALLX(k)]=fitness(POP,l)

end

for k=1:run
FITNESS_ALLX(k)=FITNESS_ALLX(k)/(MAXFITUP/100)
end
MEAN = mean(FITNESS_ALLX)
mf=tabul(FITNESS_ALLX)
STD=stdevf(mf([:],1), mf([:],2))

// Show graphical results

//clf(), xdel,

//plot2d([1:1:run], MFITNESSX)

endfunction

//*************************************************************
// A system with GA without any additional parameters
//
// p := number of parameters between strings left and right (actually  p=5)
// l := length of strings ( actually l=5)
// n := number of elements in POP (actually n=4)
// POP := a predefined population (can be done automatically)
// N := number of cycles
// MThreshold := number of cycles which have to be waited until the mutation operators will be applied

function[FITNESS_ALL_PERC,POP]=ga(POP,l,p,n,N, MThreshold,show)

MCount = 0
FITNESS_ALLLOG=[]

for cyc = 1:N

[POP]=bin22dec(POP,l,show) //Convert binary string into integer

[POP]=fitnessComp1(POP,l,show)  // Compute fitness value with fitness1

[FITNESS_ALL]=fitness(POP,l,show) //Sum up all fitness values
FITNESS_ALLLOG(cyc)=FITNESS_ALL

[MFITNESS]=maxfitness(POP,l,show)// Find max fitness value

[POP,AFITNESS]=rfitness(POP,l,n,FITNESS_ALL,show) // Compute relative fitness values
//[POP]=newMember(POP,l,n) // Translates rfitness into integral fractions at l+p
[POP]= newPop0(POP,l,p,n,show) //Select only the positiv members, with multiple copies if necessary
[POP]= crossoverPrep(POP,l,p,n,show) //Prepare crossover by copying pairing candidates to the right
[POP]= crossover(POP,l,p,n,show) // Do crossover

if show==1 then
printf('Mutationcount = %d\n', MCount),
end

if(MCount > MThreshold) then
[POP]= mutation(POP,l,p,n),
if show==1 then  disp(POP),  end
MCount=0,
end

MCount = MCount + 1

end //for == N

printf("Number of Events n * N = %d\n",n*N)

// Compute the maximal value and the percentage of success

[MAXFIT]=maxfit02(l,n)
FITNESS_ALL_PERC=[]

for i=1:N, FITNESS_ALL_PERC(i) = FITNESS_ALLLOG(i)/(MAXFIT/100), end

// Show graphical results

if show==2 then
clf(), xdel,
plot2d([1:1:N], FITNESS_ALL_PERC),
end

endfunction

//*************************************************************
// GA algorithm with fitness and conditioned mutation
//
// Works like 'normal' GA but uses mutation only if the actual maximal fitness
// stays 'constant' over MT-many cycles and is below te theoretical maximum
//
// p := number of parameters between strings left and right (actually  p=5)
// l := length of strings ( actually l=5)
// n := number of elements in POP (actually n=4)
// POP := a predefined population (can be done automatically)
// N := number of events
// MT := mutation trigger; number of values to monitor for to trigger mutation

function[FITNESS_ALL_PERC,DIST2,STD, MEAN, FREQ,STD1, MEAN1, FREQ1,FX,POP]=ga1(POP,l,p,n,N, MT,show)

//Theoretical Maximum for Fitness according to y=x^2

TMaxFit = ((2^l)-1)^2*n

// Install the counters

r= (2^l)
c= 6

FX = zeros(r,c)

MCount = 0
FITNESS_ALLLOG=[]
MTriggerEstimator=[]

// Generate an internal index for display

for j=1:r
FX(j,1)=j-1
end

for cyc = 1:N

for j=1:n, v=POP(j,:),
d= vec2dec(v,l),  //decimal value
[POP(j,l+1)]= d,  //decimal value
FX(d+1,2)=FX(d+1,2)+1, //occurences
end

for i=1:n,[POP(i,l+2)]= fitness1(POP(i,l+1))
end

[FITNESS_ALL]=fitness(POP,l)
FITNESS_ALLLOG(cyc)=FITNESS_ALL

[MFITNESS]=maxfitness(POP,l)

if show ==1 then disp(FITNESS_ALL), end

MTriggerEstimator(cyc)=FITNESS_ALL

if show ==1 then disp(MTriggerEstimator(cyc)), end

[POP,AFITNESS]=rfitness(POP,l,FITNESS_ALL)

[POP]=newMember(POP,l,n)
[POP]=newPop(POP,l,p,n)
[POP]= crossoverPrep(POP,l,p,n)
[POP]= crossover(POP,l,p,n)

if show ==1 then disp(MCount),   end

if(MCount > MT) then

if show ==1 then disp(MTriggerEstimator(cyc)), disp(MTriggerEstimator(cyc-MT)), disp(TMaxFit), end
if (MTriggerEstimator(cyc) == MTriggerEstimator(cyc-MT) & MTriggerEstimator(cyc) < TMaxFit) then [POP]= mutation(
POP,l,p,n),
if show==1 then  disp(POP),  end
end
MCount=0,
end

MCount = MCount + 1

end //for == N

for j=1:r

FX(j,3)=(FX(j,2)/n)/N //Normal frequency
FX(j,4)=(FX(j,2)/n)/(((1/2^l)*N)/100) // Frequency as percentage
end//m

disp(FX)

FREQ1=tabul(FX(:,3))
MEAN1=mean(FREQ1(:,1))
STD1= stdevf(FREQ1(:,1), FREQ1(:,2))
FREQ=tabul(FX(:,4))
MEAN=mean(FREQ(:,1))
STD= stdevf(FREQ(:,1), FREQ(:,2))
MAX=max(FREQ(:,1))
MIN=min(FREQ(:,1))
DIST=MAX-MIN
DIST2=DIST/2

printf("Number of Events n * N = %d\n",n*N)
// Compute the maximal value and the percentage of success

[MAXFIT]=maxfit02(l,n)
FITNESS_ALL_PERC=[]

for i=1:N, FITNESS_ALL_PERC(i) = FITNESS_ALLLOG(i)/(MAXFIT/100), end

// Show graphical results

if show==2 then
clf(), xdel,
plot2d([1:1:N], FITNESS_ALL_PERC),
end

endfunction

//*************************************************************
// A system with GA for a world with a table
//
// A world W organized as a table  maps a set D into a set R
// l := length of strings
// p := number of cells between string <1...l> and <l+p+1, ..., l+p+l>
// Pos 1-l := String
// Pos l+1 := Decimal Value of binary string
// Pos l+2 := Fitness for l+1 and l+p
// Pos l+3 := Percentage of overall fitness
// Pos l+4 := Expected count according to fitness
// Pos l+5 := Realized count
// Pos l+6 := 2nd Decimal value of a compund fitness
// Pos l+p := flag for crossover
// p := 7
// POP := a predefined population (can be done automatically)
// n := number of elements in POP
// N := number of cycles
// MT := number of cycles which have to be waited until the mutation operators will be applied

function[FITNESS_ALL_PERC,POP]=gaw1(W,POP,l,p,n,N, MT,l1,show)

MCount = 0
FITNESS_ALLLOG=[]

for cyc = 1:N

if show == 1 then disp('cyc ='),disp(cyc),disp(' '),end

for j=1:n, v=POP(j,:),
d1= vec22dec(v,1,l1),  //decimal value1
d2= vec22dec(v,l1+1,l),  //decimal value2
[POP(j,l+1)]= d1,  //decimal value
[POP(j,l+6)]= d2,  //decimal value
end

if show == 1 then printf('New Numbers in POP '), disp(POP), end

for i=1:n,[POP(i,l+2)]= fitness2(POP(i,l+1),POP(i,l+6),W)
end

[FITNESS_ALL]=fitness(POP,l)

if show == 1 then printf('FITNESS_ALL = %f\n',FITNESS_ALL), end

FITNESS_ALLLOG(cyc)=FITNESS_ALL

[MFITNESS]=maxfitness(POP,l)

[POP,AFITNESS]=rfitness(POP,l,FITNESS_ALL)

if show == 1 then disp(POP), end

[POP]=newMember(POP,l,n)
[POP]=newPop2(POP,l,p,n)

if show == 1 then disp(POP), end

[POP]= crossoverPrep(POP,l,p,n)
[POP]= crossover(POP,l,p,n)

if show == 1 then disp(POP),printf('MCount = %d\n',MCount), end

if(MCount > MT) then
[POP]= mutation(POP,l,p,n), printf('Mutation at cycle = %d\n',cyc),
if show==1 then  disp(POP),  end
MCount=0,
end

MCount = MCount + 1

end //for == N

printf("Number of Events n * N = %d\n",n*N)

// Compute the maximal value and the percentage of success

MAXFIT=20*n   //The value '20' is set in the function fitness2()
FITNESS_ALL_PERC=[]

for i=1:N, FITNESS_ALL_PERC(i) = FITNESS_ALLLOG(i)/(MAXFIT/100), end

// Show graphical results

if show==2 | show == 1 then
clf(), xdel,
plot2d([1:1:N], FITNESS_ALL_PERC),
end

endfunction

//*************************************************************
// A system with GA for a world with a table and with
// multi-compartment genomes
//
// A world W organized as a table  maps a set D into a set R
// l := length of strings
// p := number of cells between string <1...l> and <l+p+1, ..., l+p+l>
// Pos 1-l := String
// Pos l+1 := Decimal Value of binary string
// Pos l+2 := Fitness for l+1 and l+p
// Pos l+3 := Percentage of overall fitness
// Pos l+4 := Expected count according to fitness
// Pos l+5 := Realized count
// Pos l+6 := 2nd Decimal value of a compund fitness
// Pos l+7 := flag for crossover
// p := 7
// POP := a predefined population (can be done automatically)
// n := number of elements in POP
// N := number of cycles
// MT := number of cycles which have to be waited until the mutation operators will be applied
// V := version

function[FITNESS_ALL_PERC,MAXGENOMECOUNT,POP,V]=gaw2(W,POP,l,n,N, MT,b,show,V)

p = 7
MCount = 0
FITNESS_ALLLOG=[]

for cyc = 1:N

if show == 1 then disp('cyc ='),disp(cyc),disp(' '),end

for i=1:n , v=POP(i,:), [D]= vec222dec(v,l,b,show),  [POP(i,l+2),goal]= fitness3(D,W),  end //for i

if show == 1 then printf('New Numbers in POP '), disp(POP), end

[FITNESS_ALL]=fitness(POP,l)

if show == 1 then printf('FITNESS_ALL = %f\n',FITNESS_ALL), end

FITNESS_ALLLOG(cyc)=FITNESS_ALL

[MFITNESS]=maxfitness(POP,l)

[POP,AFITNESS]=rfitness(POP,l,FITNESS_ALL)

// if show == 1 then disp(POP), end

[POP]=newMember(POP,l,n)

if show == 1 then disp(POP), end

[POP]=newPop2(POP,l,p,n)

if show == 1 then disp(POP), end

[POP]= crossoverPrep(POP,l,p,n)
[POP]= crossover(POP,l,p,n)

if show == 1 then disp(POP),printf('MCount = %d\n',MCount), end

if(MCount > MT) then
[POP]= mutation(POP,l,p,n), printf('Mutation at cycle = %d\n',cyc),
if show==1 then  disp(POP),  end
MCount=0,
end

MCount = MCount + 1

end //for == N

printf("Number of Events n * N = %d\n",n*N)

// Compute the maximal value and the percentage of success

[r,c]=size(POP)
[r2,c2]=size(W)

MAXFIT=goal*r2*r //The value 'goal' is set in the function fitness3()
MAXFITGENOME = goal*r2  // To count the complete genomes in a population
FITNESS_ALL_PERC=[]

MAXGENOMECOUNT = 0
for i=1:r,
if POP(i,l+2) == MAXFITGENOME then MAXGENOMECOUNT =MAXGENOMECOUNT+1, end,
end
for i=1:N, FITNESS_ALL_PERC(i,1)=i, FITNESS_ALL_PERC(i,2) = FITNESS_ALLLOG(i)/(MAXFIT/100), end

// Show graphical results

if show==2 | show == 1 then
clf(), xdel,
scf(V),
plot2d([1:1:N], FITNESS_ALL_PERC(:,2)),
end

endfunction

//*************************************************************
// Computing the worst case convergence time tcw
//
// p := number of parameters between strings left and right (actually  p=5)
// l := length of strings ( actually l=5)
// n := number of elements in POP (actually n=4)
// POP := a predefined population (can be done automatically)
//
// f1 := fitness of all individuals with a allele value '1' at a position
// f0 := fitness of all individuals with a allele value '0' at a position
// r = f1/f0
// tcw := worst case convergence time
//
// Assumption: POP has the relativ fitness available at l+3

function[POP,tcw,tcabin,ratio,f1,f0]=ftcw2(W,POP,l,p,n,l1,show)

for j=1:n, v=POP(j,:),
d1= vec22dec(v,1,l1),  //decimal value1
d2= vec22dec(v,l1+1,l),  //decimal value2
[POP(j,l+1)]= d1,  //decimal value
[POP(j,l+6)]= d2,  //decimal value
end

for i=1:n,[POP(i,l+2)]= fitness2(POP(i,l+1),POP(i,l+6),W)
end

[FITNESS_ALL]=fitness(POP,l)

[MFITNESS]=maxfitness(POP,l)

[POP,AFITNESS]=rfitness(POP,l,FITNESS_ALL)

[POP,ratio,f1,f0]=fratio10(POP,l,show)

tcw = log((n-1)^2)/log(ratio)
tcabin = log(n-1)/log(ratio)

endfunction

//***********************************************************************
// Examples
//
POP1 = [0 1 1 0 1 0 0 0 0 0; 1 1 0 0 0 0 0 0 0 0; 0 1 0 0 0  0 0 0 0 0; 1 0 0 1 1 0 0 0 0 0;]
POP = [0 1 1 0 1; 1 1 0 0 0; 0 1 0 0 0; 1 0 0 1 1;]

P205 =[0 0; 0 1]
P250 = [1 1; 0 0]
P272 = [1 1; 1 0]

P306 = [0 0 1; 0 1 0; 0 1 0]
P345 = [0 1 1; 0 1 1; 1 1 1]
P373 = [1 1 0; 1 1 0; 1 1 0]

W=[1 3; 2 1; 3 2]

W2=[1 3; 2 1; 3 2; 4 4; 5 7; 6 5]
```

Gerd Doeben-Henisch 2014-01-14