23#include <gsl/gsl_rng.h>
24#include <gsl/gsl_randist.h>
31 struct solution **parent, **offspring, *best;
34 double *cost, *fitness, mincost, **ranking_aux;
41static int cmp_doublep(
const void *a,
const void *b) {
42 double x = **(
double **) a;
43 double y = **(
double **) b;
52static void ranking(
double *fitness,
double **aux,
double *cost,
double sp,
int n) {
55 for (i = 0; i < n; i++)
57 qsort(aux, n,
sizeof(
double *), cmp_doublep);
58 for (i = 0; i < n; i = j) {
59 num = sp - (sp-1.) * 2.0 * i / (n-1.);
61 for (j = i+1; j < n && *aux[i] == *aux[j]; j++) {
62 num += sp - (sp-1.) * 2.0 * j / (n-1.);
65 for (k = i; k < j; k++)
66 fitness[aux[k]-cost] = num / den;
70static void sus(
struct solution **o,
struct solution **p,
const double *f,
int nsel,
int n) {
72 double x, cumfit, totfit = 0.0;
75 for (i = j = 0; i < n; i++)
77 x = gsl_rng_uniform(rng);
82 if (totfit * x < cumfit * nsel) {
89 copySolution(o[j], o[j-1]);
96 fprintf(stderr,
"SUS warning: end of parent array reached.");
101 for (i = n-1; i > 0; i--) {
102 j = gsl_rng_uniform_int(rng, i+1);
110static void single_step_mutation(
struct solution **pop,
int n,
double Pm,
struct move *tmpmove) {
112 for (i = 0; i < n; i++)
113 if (gsl_rng_uniform(rng) < Pm) {
114 randomMove(tmpmove, pop[i]);
115 applyMove(pop[i], tmpmove);
120static void standard_mutation(
struct solution **pop,
int n,
double Pm,
struct move *tmpmove,
struct pathState *tmppath) {
123 for (i = 0; i < n; i++) {
124 initPathAwayFrom(tmppath, pop[i]);
125 k = getPathLength(tmppath);
126 pm = 1.-pow(1.-Pm, 1./k);
127 k = gsl_ran_binomial(rng, pm, k);
128 for (j = 0; j < k; j++) {
129 nextRandomMove(tmpmove, tmppath);
130 applyMove(pop[i], tmpmove);
136static void geometric_recombination(
struct solution **pop,
int n,
double Px,
struct move *tmpmove,
struct pathState *tmppath) {
140 for (i = 0; i < n; i++) {
141 if (gsl_rng_uniform(rng) < Px) {
142 initPathTo(tmppath, tmpsol, pop[i]);
143 k = getPathLength(tmppath);
145 k -= gsl_rng_uniform_int(rng, k/2)+1;
149 while (getPathLength(tmppath) > k) {
150 nextRandomMove(tmpmove, tmppath);
151 applyMove(tmpsol, tmpmove);
167 ss->popsize = popsize;
168 ss->parent = malloc(popsize *
sizeof (
struct solution *));
169 for (i = 0; i < popsize; i++)
170 ss->parent[i] = allocSolution(p);
171 ss->best = allocSolution(p);
172 ss->cost = malloc(popsize *
sizeof (
double));
174 ss->offspring = malloc(popsize *
sizeof (
struct solution *));
175 for (i = 0; i < popsize; i++)
176 ss->offspring[i] = allocSolution(p);
177 ss->v = allocMove(p);
178 ss->ps = allocPathState(p);
179 ss->ranking_aux = malloc(popsize *
sizeof (
double *));
180 ss->fitness = malloc(popsize *
sizeof (
double));
182 for (i = 0; i < popsize; i++) {
183 randomSolution(ss->parent[i]);
185 ss->mincost = INFINITY;
186 for (i = 0; i < popsize; i++) {
187 ss->cost[i] = getObjectiveValue(ss->parent[i]);
188 if (ss->cost[i] < ss->mincost) {
189 ss->mincost = ss->cost[i];
190 copySolution(ss->best, ss->parent[i]);
196 ss->Pm = (1.-1./ss->SP)*.8;
202 free(ss->ranking_aux);
204 freePathState(ss->ps);
206 for (i = 0; i < ss->popsize; i++) {
207 freeSolution(ss->offspring[i]);
208 freeSolution(ss->parent[i]);
210 freeSolution(ss->best);
219 int popsize = ss->popsize, i;
222 ranking(ss->fitness, ss->ranking_aux, ss->cost, ss->SP, ss->popsize);
225 sus(ss->offspring, ss->parent, ss->fitness, popsize, popsize);
228 geometric_recombination(ss->offspring, popsize, ss->Px, ss->v, ss->ps);
232 single_step_mutation(ss->offspring, popsize, ss->Pm, ss->v);
235 standard_mutation(ss->offspring, popsize, ss->Pm, ss->v, ss->ps);
240 ss->parent = ss->offspring;
241 ss->offspring = tmppop;
242 for (i = 0; i < popsize; i++) {
243 ss->cost[i] = getObjectiveValue(ss->parent[i]);
244 if (ss->cost[i] < ss->mincost) {
245 ss->mincost = ss->cost[i];
246 copySolution(ss->best, ss->parent[i]);
257 fprintf(stderr,
"sga: printSolverState() not implemented yet.\n");
262double getSelectivePressure(
struct solverState *ss) {
266double getRecombinationRate(
struct solverState *ss) {
274void setSelectivePressure(
struct solverState *ss,
double SP) {
275 if (SP >= 1. && SP <= 2.)
278 fprintf(stderr,
"sga: Invalid selective pressure. Unchanged.\n");
281void setRecombinationRate(
struct solverState *ss,
double Px) {
282 if (Px >= 0. && Px <= 1.)
285 fprintf(stderr,
"sga: Invalid recombination rate. Unchanged.\n");
288void setMutationRate(
struct solverState *ss,
double Pm) {
289 if (Pm >= 0. && Pm <= 1.)
292 fprintf(stderr,
"sga: Invalid mutation rate. Unchanged.\n");