La parte di definizione della funzione di Loss e di creazione del dataframe è in comune con l’algoritmo precedente
source("birra.R")
input=c(runif(1,50,100),runif(1,10,20))
output=birra(input)
L=output[1]+output[2]
parametri<-c(input[1],input[2],output[1],output[2],L)
nomi_col<-c("Malto","Luppolo","Sodio","Potassio","L")
df=data.frame()
Questo algoritmo è una variazione dell’algoritmo di ricerca dell’ottimo Random Blind Search.
La differenza principale rispetto al codice precedente sta nel fatto che, prima di chiamare la funzione birra sull’input casuale, vengono eseguite alcune operazioni di aggiustamento sull’input stesso.
Alla prima riga del ciclo for, viene generato un vettore d contenente due numeri casuali campionati dalla distribuzione normale con media 0 e deviazione standard specificata,5 e 1 rispettivamente, pari al 10% del range di variazione delle due variabili di input. Successivamente, il vettore di input casuale input1 viene calcolato come la somma di input e d.
Per evitare che il nuovo input generato esca dai limiti specificati, il codice controlla se i valori del nuovo input input1 sforano i limiti massimo e minimo di ogni variabile. Se è così, viene impostato il valore di input1 sul valore massimo o minimo consentito.
In seguito, viene valutata 30 volte la somma dei primi due elementi dell’output della funzione birra per l’input input1 e ne calcola la media. Questa media viene assegnata alla variabile L1. Se il valore di L1 è inferiore al valore di L trovato in precedenza, allora i parametri vengono aggiornati con i valori del nuovo input, dell’output e del valore di L1.
Infine viene creato un nuovo vettore di parametri
parametri contenente i valori dei due input i due
output e la loro somma L (Loss Function) , e
lo aggiunge a un data frame df utilizzando la funzione
rbind. Questo processo viene ripetuto per 1000
iterazioni.
for (i in c(1:1000)){
d<-c(rnorm(1,0,5),rnorm(1,0,1))
input1<-input+d
#aggiusto se sforo dal range
input1[1]<-max(50,input1[1])
input1[1]<-min(100,input1[1])
input1[2]<-max(10,input1[2])
input1[2]<-min(20,input1[2])
#valuto 30 volte la loss e faccio la media
LL<-numeric()
output1=birra(input1)
for (k in c(1:30)){
LL[k]<-output1[1]+output1[2]
}
L1<-mean(LL)
if (L1<L){
input=input1
output=output1
L<-L1
}
parametri<-c(input[1],input[2],output[1],output[2],L)
df=rbind(df,parametri)
}
colnames(df)=nomi_col
Statistiche di sintesi
summary(df)
## Malto Luppolo Sodio Potassio
## Min. :50.00 Min. :10.00 Min. :3.035 Min. :26.44
## 1st Qu.:55.60 1st Qu.:10.00 1st Qu.:3.035 1st Qu.:26.45
## Median :59.25 Median :10.14 Median :3.158 Median :26.76
## Mean :58.61 Mean :10.75 Mean :3.338 Mean :26.81
## 3rd Qu.:60.23 3rd Qu.:10.64 3rd Qu.:3.634 3rd Qu.:26.76
## Max. :67.31 Max. :17.87 Max. :4.974 Max. :29.95
## L
## Min. :29.56
## 1st Qu.:29.61
## Median :29.80
## Mean :30.15
## 3rd Qu.:30.47
## Max. :34.65
tail(df,n=1)
## Malto Luppolo Sodio Potassio L
## 1000 53.18429 10.5698 3.119529 26.44204 29.56157
plot(df$L,type="h",col="darkblue",main="Funzione di Loss",xlab="Iterazioni",ylab="Sodio+Potassio")