Enviado em 01/12/2018 - 22:57h
olá, estou estudando o algoritmo firefley e peguei seu código na internet em linguagem c++, porem quando eu coloco para executar não acha a melhor função nem o melhor vaga-lume, acredito o erro esta na FunctionCallback. O codigo segue abaixo
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <string.h>
#include <memory.h>
#define DUMP 1
#define MAX_FFA 1000
#define MAX_D 1000
using namespace std;
int D = 1000; // dimensão do problema
int n = 20; // número de vagalumes
int MaxGeneration; // número de interações
int NumEval; // número de avaliações
int Index[MAX_FFA]; // tipo de vagalumes de acordo com valores de aptidão
double ffa[MAX_FFA][MAX_D]; // agentes vagalumes
double ffa_tmp[MAX_FFA][MAX_D]; // população intermediária
double f[MAX_FFA]; // valores de aptidão
double I[MAX_FFA]; // intensidade da luz
double nbest[MAX_FFA]; // a melhor solução até agora
double lb[MAX_D]; // limite inferior
double ub[MAX_D]; // limite superior
double alpha = 0.5; // parâmetro alpha
double betamin = 0.2; // parâmetro beta
double gama = 1.0; // parâmetro gamma
double fbest; // a melhor função objetivo
typedef double (*FunctionCallback)(double sol[MAX_D]);
/*funções benchmark*/
double cost(double sol[MAX_D]);
double sphere(double sol[MAX_D]);
/*Escreva sua função objetivo*/
FunctionCallback function = &cost;
// opcionalmente recalcular o novo valor alfa
double alpha_new(double alpha, int NGen)
{
double delta; // delta parameter
delta = 1.0-pow((pow(10.0, -4.0)/0.9), 1.0/(double) NGen);
return (1-delta)*alpha;
}
// inicializar a população de vagalumes
void init_ffa()
{
int i, j;
double r;
// inicializar os limites inferior e superior
for (i=0;i<D;i++)
{
lb[i] = 0.0;
ub[i] = 2.0;
}
for (i=0;i<n;i++)
{
for (j=0;j<D;j++)
{
r = ( (double)rand() / ((double)(RAND_MAX)+(double)(1)) );
ffa[i][j]=r*(ub[i]-lb[i])+lb[i];
}
f[i] = 1.0; // inicializar atratividade
I[i] = f[i];
}
}
// implementação de bubble sort
void sort_ffa()
{
int i, j;
// inicialização dos índices
for(i=0;i<n;i++)
Index[i] = i;
// Bubble sort
for(i=0;i<n-1;i++)
{
for(j=i+1;j<n;j++)
{
if(I[i] > I[j])
{
double z = I[i]; // troca de atração
I[i] = I[j];
I[j] = z;
z = f[i]; // troca de aptidão
f[i] = f[j];
f[j] = z;
int k = Index[i]; // troca de índices
Index[i] = Index[j];
Index[j] = k;
}
}
}
}
// substituir a antiga população de acordo com os novos valores de índice
void replace_ffa()
{
int i, j;
// copiar população original para a área temporária
for(i=0;i<n;i++)
{
for(j=0;j<D;j++)
{
ffa_tmp[i][j] = ffa[i][j];
}
}
// seleção das gerações no sentido de EA
for(i=0;i<n;i++)
{
for(j=0;j<D;j++)
{
ffa[i][j] = ffa_tmp[Index[i]][j];
}
}
}
void findlimits(int k)
{
int i;
for(i=0;i<D;i++)
{
if(ffa[k][i] < lb[i])
ffa[k][i] = lb[i];
if(ffa[k][i] > ub[i])
ffa[k][i] = ub[i];
}
}
void move_ffa()
{
int i, j, k;
double scale;
double r, beta;
for(i=0;i<n;i++)
{
scale = abs(ub[i]-lb[i]);
for(j=0;j<n;j++)
{
r = 0.0;
for(k=0;k<D;k++)
{
r += (ffa[i][k]-ffa[j][k])*(ffa[i][k]-ffa[j][k]);
}
r = sqrt(r);
if(I[i] > I[j]) // mais brilhante e mais atraente
{
double beta0 = 1.0;
beta = (beta0-betamin)*exp(-gama*pow(r, 2.0))+betamin;
for(k=0;k<D;k++)
{
r = ( (double)rand() / ((double)(RAND_MAX)+(double)(1)) );
double tmpf = alpha*(r-0.5)*scale;
ffa[i][k] = ffa[i][k]*(1.0-beta)+ffa_tmp[j][k]*beta+tmpf;
}
}
}
findlimits(i);
}
}
void dump_ffa(int gen)
{
cout << "Dump at gen= " << gen << " best= " << fbest << endl;
}
/* mensagens de sintaxe no display */
void help()
{
cout << "Syntax:" << endl;
cout << " Firefly [-h|-?] [-l] [-p] [-c] [-k] [-s] [-t]" << endl;
cout << " Parameters: -h|-? = command syntax" << endl;
cout << " -n = number of fireflies" << endl;
cout << " -d = problem dimension" << endl;
cout << " -g = number of generations" << endl;
cout << " -a = alpha parameter" << endl;
cout << " -b = beta0 parameter" << endl;
cout << " -c = gamma parameter" << endl;
}
int main(int argc, char* argv[])
{
int i;
int t = 1; // contador de geração
// manipulação de parâmetros interativos
for(int i=1;i<argc;i++)
{
if((strncmp(argv[i], "-h", 2) == 0) || (strncmp(argv[i], "-?", 2) == 0))
{
help();
return 0;
}
else if(strncmp(argv[i], "-n", 2) == 0) // número de vagalumes
{
n = atoi(&argv[i][2]);
}
else if(strncmp(argv[i], "-d", 2) == 0) // dimensão do problema
{
D = atoi(&argv[i][2]);
}
else if(strncmp(argv[i], "-g", 2) == 0) // número de gerações
{
MaxGeneration = atoi(&argv[i][2]);
}
else if(strncmp(argv[i], "-a", 2) == 0) // parâmetro alpha
{
alpha = atof(&argv[i][2]);
}
else if(strncmp(argv[i], "-b", 2) == 0) // parâmetro beta
{
betamin = atof(&argv[i][2]);
}
else if(strncmp(argv[i], "-c", 2) == 0) // parâmetro gamma
{
gama = atof(&argv[i][2]);
}
else
{
cerr << "Fatal error: invalid parameter: " << argv[i] << endl;
return -1;
}
}
// laço de otimização do algoritmo firefly
// determinar o ponto de partida de gerador aleatório
srand(1);
// gerar os locais iniciais de n vagalumes
init_ffa();
#ifdef DUMP
dump_ffa(t);
#endif
while(t <= MaxGeneration)
{
// esta linha de reduzir alfa é opcional
alpha = alpha_new(alpha, MaxGeneration);
// avaliar novas soluções
for(i=0;i<n;i++)
{
f[i] = function(ffa[i]); // obtêm aptidão de solução
I[i] = f[i]; // inicializar atratividade
}
// Classificação dos vagalumes pela sua intensidade de luz
sort_ffa();
// substituir população mais velha
replace_ffa();
// encontrar o atual melhor
for(i=0;i<D;i++)
nbest[i] = ffa[0][i];
fbest = I[0];
// mover todos os vagalumes para os melhores locais
move_ffa();
#ifdef DUMP
dump_ffa(t);
#endif
t++;
}
cout << "End of optimization: fbest = " << fbest << endl;
return 0;
}
// função teste FF
double cost(double* sol)
{
double sum = 0.0;
for(int i=0;i<D;i++)
sum += (sol[i]-1)*(sol[i]-1);
return sum;
}
double sphere(double* sol) {
int j;
double top = 0;
for (j = 0; j < D; j++) {
top = top + sol[j] * sol[j];
}
return top;
}
Enviado em 03/12/2018 - 11:09h
Prezado,const double RAND_NORMALIZE_FACTOR=1.0/(RAND_MAX+1.0);
/* ... */
void init_ffa(){
/* ... */
r=rand()*RAND_NORMALIZE_FACTOR;
/* ... */
}
struct ffa_info {
double brightness, fitness;
vector<double> agents;
ffa_info(size_t dimension, double lb=1.0, double ub=2.0):
brightness(1.0), fitness(1.0)
{
agents.reserve(dimension);
while(dimension--)
agents.push_back((ub-lb)*rand()*RAND_NORMALIZE_FACTOR-lb);
}
// Função para permitir o uso de std::sort.
bool operator<(const ffa_info &other){ return brightness<other.brightness; }
};
class ffa_base {
private:
vector<ffa_info> fireflies;
public:
ffa_base(size_t n_fireflies, size_t dimension):
ffa(n_fireflies, ffa_info(dimension))
{
}
virtual double objective(const vector<double> &agents) = 0; // Função virtual pura, a ser implementada nas classes derivadas.
void next_generation(){
for(auto &firefly: fireflies)
firefly.brightness=firefly.fitness=objective(firefly.agents);
sort(fireflies.begin(), fireflies.end());
}
double fbest(){ return fireflies[0].brightness; }
void move(){ /* ... */ }
void dump(ostream &os){ /* ... */ }
/* ... o que mais for necessário ...*/
};
class ffa_cost: public ffa_base {
public:
using ffa_base::ffa_base; // Herda construtores da classe base.
double objective(const vector<double> &agents){
double sum=0.0;
for(auto ag: agents)
sum+=(ag-1)*(ag-1);
return sum;
}
};
class ffa_sphere: public ffa_base { /* ... */ };
Enviar mensagem ao usuário trabalhando com as opções do php.ini
Meu Fork do Plugin de Integração do CVS para o KDevelop
Compartilhando a tela do Computador no Celular via Deskreen
Como Configurar um Túnel SSH Reverso para Acessar Sua Máquina Local a Partir de uma Máquina Remota
Configuração para desligamento automatizado de Computadores em um Ambiente Comercial
Criando uma VPC na AWS via CLI
Multifuncional HP imprime mas não digitaliza
Dica básica para escrever um Artigo.
Como Exibir Imagens Aleatórias no Neofetch para Personalizar seu Terminal
Debian 12 (net inst) instalado Pendrive erro ao inicializar (3)
Agora temos uma assistente virtual no fórum!!! (246)