Le codage doit satisfaire le théorème fondamental des algorithmes génétiques, c´est à dire que les schèmes courts et d´ordres petits soient pertinents pour le problème et le plus indépendants possible des schèmes complémentaires (aux autres positions instanciées). |
Un alphabet de taille minimale est toujours préférable. |
typedef struct {
long ind;
char gen[L];
long phen;
long adapt;
} Ind;
Ind Pop1[N], Pop2[N];
for(i=0;i < N; i++)
{
pc = (Pop1 + i)->gen;
for (j = 0; j < L; j++)
pc[j] = rnd(Alpha[0], Alpha[Na-1] + 1);
}
Où rnd(v1,v2) retourne un entier de l´intervalle [v1,v2[ (voir 4-4-3).
long flip(float p)
{
return((drand48() <= p) ? 1 : 0);
}
Fonction retournant un entier de l´intervalle v1, v2 (utilisée pour
choisir un point de coupure lors d´un croisement):
long rnd(long v1, long v2)
{
return((long) (drand48() * (v2 - v1) + v1));
}
Fonction retournant la somme des adaptations de tous les individus de la
population pop (utilisée pour sélectionner des individus par une
probabilité biaisée par son adaptation: voir la fonction reproduction()):
long Somme(Ind *pop)
{
long S = 0, i;
for (i = 0; i < N; i++)
S += (pop + i)->adapt;
return(S);
}
reproduction(Ind *pop)
{
static long inc = 0;
long i, v;
v = S * drand48();
for (i = 0; i < N; i++)
{
if ((++inc >= N) inc = 0;
if ((pop + inc)->adapt > v) return(inc);
}
return(N - 1);
}
void croisement(long i1, long i2, long i3, long i4, Ind *pop)
{
char *pc1, *pc2, *pc3, *pc4;
long coup, i;
pc1 = (pop + i1)->chaine; pc2 = (pop + i2)->chaine;
pc3 = (pop + i3)->chaine; pc4 = (pop + i24->chaine;
coup = rnd(0, 4);
for (i = 0; i < coup; i++)
{pc3[i] = pc1[i];pc4[i] = pc2[i];}
for (i = coup; i < L; i++)
{pc3[i] = pc2[i];pc4[i] = pc1[i];}
}
void mutation(long ind, Ind *pop)
{
char *pc;
if(flip(0.001))
{
pc = (pop + ind)->chaine + rnd(0, 4);
*pc = rnd(Alpha[0], Alpha[Na-1]);
}
}