#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>
#include"mersenne.h"
/* Control Parameters of the search algorithm*/
#define POP_SIZE 50 /* The number of candidate solutions*/
#define MAX_ITER 300 /*The number of iterations*/
//Problem definitions
#define DIM 20 //number of problem variables. Number of BITS. <<<<<<<MUDAR PARA CADA INSTANCIA!!!!!!!!!!!
#define RUN 10 /*Algorithm can run many times in order to see its robustness*/
#define PM 0.1 //mutation factor
#define CR .5 //PR parameter (Perturbation Rate)---crossing over factor---------------/
//Global variables
int pop[POP_SIZE][DIM]; //population of candidate solutions.
double fo[POP_SIZE]; //objective function value.
int best[DIM]; //best solution found
double bestfo[0]; //best fo value
int best_index[0]; //index for the best solution
int U[DIM]; //solution to be evaluated
int nfeval; /* number of function evaluations */
double Best[RUN];//best fitness in each run.
//Functions declarations
void AvgStdDev(double *Avg,double *StdDev,double Var[]);
double randon( double inferior, double superior);
void DE(int r);
double bde_fitness(int sol[DIM]);
void assignd(int D, int a[], int b[]);
double randon( double inferior, double superior)
{
// double aux = (float)inferior + ((superior - inferior)*rand()/(RAND_MAX+1.0));
double aux = (float)inferior + ((superior - inferior)*MT_randInt(RAND_MAX)/(RAND_MAX+1.0));
return aux;
}
/*Main program of the search algorithm*/
int main()
{
int i, j, k, r;
double avg,
std;
MT_seed();
nfeval = 0;
for (r=0;r<RUN;r++)
{
//Init population
for (j=0;j<POP_SIZE;j++)//each individual
{
fo[j] = 0.0;
for (k=0; k<DIM;k++) //each dimension
{
best[k] = 0;
pop[j][k] = (int)round(randon(0,1)); //binary population
}
}
//Objective function calculation
for (i = 0;i<POP_SIZE;i++)
{
for (j = 0;j<DIM;j++)
U[j] = pop[i][j];
fo[i] = bde_fitness(U); //add your optimization problem
}
//Best current solution identification.
bestfo[0] = fo[0];
best_index[0] = 0;
for(i=0;i<POP_SIZE;i++)
{
if (fo[i]>=bestfo[0]) //>= for maximization //<= for minimization
{
Best[r] = fo[i];
bestfo[0]=fo[i];
for(j=0;j<DIM;j++)
best[j]=pop[i][j];
best_index[0] = i;
}
}
DE(r); //evolutionary loop
//print best infividual and its fitness
printf("Best individual. FO: %.2f\n", Best
[r
]); for (j = 0; j<DIM; j++)
}//end FOR RUN
AvgStdDev(&avg,&std,Best);
printf("Average Best: %.2f +/- %.2f\n", avg
, std
); printf("Average number of function evaluations: %.f\n", (double)nfeval
/RUN
);
return 0;
}//end MAIN
void AvgStdDev(double *Avg,double *StdDev,double Var[])
{
int i;
*Avg = 0;
*StdDev = 0;
for (i=0;i<RUN;i++)
*Avg += Var[i];
*Avg /= RUN;
for (i=0;i<RUN;i++)
{
*StdDev
+= pow((*Avg
-Var
[i
]),2); }
*StdDev /= RUN;
}
double bde_fitness(int sol[DIM])
{
int i, j, k;
float FObj;
FObj = 0;
// this simple problem concerns to find the individual with 1's and 0's interchanged. Maximization problem!
for (i=0; i<(DIM-1); i++)
{
if (sol[i] != sol[i+1])
FObj++;
}
nfeval++; //update global variable
return FObj;
}
//Differential Evolution Code
void DE(int r)
{
int i, j, L, n; /* counting variables */
int r1; /* placeholders for random indexes */
int gen;
double trial_cost; /* buffer variable */
int tmp[DIM];
/*-----Initialize random number generator-----------------------------*/
MT_seed();
/*=======================================================================*/
/*=========Iteration loop================================================*/
/*=======================================================================*/
gen = 0; /* generation counter reset */
while (gen < MAX_ITER)
{ /* is accepted by compiler */
gen++;
for (i=0; i<POP_SIZE; i++) /* Start of loop through ensemble */
{
/* Pick a random population member */
r1
=(int)( ((double)rand() / ((double)(RAND_MAX
)+(double)(1)) ) * POP_SIZE
); if (r1 == POP_SIZE)
r1 = POP_SIZE-1;
/*-------BDE---------------------------------------------------------------------------------------*/
/*-------Model 1: DE/rand/1/bin--------------------------------------------------------------------*/
/*-------Model 2: DE/best/1/bin--------------------------------------------------------------------*/
assignd(DIM,tmp,pop[i]);
n
= (int)( ((double)rand()/((double)(RAND_MAX
)+(double)(1)) ) * DIM
); for (L=0; L<DIM; L++) /* perform D binomial trials */
{
if (((double)rand()/((double)(RAND_MAX
)+(double)(1)) < CR
) || L
== (DIM
-1)) /* change at least one parameter */ {
if ( randon(0.0,1.0) < PM)//mutation occurs
{
if (tmp[n]==0)
tmp[n] = 1;
else tmp[n] = 0;
}
/*Two models for information exchange. Comment or uncomment the following lines.
Model 1: DE/rand/1/bin. Moves toward a randon solution
Model 2: DE/best/1/bin. moves toward best solution in current population */
// else tmp[n] = pop[r1][n];//moves toward a randon solution. Model 1.
else tmp[n] = best[n]; //moves toward the best solution in current population. Model 2.
}
n = (n+1)%DIM;
}
/*=======Trial mutation now in tmp[]. Test how good this choice really was.==================*/
for (L=0; L<DIM; L++) /* check bounds */
{
if (tmp[L] > 1)
tmp[L] = 1;
if (tmp[L] < 0)
tmp[L] = 0;
}
for (j = 0;j<DIM;j++)
U[j] = tmp[j];
trial_cost = bde_fitness(U);
/* Evaluate new vector in tmp[] */
if (trial_cost >= fo[i]) /* >= for maximization. improved objective function value */
{
fo[i]=trial_cost;
for (j=0;j<DIM;j++)
pop[i][j] = tmp[j];
if (trial_cost > bestfo[0]) //> for maximizatio
{ /* if so...*/
bestfo[0]=trial_cost; /* reset cmin to new low...*/
best_index[0]=i;
for (j=0;j<DIM;j++)
best[j] = tmp[j];
Best[r] = bestfo[0];
}
}
else
{
//DO NOTHING!!!
}
}//END FOR End mutation loop through pop.
}//end WHILE
}
/*-----------End of DE()------------------------------------------*/
void assignd(int D, int a[], int b[])
/**C*F****************************************************************
** **
** Assigns D-dimensional vector b to vector a. **
** You might encounter problems with the macro ASSIGND on some **
** machines. If yes, better use this function although it's slower. **
** **
***C*F*E*************************************************************/
{
int j;
for (j=0; j<D; j++)
{
a[j] = b[j];
}
}