I have to implement a genetic algorithm in R to optimize the minimum of the Schaffer function. Below I describe each step and I need to create one big function and another loop for 100 iterations (and from 100 iterations choose the best solution) for the Schaffer function. I would be grateful for any tips, where and how I can make a loop and implement everything in one function.
#1. create the size of population - constant
N <- 100
population <- matrix(runif(N*2,min=-100,max=100), N, 2)
#2. count schaffer function - y for each element of population
schaffer_mod <- function(xx,N) {
x1 <- xx[1:N,1]
x2 <- xx[1:N,2]
fact1 <- (sin(x1^2-x2^2))^2 - 0.5
fact2 <- (1 + 0.001*(x1^2+x2^2))^2
y <- 0.5 + fact1/fact2
return(y)
}
y <- schaffer_mod(population,100)
newpopulation <- cbind(population,y)
# 3. sort to achieve best solution (value of y) at the top
newpopulation.sort <- newpopulation[order( newpopulation[,3]),]
# 4. choose the best 20% of solutions - by the best y
parents <- newpopulation.sort[1:20,1:2] #drop y value
# 5.CROSSING
#random choose the number of raws to take
raw1 <- sample(1:20,100, replace=T)
raw2 <- sample(1:20,100, replace=T)
#average from crossing parents
child1 <- (parents[raw1,1]+parents[raw2,2])/2
child2 <- (parents[raw1,2]+parents[raw2,1])/2
newpopulation <- matrix(c(child1,child2),100,2)
# 6. MUTATION
#choose random 20raws <- it this point I have to implement a loop, but do not know how I can do it correctly
gen20_1 <- sample(1:100,20)
gen20_2 <- sample(1:100,20)
child_gen20_1 <- matrix((newpopulation[gen20_1,1]),20,1)
child_gen20_2 <- matrix((newpopulation[gen20_2,1]),20,1)
# choose random which line to choose
# first operations of counting on first column - first child
nr1 <- sample(1:20,1)
mutation_value <- -100+runif(1)*200
a1 <- child_gen20_1[nr1,1] + mutation_value
if ((a1 > -100) && a1 < 100) #if its true, change the value in the matrix-newpopulation
{
newpopulation[nr1,1] <- newpopulation[nr1,1]+mutation_value
}
# FOR THE SECOND COLUMN - SECOND CHILD
nr2 <- sample(1:20,1)
mutation_value <- -100+runif(1)*200
a2 <- child_gen20_2[nr2,1] + mutation_value
if ((a2 > -100) && a2 < 100)
{
newpopulation[nr2,2] <- newpopulation[nr2,2]+mutation_value
}
#mutation should be counted 20 times for each column. would be grateful to advice, how I should create a loop
#7. new population after mutation
population <- newpopulation
#8. new y
y <- schaffer_mod(populacja,100)
population <- cbind(population,y)
#9. sort
newpopulation.sort <- population[order(population[,3]),]
#10. result
x1 = newpopulation.sort[1,1]
x2 = newpopulation.sort[1,2]
y = newpopulation.sort[1,3]
The aim is to make these 10 steps x100 times and choose x1,x2 for which y was the smallest one - searching for the minimum of the Schaffer function.