# GA_v3.sce

```//**************************************************************
// File:GA_v3.sce
// Authors: Gerd Doeben-Henisch
// Version Start: January-18, 2010
// Version Last: April-3, 2011
//******************************************************************
// Function: Implements a simple GA according to Goldberg (1989)
//            Without Mutation!
//
//****************************************************************
// SW-STRUCTURE
//
// All data are organized in a dynamical table. Left hand the actual genes, in the  middle
// supporting parameters and to the right intermediate modifications of the genes to the left.
//
//***************************************************
// POP FORMAT
// l := length of strings
// Pos 1-l := String
// Pos l+1 := Decimal Value of binary string
// Pos l+2 := Fitness
// Pos l+3 := Percentage of overall fitness
// Pos l+4 := Expected count according to fitness
// Pos l+5 := Realized count

POP = [0 1 1 0 1 13 169 0 0 0; 1 1 0 0 0 24 576 0 0 0; 0 1 0 0 0  8 64 0 0 0; 1 0 0 1 1 19 361 0 0 0;]

// Variable for overall Fitness

FITNESS_ALL = 0

// Variable for average Fitness

AFITNESS = 0

//***************************************************
//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)

FITNESS_ALL=0;
[r,c]=size(POP);
for j=1:r
FITNESS_ALL=FITNESS_ALL+POP(j,l+2)
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)

MFITNESS=0
[r,c]=size(POP);
for j=1:r
if POP(j,l+2) > MFITNESS then MFITNESS = POP(j,l+2)
end
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

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

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

AFITNESS=FITNESS_ALL/r

endfunction

//***************************************************
//Function to compute the relative count of a string
// along with the realized new count by 'rounding up'
// Compute all the l+4 and l+5-th positions
// l := length of fitness strings
// n :=  number of individuals in POP

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

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
// k := row_new
// p := number of parameters (P=5)

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

[r,c]=size(POP);

// Testing the boundaries

if (j < 1) then printf('ERROR: Position of old String outside of Matrix! r = %d, j = %d', r,j)
elseif  (j > r) then printf('ERROR: Position of old String outside of Matrix!, r = %d, j = %d', r,j)
elseif (k < 1) then printf('ERROR: Position of new String outside of Matrix!, r = %d, k = %d', r,k)
elseif (k > r) then printf('ERROR: Position of new String outside of Matrix!, r = %d, k = %d', r,k)
end

// Making a copy

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

endfunction

function[POP]=strcpyRL(POP,l,p,j,k)

[r,c]=size(POP);

// Testing the boundaries

if (j < 1) then printf('ERROR: Position of old String outside of Matrix! r = %d, j = %d', r,j)
elseif  (j > r) then printf('ERROR: Position of old String outside of Matrix!, r = %d, j = %d', r,j)
elseif (k < 1) then printf('ERROR: Position of new String outside of Matrix!, r = %d, k = %d', r,k)
elseif (k > r) then printf('ERROR: Position of new String outside of Matrix!, r = %d, k = %d', r,k)
end

// Making a copy

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

endfunction

//***************************************************
// Make a copy of all strings from the old rows to the new ones
// where the new copies will start at position l+p+1
// l := length of string
// j := row_old
// k := row_new
// p := number of parameters (p=5)
// r2 := memory of position for new strings

function[POP]= newPop(POP,l,p,n)

[r,c]=size(POP);
r2 = 1

for j=1:r

if POP(j,l+p) > 0 then r3 = POP(j,l+p)-1,

for k=r2:(r2+r3), //printf('\n k = %d\n', k)
[POP]=strcpyLR(POP,l,p,j,k)
end

r2=k+1

end
end

endfunction

//***************************************************
// Prepare the crossover operations within a population POP
// by randomly selecting the new strings and copy them onto the
// POP base area from position 1 - l
//
// General Assumption: the number of members n is even!!!
//
// The strings are assumed to be in the area starting at l+p+1
// The parameter at l+p has been changed to a flag '1' := not yet mated
// j := target position in the base area for copy action

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

[r,c]=size(POP);

// Set a flag at position l+p with '1'

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

// Select randomly the strings for transfer

j = 1 //:= Baseline for filling up with strings

while(j < n+1)

S = 1 //:= Flag for searching a string to be copied

while(S == 1)

k1 = round(n * rand())
if k1==0 then k1=1
end

printf('k1 = %d\n',k1)

if POP(k1,l+p) <> 0 then POP=strcpyRL(POP,l,p,j,k1)
//mshow(POP,n,l+p+l)
POP(k1,l+p) = 0,
S=0
else S=1
end

end
j = j+1
// mshow(POP,n,l+p+l)

printf('j = %d\n',j)

end

endfunction

//***************************************************
// Apply a crossover operation onto two adjacent strings at intersection x
// The strings are assumed to be randomly paired in the area at position 1
//

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

[r,c]=size(POP);

j=1

while(j < n+1)

// printf('j = %d\n',j)

x = round(l * rand())
if x == 0 then x=1  // This does not change anything
end
// printf('x = %d\n',x)

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

j=j+2
end

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]= vec2dec(v,l)

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

endfunction

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

function[F]= fitness1(D)

F=D^2

endfunction

//*************************************************************
// All Functions Unified
//
// 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)
// popge := a predefined population (can be done automatically)
// run := number of cycles

function[POP,FITNESS_ALLLOG]=gasimple(POP,l,p,n,run)

FITNESS_ALLLOG=[]

for cyc = 1:run

[M]= mshow(POP,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_ALL]=fitness(POP,l)
FITNESS_ALLLOG(cyc)=FITNESS_ALL

[MFITNESS]=maxfitness(POP,l)

[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)

end

clf(), xdel, plot2d([1:1:run], FITNESS_ALLLOG)

endfunction
```

Gerd Doeben-Henisch 2013-01-14