-
Notifications
You must be signed in to change notification settings - Fork 14
How to add a new technique?
Gustavo Rosa edited this page Mar 23, 2017
·
5 revisions
If you want to add another optimization technique not implemented here, you can follow the steps below:
- Define a directive corresponding to your technique in opt.h (e.g. _PSO_ = 1 concerning Particle Swarm Optimization). Suppose we want to add Brazilian Soccer Optimization (BSO): we just need to add the following line in opt.h:
#define _BSO_ X
, where X stands for a natural number not used before. - If your technique does need a different structure not implemented in LibOPT, you must do the following:
- All structures are implemented in include/common.h. Therefore, you should work on there first.
- At structure Agent, add your desired parameters. For instance, suppose BSO needs a player's strength for each decision variable: we need to add the following line:
- At structure SearchSpace, add your desired parameters. For instance, suppose BSO uses an additional variable that encodes the quality of the grass during the match: we need to add the following line:
- Now, we should move to src/common.c. There, you must allocate and deallocate your new variables as follows:
- At function CreateAgent, you should add one more switch command in order to allocate your new variable, as well as to initialize it:
- At function DestroyAgent, you should deallocate your new variable:
- At function CreateSearchSpace, you should add one more switch command in order to allocate your new variable, as well as to initialize it. Notice you must do that only if your new variable is an array.
- At function DestroySearchSpace, you should deallocate your new variable:
- Further, you need to create files include/bso.h and src/bso.c. In regard to their headers, you must do as follows:
- in file include/bso.h:
#ifndef BSO_H #define BSO_H #include opt.h ... /* >>> YOUR NEW CODE HERE <<< */ #endif
- in file src/bso.c:
#include "bso.h"
- Finally, you need to update Makefile in order to compile your new technique. You can just copy and paste the lines regarding any technique that has been written already.
typedef struct Agent_{
int n; /* number of decision variables */
double *x; /* position */
double *v; /* velocity */
double f; /* fitness value */
...
double *strength; /* >>> NEW LINE HERE <<< */
}Agent;
typedef struct SearchSpace_{
int m; /* number of agents (solutions) */
int n; /* number of decision variables */
Agent **a; /* array of pointers to agents */
...
double grass_quality; /* >>> NEW LINE HERE <<< */
}SearchSpace;
/* It creates an agent
Parameters:
n: number of decision variables
opt_id: identifier of the optimization technique */
Agent *CreateAgent(int n, int opt_id){
if((n < 1) || opt_id < 1){
fprintf(stderr,"\nInvalid parameters @CreateAgent.\n");
return NULL;
}
Agent *a = NULL;
a = (Agent *)malloc(sizeof(Agent));
a->v = NULL;
a->strength = NULL; /* >>> NEW LINE HERE <<< */
switch (opt_id){
case _PSO_:
a->v = (double *)malloc(n*sizeof(double));
break;
...
case _BSO_: /* >>> NEW CASE HERE <<< */
a->strength = (double *)malloc(n*sizeof(double));
break;
default:
free(a);
fprintf(stderr,"\nInvalid optimization identifier @CreateAgent\n");
return NULL;
break;
}
a->x = (double *)malloc(n*sizeof(double));
return a;
}
/* It deallocates an agent
Parameters:
a: address of the agent to be deallocated
opt_id: identifier of the optimization technique */
void DestroyAgent(Agent **a, int opt_id){
Agent *tmp = NULL;
tmp = *a;
if(!tmp){
fprintf(stderr,"\nAgent not allocated @DestroyAgent.\n");
exit(-1);
}
if(tmp->x) free(tmp->x);
switch (opt_id){
case _PSO_:
if(tmp->v) free(tmp->v);
break;
case _BSO_:
if(tmp->strength) free(tmp->strength); /* >>> DEALLOCATE YOUR VARIABLE HERE <<<*/
break;
default:
fprintf(stderr,"\nInvalid optimization identifier @DestroyAgent.\n");
break;
}
free(tmp);
}
/* It creates a search space
Parameters:
m: number of agents
n: number of decision variables
opt_id: identifier of the optimization technique */
SearchSpace *CreateSearchSpace(int m, int n, int opt_id){
SearchSpace *s = NULL;
if((m < 1) || (n < 1) || (opt_id < 1)){
fprintf(stderr,"\nInvalid parameters @CreateSearchSpace.\n");
return NULL;
}
int i;
s = (SearchSpace *)malloc(sizeof(SearchSpace));
s->m = m;
s->n = n;
s->a = (Agent **)malloc(s->m*sizeof(Agent *));
s->a[0] = CreateAgent(s->n, opt_id);
if(s->a[0]){ /* Here, we verify whether opt_id is valid or not. In the latter case, function CreateAgent returns NULL. */
for(i = 1; i < s->m; i++)
s->a[i] = CreateAgent(s->n, opt_id);
}else{
free(s->a);
free(s);
return NULL;
}
switch (opt_id){
case _BSO_:
/* >>> NEW VARIABLE HERE <<<*/
break;
}
return s;
}
/* It deallocates a search space
Parameters:
s: address of the search space to be deallocated
opt_id: identifier of the optimization technique */
void DestroySearchSpace(SearchSpace **s, int opt_id){
SearchSpace *tmp = NULL;
int i;
tmp = *s;
if(!tmp){
fprintf(stderr,"\nSearch space not allocated @DestroySearchSpace.\n");
exit(-1);
}
for(i = 0; i < tmp->m; i++)
if(tmp->a[i]) DestroyAgent(&(tmp->a[i]), opt_id);
free(tmp->a);
switch (opt_id){
case _BSO_:
/* >>> DEALLOCATE YOUR VARIABLE HERE <<<*/
break;
default:
fprintf(stderr,"\nInvalid optimization identifier @DestroySearchSpace.\n");
break;
}
free(tmp);
}