Algoritmi genetici e programmazione genetica

annuncio pubblicitario
Scuola Politecnica e delle Scienze di Base
Corso di Studi in Ingegneria Informatica
tesi di laurea in Intelligenza artificiale
Algoritmi genetici e
programmazione genetica
Anno Accademico 2015/2016
relatore
Ch.mo prof. Carlo Sansone
candidato
Pierluigi Filosa
matr. N46/1180
Alla mia famiglia, per aver creduto in me ed essere stati guida e stimolo per la mia
crescita personale e professionale.
Indice
Introduzione
1
1
Algoritmi genetici
1.1 L’algoritmo genetico di J. H. Holland . . . . . . . . . . . . . . . . . . . . . . .
1.2 Operazioni genetiche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3 Come funzionano gli AG? Il teorema degli schemi . . . . . . . . . . . . . . . . .
2
2
3
6
2
Programmazione genetica
2.1 Terminal set e Function set . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.2 Inizializzazione della popolazione . . . . . . . . . . . . . . . . . . . . . . . . .
2.3 Operazioni genetiche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9
9
11
12
3
Un esempio di programmazione genetica
3.1 Fasi preparatorie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2 Esecuzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
14
14
16
4
TinyGP
4.1 Caratteristiche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.2 Input data files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.3 Compilazione ed esecuzione . . . . . . . . . . . . . . . . . . . . . . . . . . . .
19
19
20
21
Conclusioni
23
Bibliografia
24
I
Introduzione
Gran parte dei problemi trattati dall’intelligenza artificiale consistono nella ricerca di un massimo
o minimo globale in uno spazio ricerca limitato. Spesso le tecniche esatte di risoluzione non sono
in grado di espletare soluzioni in tempi ragionevoli; per tale motivo, per questo particolare tipo
di problemi, risultano più efficienti algoritmi di tipo euristico [8]. Gli algoritmi genetici e la programmazione genetica rientrano nella famiglia degli algoritmi evolutivi: un insieme di tecniche
euristiche in grado di risolvere problemi di ricerca globale imitando i processi di selezione ed evoluzione naturale. Questi algoritmi si basano sul principio darwiniano secondo cui gli individui più
“adatti” all’ambiente hanno più probabilità di sopravvivere e di trasmettere i propri caratteri alle
generazioni successive.
Introdurremo, inizialmente, gli aspetti fondamentali di un algoritmo genetico, per poi trattare nel dettaglio il modello di algoritmo genetico proposto da J. H. Holland. Seguirà una breve
panoramica sulle operazioni genetiche, un insieme di tecniche che permettono l’imitazione del
processo evolutivo, per poi concludere con una piccola trattazione matematica sul funzionamento degli algoritmi genetici. Successivamente ci concentreremo in maniera più approfondita sulla
programmazione genetica, descrivendo gli aspetti chiave e le caratteristiche principali di questa
tecnica. Negli ultimi due capitoli tratteremo due esempi di programmazione genetica. Il primo
sarà un semplice esempio illustrativo di regressione simbolica, nel quale verranno evidanziate le
fasi preparatorie atte a specificare gli ingredienti che il processo evolutivo utilizzerà per la generazione di soluzioni, nonché il processo di evoluzione stesso. Infine nell’ultimo capitolo descriveremo in maniera sintetica un sistema di programmazione genetica reale, TinyGP, sviluppato e
implementato da Riccardo Poli.
1
Capitolo 1
Algoritmi genetici
Gli algoritmi genetici (AG) sono algoritmi di ricerca euristici ispirati al principio della selezione
naturale ed evoluzione biologica teorizzato da Charles Darwin nel 1895. L’obiettivo degli AG
è quello di trovare una soluzione ottimale di un determinato problema di ricerca, simulando le
meccaniche che governano l’evoluzione biologica e la riproduzione sessuale presenti in natura.
La ricerca parte da una popolazione iniziale di individui, detti cromosomi, che rappresentano
ipotetiche soluzioni al problema dato. Ogni individuo della popolazione è codificato in una stringa
composta da simboli di un alfabeto finito, detti geni, dove ogni gene rappresenta un’istanza di un
particolare simbolo del suddetto alfabeto, detto allele. Alla pari del processo evolutivo biologico,
nel contesto degli AG, la popolazione iniziale di individui evolve dando origine ad una nuova
generazione caratterizzata da individui tendenzialmente “migliori” della precedente in termini di
adattabilità all’ambiente, ovvero che risolvono più efficacemente il problema di ricerca dato. Tale
processo si protrae fino al raggiungimento di un criterio di terminazione prestabilito.
1.1
L’algoritmo genetico di J. H. Holland
Il primo prototipo di algoritmo genetico fu proposto da J.H. Holland nei primi anni ’60 al fine di
implementare i meccanismi di adattamento naturale nei sistemi informatici. L’algoritmo genetico
di Holland prevede una popolazione di N cromosomi di lunghezza prefissata L codificati in codice
binario. L’insieme di tutti i possibili cromosomi rappresenta lo spazio di ricerca, ovvero lo spazio che l’algoritmo esplora durante il processo di ricerca, formato al massimo da 2L cromosomi.
Supponiamo di avere un problema codificato con L = 3 bit: lo spazio di ricerca del problema sarà
2
Scuola Politecnica e delle Scienze di Base – Corso di Studi in Ingegneria Informatica
Algoritmi genetici e programmazione genetica
Figura 1.1: Esempio di spazio di ricerca con L = 3.
composto al massimo da 8 cromosomi, rappresentabile geometricamente come un cubo (Figura
1.1).
L’algoritmo genetico formulato da Holland funziona come descritto a seguire. Inizialmente
viene generata, in maniera casuale, una popolazione iniziale di N individui di lunghezza L. Ogni
singolo individuo della popolazione Ci (i = 1, ..., N) viene valutato mediante una funzione di fitness f , la quale restituisce un valore fi , per l’appunto la fitness, proporzionale alla capacità del
cromosoma di risolvere il problema dato. L’algoritmo genera iterativamente una nuova popolazione di N individui (rimpiazzando completamente quella precedente) applicando alla generazione
corrente le operazioni genetiche fino al soddisfacimento di un criterio di terminazione prestabilito:
questo può essere un numero massimo di generazioni (iterazioni massime dell’algoritmo) Gmax ,
oppure il raggiungimento di un valore di fitness accettabile per il problema dato. In figura 1.2 è
riportato un diagramma di flusso che sintetizza il ciclo di vita di un tipico algoritmo genetico.
1.2
Operazioni genetiche
Darwin, osservando le differenze fra specie affini viventi nelle diverse isole dell’Arcipelago delle
Galápagos, si convinse che la lenta modificazione delle specie - la loro evoluzione - era dovuta
principalmente alla selezione naturale: sopravvivono e si riproducono, cioè, gli individui dotati di
caratteristiche più vantaggiose nella lotta per l’esistenza (in sostanza, meglio adattati all’ambiente)
[7]. Analogamente, un algoritmo genetico seleziona i candidati che contribuiranno alla creazione
della nuova generazione in base ai loro valori di fitness, premiando tendenzialmente quelli dotati
3
Scuola Politecnica e delle Scienze di Base – Corso di Studi in Ingegneria Informatica
Algoritmi genetici e programmazione genetica
Figura 1.2: Diagramma di flusso di un tipico algoritmo genetico. Le quantità pr , pc , e pm indicano, rispettivamente, le
probabilità di riproduzione, crossover e mutazione. [4].
di fitness più alta. La probabilità di selezione del generico cromosoma Ci è data da
fi
pi =
n
∑ fk
k=1
Tale logica di selezione è denominata selezione proporzionale alla fitness oppure selezione a
roulette. Supponiamo di avere una popolazione composta da N = 5 individui con rispettive fitness
f1 = 6.82, f2 = 1.11, f3 = 8.48, f4 = 2.57, f5 = 3.08. Ogni individuo occupa uno spicchio
della roulette proporzionale al suo valore di fitness e, dunque, alla sua probabilità di selezione.
L’algoritmo genera un numero casuale compreso nell’intervallo [0, 1) , il quale individua uno
4
Scuola Politecnica e delle Scienze di Base – Corso di Studi in Ingegneria Informatica
Algoritmi genetici e programmazione genetica
Figura 1.3: Selezione a roulette [2].
spicchio di roulette corrispondente all’individuo che verrà selezionato. La roulette per questo
esempio assumerà la forma in figura 1.3.
Un’ulteriore logica di selezione, particolarmente diffusa nella programmazione genetica, è la
selezione a torneo. Si scelgono casualmente due individui dalla popolazione e si genera un numero casuale r ∈ [0, 1] . Se r < k, dove k ∈ [0, 1] è un parametro prefissato, si seleziona l’individuo
con fitness più alta, altrimenti quello con fitness più bassa. Infine, i due individui vengono reinseriti nella popolazione iniziale, pronti per essere eventualmente scelti per un altro torneo [3].
L’operazione di riproduzione consiste semplicemente nel copiare cromosomi dell’attuale popolazione, precedentemente selezionati, nella generazione successiva.
L’operazione di crossover (Figura 1.4, v. pag. 6), nella sua variante più semplice, detta
crossover a un punto, coinvolge due cromosomi genitori C1 e C2 e, dopo la scelta casuale di una
posizione (o locus), detta punto di crossover, consiste in uno scambio di geni che dà origine a
due nuovi cromosomi figli a partire dai due cromosomi genitori. In tale accezione il primo figlio,
C3 , eredita i primi k geni del genitore C1 e gli ultimi L − k geni del genitore C2 . Viceversa, il
secondo figlio, C4 , eredita i primi k geni del genitore C2 e gli ultimi L − k geni del genitore C1 .
L’operazione di crossover appena descritta avviene alla stregua della ricombinazione biologica tra
due organismi aploidi1 .
L’operazione di mutazione (Figura 1.5, v. pag. 7) consiste nell’invertire il valore di un singolo
gene, scelto casualmente, di un cromosoma selezionato. Secondo Holland [1], lo scopo dell’operazione di mutazione è quello di garantire la diversità di un dato gene all’interno della popolazione.
1 Organismi
caratterizzati da un corredo cromosomico costituito da un singolo cromosoma.
5
Scuola Politecnica e delle Scienze di Base – Corso di Studi in Ingegneria Informatica
Algoritmi genetici e programmazione genetica
Figura 1.4: Esempio di crossover.
Per esempio, senza mutazione, ogni cromosoma della popolazione potrebbe avere come primo
gene un “1” , e potrebbe non esserci alcun modo di ottenere un cromosoma con uno “0” nel primo
gene.
1.3
Come funzionano gli AG? Il teorema degli schemi
Holland affermava che gli AG operano esplorando, enfatizzando e ricombinando buoni blocchi
costituenti (combinazioni di bit che conferiscono alti valori di fitness alle stringhe in cui essi sono
presenti) di soluzioni in maniera altamente parallela. L’idea di base è che buone soluzioni sono
tendenzialmente formate da buoni blocchi costituenti. Holland introdusse la nozione di schema
per formalizzare la nozione informale di blocchi costruttori [3]. Un esempio di schema è il piano
frontale del cubo in figura 1.1 (v. pag. 3), ovvero tutte le stringhe di lunghezza L = 3 che hanno
come secondo gene il valore “1”, ovvero: 111,110,011,010. È possibile descrivere tale sottoinsieme dello spazio di ricerca mediante la notazione compatta H = ∗1∗2 . Possiamo allora definire
uno schema come l’insieme di tutte le stringhe ottenibili sostituendo al posto del simbolo * gli
altri elementi dell’alfabeto di codifica, lasciando invariati i bit definiti.
Si definisce ordine di uno schema H, indicato con o(H), il numero di bit definiti all’interno
dello schema stesso.
Si definisce lunghezza di uno schema H, indicato con d(H), la distanza tra il primo e l’ultimo
bit definito. Per esempio lo schema H = 1 ∗ ∗ ∗ ∗1 è di ordine 2 ed ha lunghezza 5.
Ogni stringa di bit di lunghezza L è un’istanza di 2L schemi differenti. Per esempio, la stringa
“11” è un’istanza degli schemi H1 = ∗∗, H2 = 1∗, H3 = ∗1 e H4 = 11. Quindi, una popolazione
2 H sta per “hyperplane” (iperpiano), in quanto gli schemi definiscono iperpiani nello spazio L-dimensionale delle
stringhe di L bit [3].
6
Scuola Politecnica e delle Scienze di Base – Corso di Studi in Ingegneria Informatica
Algoritmi genetici e programmazione genetica
Figura 1.5: Esempio di mutazione.
di N individui, con1 ≤ N ≤ 2L , è caratterizzata da istanze di un numero di schemi compreso tra
2L e N2L . Di conseguenza, l’algoritmo genetico, pur valutando esplicitamente la fitness di soli
N individui, in realtà elabora implicitamente la fitness media3 di un numero molto maggiore di
schemi. Tale caratteristica degli AG è chiamata parallelismo implicito.
Consideriamo ora gli effetti che apportano le operazioni genetiche alle istanze degli schemi,
trattando in primis l’operazione di selezione. Sia m(H,t) il numero di istanze dello schema H
al tempo t e Û (H,t)la fitness media dello schema H al tempo t. Indichiamo, infine, con f¯ (t)la
fitness media dell’intera popolazione. Il numero atteso di istanze di H al tempo t + 1 è dato dalla
seguente equazione
E (m (H,t + 1)) = m (H,t)
Û (H,t)
f¯ (t)
La precedente equazione afferma che, se la fitness media di uno schema è maggiore della fitness media dell’intera popolazione, allora il numero di istanze dello schema H al tempo t + 1 è
aumentato.
Consideriamo ora gli effetti del crossover e della mutazione. Sia pc la probabilità di crossover
a singolo punto su un cromosoma, supponiamo inoltre che un’istanza dello schema H sia selezionata come cromosoma genitore. Si dice che lo schema H “sopravvive” al crossover se uno dei
discendenti è anch’esso un’istanza di H. Possiamo definire la probabilità di sopravvivenza di uno
schema H al crossover a singolo punto mediante la seguente formula
Sc (H) ≥ 1 − pc
d (H)
L−1
Dunque gli schemi più piccoli (in termini di lunghezza) hanno più probabilità di sopravvivenza.
Sia pm la probabilità di mutazione di un bit di un cromosoma. Uno schema H “sopravvive” all’operazione di mutazione se tutti i o(H) bit fissi restano invariati. Possiamo definire la probabilità
di sopravvivenza di uno schema H all’operazione di mutazione come
3 Con
fitness media di uno schema H indichiamo la media delle fitness di tutte le possibili istanze del dato schema.
7
Scuola Politecnica e delle Scienze di Base – Corso di Studi in Ingegneria Informatica
Algoritmi genetici e programmazione genetica
Sm (H) = (1 − pm )o(H)
Dunque gli schemi con ordine più basso hanno più probabilità di sopravvivenza.
Unendo i contributi di tutti gli operatori genetici ricaviamo la seguente relazione, nota come
teorema degli schemi :
Û (H,t)
d (H)
E (m (H,t + 1)) ≥ m (H,t) ¯
1 − pc
(1 − pm )o(H)
L−1
f (t)
Essa descrive la crescita di uno schema di generazione in generazione: schemi di piccola lunghezza, di basso ordine e con fitness media al di sopra della media riceveranno un aumento esponenziale
di istanze nel tempo [3].
8
Capitolo 2
Programmazione genetica
La programmazione genetica (PG), elaborata principalmente ad opera di John R. Koza, è un
metodo per la generazione automatica di programmi in grado di risolvere un determinato problema a partire da una descrizione di alto livello di quest’ultimo. Analogamente a quanto visto
con gli algoritmi genetici, si tratta di un processo casuale che non garantisce un risultato perfetto,
bensì un risultato ottimale che rispetti determinati criteri prefissati dall’utente. La PG è di fatto
un’estensione degli algoritmi genetici, dove gli individui della popolazione sono programmi, tipicamente espressi come alberi sintattici. Per esempio in figura 2.1 è mostrata la struttura ad albero
del programma max (x + x, x + 3 ∗ y).
2.1
Terminal set e Function set
Le unità basilari per il processo di creazione dei programmi sono i terminali e le funzioni. L’insieme dei terminali, il quale comprende gli input, le costanti e le funzioni senza argomento dei
programmi da generare, è detto terminal set. Il programma in figura 2.1 è composto da due input
(x e y), una costante (5) e da nessuna funzione senza argomento. In analogia alla struttura ad albero dei programmi, gli elementi appartenenti al terminal set rappresentano i nodi foglia dell’albero
stesso.
L’insieme delle funzioni è detto function set. La scelta del function set per un problema di PG
è strettamente correlato al dominio del problema da risolvere. La gamma delle funzioni disponibili
è molto ampia, trattandosi a tutti gli effetti di un problema di programmazione, e può comprendere:
funzioni booleane, operazioni aritmetiche, strutture di controllo iterative, subroutine generiche etc.
9
Scuola Politecnica e delle Scienze di Base – Corso di Studi in Ingegneria Informatica
Algoritmi genetici e programmazione genetica
Figura 2.1: Esempio di struttura ad albero del programma max (x + x, x + 3 ∗ y) [5]
[5]. In analogia alla struttura ad albero dei programmi, gli elementi appartenenti al function set
rappresentano i nodi intermedi dell’albero stesso. L’unione di terminal set e function set è detto
primitive set.
Il terminal set ed il function set dovrebbero essere scelti in maniera tale da soddisfare i requisiti
di chiusura e sufficienza [4]. La proprietà di chiusura richiede che ogni funzione del function set
sia in grado di accettare ed elaborare ogni valore e tipo di dato appartente al terminal set, nonché
ogni valore e tipo di dato elaborato dalle funzioni del function set. Tale proprietà è indispensabile poiché le funzioni appartenenti al terminal set potrebbero fallire a tempo di esecuzione[5].
L’esempio classico di funzione che non soddisfa la proprietà di chiusura è la divisione, la quale non può accettare come secondo input lo 0. Per ovviare a tale problema è possibile ricorrere
ad una versione modificata della classica divisione, detta divisione protetta, la quale restituisce,
per esempio, all’evenienza della situazione precedentemente descritta, il valore 1. La proprietà
di sufficienza è soddisfatta quando il primitive set è, per l’appunto, sufficiente per la generazione
di una soluzione al problema da risolvere. Purtroppo tale proprietà è assicurata solo quando l’utente è consapevole che una soluzione al problema dato è ottenibile combinando gli elementi del
primitive set. Supponendo di voler rappresentare una funzione trascendente, per esempio ln (x),
l’insieme P = {x, +, −, ∗, %, 0, 1, 2} sarebbe insufficiente per tale problema, poiché non esiste una
combinazione finita degli elementi di P in grado di rappresentare perfettamente la funzione ln (x).
Quando la proprietà di sufficienza non è soddisfatta, la PG può produrre solo risultati approssimati
rispetto a quello desiderato [5].
10
Scuola Politecnica e delle Scienze di Base – Corso di Studi in Ingegneria Informatica
Algoritmi genetici e programmazione genetica
Figura 2.2: Creazione di un albero completo di profondità massima 2 mediante tecnica full. Per ogni iterazione
dell’algoritmo, corrispondente ad un dato istante temporale ti , i nodi scelti sono cerchiati in rosso.
2.2
Inizializzazione della popolazione
Alla stregua degli AG e degli altri algoritmi evolutivi, nella PG gli individui della popolazione
iniziale sono generati in maniera casuale. Di seguito verranno descritti tre algoritmi di inizializzazione per la popolazione iniziale degli individui: full, grow ed una combinazione delle precedenti
nota come ramped half-and-half [4, 5]. Per gli esempi illustrativi, il primitive set di riferimento
per la generazione degli alberi sarà P = { + , − , ∗ , % , x , y , 0 , 1 , 2 }.
Fissato il parametro h che decreta la profondità massima consentita per gli alberi, la tecnica
full prevede la scelta casuale di elementi dal function set fino alla profondità massimah, dopodiché
verranno scelti solo elementi dal terminal set per completare l’albero. La figura 2.2 mostra il
processo di inizializzazione di un albero di profondità massima 2 con la tecnica full. Se le funzioni
appartenenti al function set hanno tutte la stessa arità1 , la popolazione risultante avrà lo stesso
numero di nodi per ogni albero (valore che definisce la dimensione dell’albero) e quindi la stessa
forma.
Nella tecnica grow i nodi vengono selezionati dall’intero primitive set fino alla profondità
massima h, dopodiché l’albero verrà completato con soli nodi appartenenti al terminal set. Questa
tecnica permette di creare alberi di varie forme e dimensioni; può succedere infatti che ad una data
altezza i nodi scelti siano tutti appartenenti al terminal set, troncando il processo di inizializzazione
dell’albero prima di giungere alla profondità massima h. La figura 2.3 mostra il processo di
1 La arità di una funzione è pari al numero di argomenti della stessa. Graficamente corrisponde al numero di rami
uscenti dal nodo.
11
Scuola Politecnica e delle Scienze di Base – Corso di Studi in Ingegneria Informatica
Algoritmi genetici e programmazione genetica
Figura 2.3: Creazione di un albero completo di profondità massima 2 con la tecnica di inizializzazione grow.
inizializzazione di un albero di profondità 2 con la tecnica appena descritta. Notiamo che al passo
2 viene scelto un nodo terminale, troncando il ramo sinistro dell’albero nonostante la profondità
massima non sia stata raggiunta.
Con la tecnica ramped half-and-half metà della popolazione iniziale viene creata con la tecnica full, l’altra metà con la tecnica grow. La profondità varia in un intervallo I = [2, hmax ] in modo
incrementale, garantendo una maggiore diversità degli alberi in termini di forme e dimensioni. Per
esempio, se la massima profondità è 6, il 20% degli alberi avrà profondità 2, 20% avrà profondità
3 e così via fino alla profondità 6.
2.3
Operazioni genetiche
Analogamente a quanto visto con gli algoritmi genetici, nella PG le operazioni genetiche lavorano
su individui della popolazione selezionati in base alla loro fitness. La logica di selezione più
diffusa nella PG è la selezione a torneo, precedentemente discussa nel capitolo 1.
L’operazione di crossover, denominata subtree crossover, consiste in uno scambio di sottoalberi tra gli individui della popolazione selezionati. Dati due alberi genitori, si sceglie in maniera
casuale un punto di crossover (un nodo) per ogni albero. L’albero figlio risultante sarà generato
rimpiazzando il sottoalbero tagliato nel punto di crossover del primo genitore con il sottoalbero
tagliato nel punto di crossover del secondo genitore, come illustrato in figura 2.4.
La forma di mutazione più comune nella PG, la cosiddetta subtree mutation, seleziona in
maniera casuale un punto di mutazione in un albero e sostituisce il corrispondente sotto-albero
tagliato con uno generato casualmente, come illustrato in figura 2.5.
12
Scuola Politecnica e delle Scienze di Base – Corso di Studi in Ingegneria Informatica
Algoritmi genetici e programmazione genetica
Figura 2.4: Esempio di subtree crossover. Da notare che gli alberi sulla sinistra sono soltanto copie dei genitori
selezionati, usate per non alterare la struttura genetica di quest’ultimi [5].
Un’altra forma comune di mutazione è la point mutation, analoga all’operazione di mutazione degli algoritmi genetici. Nella point mutation viene selezionato un nodo casuale ed in seguito
sostituito con un altro nodo scelto casualmente dal primitive set avente la stessa arità del primo
nodo. La scelta di quali operazioni applicare per la creazione della nuova generazione è probabilistica. Tipicamente, il crossover viene applicato con una probababilità del 90% o superiore,
mentre la mutazione con una probabilità pari circa all’1%. Quando le probabilità di crossover e
mutazione insieme raggiungono un valore p inferiore al 100%, con probabilità 1 − p si effettua
un’operazione di riproduzione, analoga all’operazione di riproduzione degli algoritmi genetici.
Figura 2.5: Esempio di subtree mutation [5].
13
Capitolo 3
Un esempio di programmazione
genetica
In questo capitolo tratteremo un esempio illustrativo di programmazione genetica, tratto da [5],
avente come obiettivo l’individuazione di una funzione matematica che fornisca gli stessi valori
della funzione target f (x) = x2 + x + 1 nell’intervallo [−1, +1]. Il diagramma di flusso in figura
3.1 illustra i vari passaggi che caratterizzano l’esecuzione della programmazione genetica.
3.1
Fasi preparatorie
Lo scopo delle prime due fasi preparatorie è quello di specificare gli ingredienti che il processo
evolutivo utilizzerà per la generazione di potenziali soluzioni, ovvero le composizioni di terminal
e function set. Poiché il problema consiste nel trovare una funzione matematica di una variabile
indipendente, il terminal set sarà composto dalla medesima variabile indipendente, nonché da
costanti numeriche effimere selezionate casualmente in un intervallo prefissato, rappresentate dal
terminale R. Ogni volta che il terminale R viene scelto per la costruzione di un nuovo albero, un
differente numero casuale è assegnato a quel determinato terminale, il quale rimarrà immutato per
tutto il tempo di esecuzione. Dunque il terminal set, T , sarà
T = {x, R}
La scelta del function set è strettamente correlata al dominio del problema da risolvere. Data
14
Scuola Politecnica e delle Scienze di Base – Corso di Studi in Ingegneria Informatica
Algoritmi genetici e programmazione genetica
Figura 3.1: Diagramma di flusso programmazione genetica [5].
la natura del nostro problema, un function set costituito solo dalle operazioni di moltiplicazione
e addizione sarebbe sufficiente, in quanto nella funzione target f (x) compaiono soltanto queste
due operazioni. Tuttavia, per completezza, scegliamo un function set caratterizzato dalle quattro
ordinarie operazioni aritmetiche: addizione, sottrazione, moltiplicazione e divisione. Dunque il
function set, F, sarà
F = {+, −, ∗, %} ,
dove % rappresenta l’operazione di divisione protetta discussa nel capitolo 2.
La terza fase preparatoria consiste nel definire una misura di fitness f . Tale misura dovrà
riflettere, per ogni individuo della popolazione, la vicinanza degli gli output di un determinato
programma con la funzione target f (x). Nel nostro esempio la misura di fitness di un determinato programma f p sarà calcolata come somma, in valore assoluto, delle differenze tra l’output
della funzione target f (x) e l’output del programma, calcolate in corrispondenza di n valori dati
15
Scuola Politecnica e delle Scienze di Base – Corso di Studi in Ingegneria Informatica
Algoritmi genetici e programmazione genetica
Figura 3.2: Popolazione iniziale di programmi generata casualmente.
dall’intervallo I = {−1, −0.9, −0.8 . . . 0.8, 0.9, 1}:
n
f p = ∑ | pi − f (xi ) |
i=1
dove pi corrisponde all’i-esimo valore di output del programma p in corrispondenza dell’i-esimo
valore dell’intervallo I e f (xi ) all’i-esimo valore della funzione target f (x) in corrispondenza
dell’i-esimo valore dell’intervallo I. La bontà di una soluzione è maggiore per valori di fitness
bassi, dunque una fitness pari a 0 corrisponde alla soluzione perfetta, ovvero ad una corrispondenza
perfetta tra gli output dell’individuo e quelli della funzione target f (x). Così definita la fitness
di un individuo sarà proporzionale all’area tra la parabola x2 + x + 1 e la curva che rappresenta
graficamente tale individuo.
Nella quarta fase preparatoria si decidono i parametri di esecuzione. Per rendere ancora
più semplice l’esempio, la dimensione della nostra popolazione sarà pari a quattro. Infine, le
probabilità di crossover, mutazione e riproduzione saranno, rispettivamente, 50%, 25% e 25%.
La quinta e ultima fase preparatoria consiste nella scelta di un criterio di terminazione. Un
criterio di terminazione ragionevole per questo problema è che il processo evolutivo continui di
generazione in generazione fintanto che un individuo risulti con fitness minore di 0, 1.
3.2
Esecuzione
La popolazione iniziale sarà composta da quattro individui, mostrati in figura 3.1, generati casualmente mediante la tecnica di inizializzazione ramped half-and-half. Il primo individuo, x + 1, ha
un valore di fitness pari a 7.7. Il secondo individuo, x2 + 1, ha un valore di fitness pari a 11.0. Gli
ultimi due individui, 2 e x, hanno rispettivamente valori di fitness pari a 17.98 e 28.7. Come già
16
Scuola Politecnica e delle Scienze di Base – Corso di Studi in Ingegneria Informatica
Algoritmi genetici e programmazione genetica
Figura 3.3: Comparazione dei grafici degli individui della popolazione iniziale con la funzione target f(x). La curva
nera in ogni grafico rappresenta la funzione target, mentre le curve rosse tratteggiate i grafici dei rispettivi individui. La
fitness associata ad ogni individuo è approssimativamente proporzionale all’area compresa tra le due curve[5].
detto in precedenza, la fitness di un individuo sarà proporzionale all’area tra la parabola x2 + x + 1e
la curva che rappresenta graficamente tale individuo. Dalla figura 3.2, la quale compara i grafici
dei quattro individui generati con quello della funzione x2 + x + 1, si nota che il primo individuo
generato, ovvero x + 1, è quello che più di tutti si avvicina alla funzione target. A questo punto si
applicano le operazioni genetiche alla popolazione iniziale per dare vita alle successive generazioni. Partendo dall’operazione di riproduzione, viene scelto l’individuo ritenuto migliore sulla base
della misura di fitness adottata per il problema. In questo caso, l’individuo migliore è quello con
la fitness più bassa in assoluto: dunque viene scelto per la riproduzione l’individuo x + 1.
Successivamente viene eseguita l’operazione di mutazione. Ipotizziamo che venga selezionato, mediante selezione a roulette, il terzo individuo della popolazione iniziale (figura 3.1c). Il
punto di mutazione sarà scelto casualmente tra uno dei tre nodi che caratterizzano l’individuo (in
questo esempio il nodo terminale 2). Infine, viene sostituito il sottoalbero troncato al punto di
mutazione scelto (in questo caso solo il terminale 2) con un albero generato casualmente a partire dai terminal e function set precedentemente dichiarati. In questo esempio, l’albero generato
casualmente è x % x ; la figura 3.4b mostra il risultato finale della mutazione.
Gli ultimi due individui della nuova generazione sono creati mediante l’operazione di crossover, ricombinando il materiale genetico di due individui della popolazione iniziale selezionati,
17
Scuola Politecnica e delle Scienze di Base – Corso di Studi in Ingegneria Informatica
Algoritmi genetici e programmazione genetica
Figura 3.4: Popolazione evoluta in seguito alle operazioni di riproduzione, crossover e mutazione.
ancora una volta, mediante selezione a roulette. Per la prima istanza dell’operazione, supponiamo
che tali individui selezionati siano il primo ed il quarto, rappresentati rispettivamente dagli alberi
in figura 3.1a e 3.2d. I punti di crossover scelti casualmente per i due alberi saranno, rispettivamente per il primo ed il quarto, il nodo “+” ed il nodo “x”. Il risultato di tale operazione corrisponde
all’albero in figura 3.4c. Per la seconda istanza dell’operazione, gli individui selezionati saranno
il primo ed il secondo, rappresentati rispettivamente dagli alberi in figura 3.1a e 3.2b. I punti di
crossover scelti casualmente per i due alberi saranno, rispettivamente per il primo ed il quarto, il
nodo “+” ed il nodo “x” in fondo a sinistra. Il risultato di tale operazione corrisponde all’albero
in figura 3.4d. A questo punto la generazione 1 è completata; poiché l’individuo in figura 3.3d
corrisponde esattamente alla funzione target del nostro problema, quest’ultimo avrà fitness pari a
0: condizione che soddisfa il criterio di terminazione prestabilito.
18
Capitolo 4
TinyGP
In questo capitolo descriveremo in maniera sintetica un sistema di PG reale, TinyGP, sviluppato e
implementato da Riccardo Poli. Il codice e la trattazione completa del sistema sono reperibili in
[5].
4.1
Caratteristiche
TinyGP è un sistema di regressione simbolica avente le seguenti caratteristiche:
1. Il terminal set include un certo numero di variabili in virgola mobile definibili dall’utente
(denominate X1 . . . XN);
2. Il function set è caratterizzato dalle operazioni di addizione, sottrazione, moltiplicazione e
divisione protetta;
3. Il training set, composta da un header e vari casi di fitness, viene letto da file;
4. La selezione avviene tramite la tecnica di selezione a torneo;
5. Implementata la subtree crossover e la point mutation;
6. Implementa variabili statiche che specificano parametri quali dimensione della popolazione,
probabilità di crossover e mutazione, numero massimo di generazioni e così via ;
19
Scuola Politecnica e delle Scienze di Base – Corso di Studi in Ingegneria Informatica
Algoritmi genetici e programmazione genetica
7. La funzione di fitness è calcolata come l’opposto della somma delle differenze, in valore
assoluto, tra l’output del programma attuale e del valore desiderato, per ogni caso di fitness.
Tinygp la massimizza;
8. I programmi sono strutturati come sequenze di istruzioni e dati, secondo la rappresentazione
lineare standard per gli alberi.
4.2
Input data files
Il file di input per TinyGP ha il seguente formato:
La prima riga specifica, rispettivamente, il numero di variabili del sistema, il numero di costanti
casuali nel primitive set, il limite inferiore e superiore per la generazione delle costanti casuali ed
infine il numero di casi di fitness. Per esempio, una parte dei casi di fitness per la funzione sin(x)
per x ∈ {0.0, 0.1, ...6.2} è:
il file completo è reperibile al seguente indirizzo: http://cswww.essex.ac.uk/staff/rpoli/TinyGP/sindata.txt
20
Scuola Politecnica e delle Scienze di Base – Corso di Studi in Ingegneria Informatica
4.3
Algoritmi genetici e programmazione genetica
Compilazione ed esecuzione
Come training set per l’esecuzione di TinyGP scegliamo la funzione sin(x) precedentemente mostrata. TinyGP può essere facilmente compilato dalla shell del sistema operativo, producendo un
output simile al seguente:
Notiamo che ad ogni generazione il programma calcola e mostra in output: il numero attuale della
generazione, la fitness e la dimensione media della popolazione, la miglior fitness nonché il programma associato a tale fitness, designato come miglior programma per la generazione attuale.
La figura 4.1 mostra nei primi due grafici l’evoluzione della fitness media, della fitness migliore
e della dimensione media dei programmi nell’arco delle generazione; l’ultimo grafico rappresenta
l’andamento del miglior programma a fine esecuzione, avente una fitness di 1.88 e corrispondente
alla seguente funzione:
21
Scuola Politecnica e delle Scienze di Base – Corso di Studi in Ingegneria Informatica
Figura 4.1
22
Algoritmi genetici e programmazione genetica
Conclusioni
In questo elaborato sono stati trattati gli aspetti principali che caratterizzano gli algoritmi genetici
e la programmazione genetica. Sebbene non siano stati menzionati nel corso dell’elaborato, si ritiene giusto elencare alcuni aspetti critici riguardanti le tecniche appena discusse. Trattandosi, per
l’appunto, di metodi di ricerca euristici, la convergenza ad una soluzione non è sempre garantita.
D’altro canto, per garantire la convergenza è spesso necessario ricorrere a popolazioni di individui
di grandi dimensioni. Questo aspetto, unito al fatto che calcolare la fitness di un singolo individuo
richiede la valutazione su un certo training set, porta ad uno sforzo computazionale notevole. Nel
caso particolare della programmazione genetica, l’albero di un programma può anche essere molto complesso; in tal caso il problema non riguarderebbe solo la dimensione temporale, ma anche
quella spaziale che può superare la capacità di memorizzazione di una singola macchina. Da qui
la necessità di realizzare un’implementazione parallela di questo tipo di algoritmi su ambienti di
tipo distribuito, per ovviare anche al problema della memoria insufficiente [8]. Gli algoritmi genetici e la programmazione genetica, sin dalla loro nascita, hanno prodotto innumerevoli risultati
in numerosi contesti applicativi. La programmazione genetica risulta particolarmente efficace, per
esempio, nei problemi di ricerca che non richiedono necessariamente una soluzione esatta; o ancora, si è dimostrata un ottimo strumento nei casi in cui il dominio del problema non è del tutto
noto. Per un elenco dettagliato dei risultati ottenuti dalla programmazione genetica è possibile
consultare [5] nonché la vasta bibliografia di John R. Koza.
23
Bibliografia
[1] J.H. Holland, Adaptation in Natural and Artificial Systems: An Introductory Analysis With
Applications to Biology, Control, and Artificial Intelligence, University of Michigan Press,
1975.
[2] Roulette
wheel
selection,
http://www.edc.ncl.ac.uk/highlight/rhjanuary2007g02.php,
16/12/2015.
[3] M. Mitchell, An Introduction to Genetic Algorithms, MIT Press, 1996.
[4] J.R. Koza, Genetic Programming: On the Programming of Computers by Means of Natural
Selection, MIT Press, 1992.
[5] R. Poli, W. B. Langdon and N, F. McPhee, A Field Guide to Genetic Programming,
http://www0.cs.ucl.ac.uk/staff/ucacbbl/ftp/papers/poli08_fieldguide.pdf
[6] W. Banzhaf, F.D. Francone, R.E. Keller, P. Nordin, Genetic Programming: An Introduction
on the Automatic Evolution of Computer Programs and Its Applications, Morgan Kaufmann,
1998
[7] Selezione naturale, Enciclopedia Treccani, http://www.treccani.it/enciclopedia/selezionenaturale, 2/12/2015
[8] Algoritmi evolutivi e programmazione genetica: strategie di progettazione e parallelizzazione,
http://biblio.cs.icar.cnr.it/tr/scaricaTR.asp?FileID=51, 20/12/2015
[9] Flowchart
(Executional
Steps)
of
Genetic
http://www.genetic-programming.com/gpflowchart.html, 19/12/2015
24
Programming,
Scarica