System Overview
GATSS consiste di un programma C++, uninterfaccia
HTML e un CGI-script che collega le due parti insieme. In questa
sessione discuteremo in breve la struttura del programma C++.
Il programma consiste di una parte principale e tre classi:
Gene, Chromo e Pop.
Gene
Questa classe definisce la parte 'atomica' del GA.
class Gene
{
public:
Gene(char *_name, coord_t _x, coord_t _y,
unsigned int _index,
unsigned int _distVecLength);
~Gene();
// Calcola distanza Euclidea tra questo gene e _gene
e restituisce il valore.
distance_t calculateDistanceTo(Gene& _gene);
// Restituisce distanza Euclidea tra questo gene
e _gene
distance_t distanceTo(Gene& _gene);
// Restituisce lindice di questo gene nel
chromosome pool originale.
unsigned int getIndex() {return index;}
// Restituisce il nome di questo gene.
char *getName() {return name;}
// Stampa informazioni del gene.
friend ostream& operator<<(ostream&
outStr, Gene& gene);
private:
distance_t *distance; // vettore distanza
unsigned int distVecLength; // lunghezza del
vettore distanza
char *name; // nome del gene
coord_t x,y; //coordinate del gene
unsigned int index; //indice del gene
};
Un Gene consiste di un nome, x- e y - coordinate, un vettore
distanza che descrive la distanza da altri geni (solo calcolata
una volta a ogni esecuzione del programma) e un indice del gene.
Operazioni possibili su un Gene possono essere viste nella
dichiarazione di classe suddetta.
Chromo
Questa classe definisce un cromosoma.
class Chromo
{
public:
Chromo(unsigned int _chromoLength, Gene *_genePool[]);
~Chromo();
// Copia il costruttore.
Chromo& Chromo::operator=(Chromo& original);
// Inizializzazione del Cromosoma.
void init();
// Calcola (se necessario) e restituisce la //valutazione
del cromosoma.
eval_t eval();
// Imposta valutazione modificata del cromosoma
//(fitness).
eval_t setModEval(eval_t _modEval) {return (myModEval
= _modEval);}
// Restituisce la valutazione del cromosoma
modificato (fitness).
eval_t getModEval() {return myModEval;}
// Restituisce la valutazione del cromosoma (fitness).
eval_t getEval() {return myEval;}
// Accoppia questo cromosoma con partner //risultante
tra due nuovi figli, child1 e child2.
void mate(float _crossover, cross_t crossoverType,
float _mutation, Chromo& partner,
Chromo& child1, Chromo& child2);
// Restituisce la lunghezza del cromosoma.
unsigned int getLength() {return chromoLength;}
// Stampa informazioni del cromosoma.
friend ostream& operator<<(ostream&
outStr, Chromo& chromo);
private:
unsigned int chromoLength; // lunghezza del
cromosoma
eval_t myEval; // valutazione del cromosoma
eval_t myModEval; // valutazione modificata del
// cromosoma (fitness)
Gene **genePool; // puntatore alloriginale
//vettore gene pool
Gene **myGenePool; // vettore privato gene pool
// Tiene traccia dei geni usati durante il
//crossover.
int Chromo::isUsed(Gene *gene, Gene *usedGene[], int
noOfUsedGenes);
// Fa il crossover usando parent1 e parent2 come
//modelli.
// A questo cromosoma è assegnato il risultato.
void crossover(cross_t crossoverType, Chromo&
parent1, Chromo& parent2);
// Fa la mutazione su questo cromosoma.
void mutate();
// Modified random generator.
unsigned int myRand();
};
Un Chromo consiste principalmente del vettore Gene e due
valori stimati (uno originale e uno modificato da uno degli
algoritmi di fitness).
Le operazioni possibili, incluso crossover e mutazione,
possono essere viste nella dichiarazione di classe sotto.
Pop
Questa classe definisce la popolazione.
class Pop
{
public:
Pop(int _popSize, unsigned int _chromoLength, Gene *_genePool[]);
~Pop();
// Inizializzazione della Popolazione.
void init();
// Calcola (se necessario) il fitness per ogni
cromosoma nella
// popolazione e restituisce la somma dei valori di
fitness.
eval_long_t fitness(fitness_t fitnessType, eval_t
fitnessParam);
// Crea una nuova popolazione usando questa
popolazione come una pool di genitori
// e restituisce un puntatore a una nuova
popolazione.
// Se deletionType == deleteAll, lutente di
questa classe deve
// cancellare questa popolazione (la nuova è
veramente nuova).
// If deletionType == steadyDelete, la vecchia
popolazione è alterata
// e così, non richiede altre azioni da dellutente.
Pop *newPop(fitness_t fitnessType, eval_t
fitnessParam,
float crossover, cross_t crossoverType, float mutation,
delete_t deletionType, int elitismValue);
// Restituisce il fitness del miglior cromosoma
nella popolazione.
eval_t bestFitness() {return myChromoPool[0]->getEval();}
// Restituisce il fitness modificato del miglior
cromosoma nella popolazione.
eval_t bestFitnessMod() {return myChromoPool[0]->getModEval();}
// Restituisce la media del fitness dei cromosomi
della popolazione.
eval_t fitnessAverage();
// Restituisce la media modificata del fitness
dei cromosomi della popolazione.
eval_t fitnessAverageMod() {return (eval / popSize);}
// Restituisce il miglior cromosoma nella
popolazione.
Chromo& bestChromo() {return *myChromoPool[0];}
Chromo **myChromoPool; // vettore Cromosoma
// (deve essere pubblico per qualche ragione
che
//ignoriamo)
// Stampa informazioni sulla popolazione.
friend ostream& operator<<(ostream&
outStr, Pop& pop);
private:
Gene **genePool; // puntatore al vettore gene pool
//originale
unsigned int chromoLength; // lunghezza dei
// cromosomi nella popolazione
eval_long_t eval; // somma di tutti i valori
//di valutazione dei cromosomi
int popSize; // numeri di cromosomi nella
//popolazione
// Restituisce un genitore usando Roulette Wheel
//Selection.
Chromo& getParent();
// Ordina chromosome pool in ordine di fitness.
void quickSort(int start, int finish);
};
Pop consiste principalmente di un vettore di Chromo.
Le possibili operazioni possono essere viste dichiarazione di
classe sotto.
Main
La cosa principale di questa parte è assegnare al GA parametri
dellutente ed eseguire il GA. Il loop di esecuzione del GA
è così:
//******************* Main Evolution Loop **********************
Pop *myPop = new Pop(popSize, chromoLength, genePool);
Pop *myNewPop;
int k;
cout << "Data:" << endl;
for (k = 0; k < generations; k++)
{
myPop->fitness(fitnessType,
fitnessParam);
cout << k
<< " "
<<
myPop->fitnessAverage() << " "
<< myPop->bestFitness() << endl;
myNewPop = myPop->newPop(fitnessType,
fitnessParam, crossover,
crossoverType, mutation, deletionType,
elitismValue);
if (deletionType == deleteAll)
{
delete
myPop;
myPop =
myNewPop;
}
}