library(GA)
source("NaK.R")
set.seed(123)

Estremi del range dei due parametri (x=malto,y=luppolo)

range1x<-50
range2x<-100
range1y<-10
range2y<-20

Cambio di segno la funzione NaK questo passaggio è necesario perchè l’algoritmo GA di default massimizza la funzione inputata.

f2 <- function(x)  -NaK(x[1],x[2])

Metodo GA

Il GA è un metodo di ottimizzazione basato sull’evoluzione genetica, che utilizza concetti evolutivi come la selezione naturale, la riproduzione e la mutazione per generare una popolazione di soluzioni iniziali, valutare la loro “idoneità” attraverso una funzione di fitness e produrre una nuova generazione di soluzioni. L’obiettivo è trovare una soluzione che ottimizzi la funzione di fitness.

Nel nostro caso, l’obiettivo è trovare il valore minimo di f2 all’interno dei limiti specificati utilizzando un’algoritmo genetico con una popolazione iniziale di 100 individui e un massimo di 1.000 iterazioni. L’oggetto risultante GA conterrà informazioni sull’ottimizzazione eseguita.

Nel codice, la funzione ga() viene utilizzata per eseguire l’algoritmo genetico.

La funzione prende in input i seguenti argomenti:

GA <- ga(type = "real-valued", 
         fitness = f2,
         lower = c(range1x, range1y), upper = c(range2x, range2y), 
         popSize = 100, maxiter = 1000, run = 200,monitor=FALSE)

Output funzione GA

Il risultato dell’esecuzione della funzione ga è un oggetto di classe “ga” contenente informazioni sull’ottimizzazione, come il valore ottimo della funzione di fitness, i valori ottimali delle variabili, il numero di iterazioni eseguite e altri dettagli sulla convergenza dell’algoritmo.

summary(GA)
## ── Genetic Algorithm ─────────────────── 
## 
## GA settings: 
## Type                  =  real-valued 
## Population size       =  100 
## Number of generations =  1000 
## Elitism               =  5 
## Crossover probability =  0.8 
## Mutation probability  =  0.1 
## Search domain = 
##        x1 x2
## lower  50 10
## upper 100 20
## 
## GA results: 
## Iterations             = 254 
## Fitness function value = -29.46 
## Solution = 
##            x1       x2
## [1,] 82.17417 11.36677

Il GA utilizza una popolazione di 100 individui e viene eseguito per 1.000 generazioni. Il parametro “elitism” imposta il numero di migliori individui conservati da una generazione all’altra, in questo caso 5. La probabilità di crossover è dell 80% e quella di mutazione è del 10%. Il risultato del GA restituisce il valore minimo della funzione, pari a 29.46 (in modulo), e la soluzione corrispondente in cui le variabili “x1” e “x2” (Malto e Luppolo rispettivamente) assumono i valori di 82.17 e 11.37.

Grafico della funzione di ottimo

plot(GA)

Nel grafico la riga continua rappresenta il valore della funzione di fitness migliore ad ogni generazione, si può notare come arrivi al suo valore massimo in poche generazioni e poi si stabilizzi.

I punti blu forniscono il valore della media del valore della fitness ad ogni generazione (fatta su tutta la popolazione di 100 individui) la soluzione non risulta particolarmente stabile, si registra un ampio range di variazione e non vi è una convergenza verso la linea che rappresenta l’ottimo. Anche dall’area verde chiara, che rappresenta la mediana della funzione, si può notare la mancata convergenza della fitness verso un valore di minimo stabile,p iù della metà dei punti variano in un range distante dal valore di ottimo.

Ci si può attendere che in una diversa iterazione dell’algoritmo giungeremo ad un risultato differente.