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 { /* ... */ };
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
Como renomear arquivos de letras maiúsculas para minúsculas
Imprimindo no formato livreto no Linux
Vim - incrementando números em substituição
Efeito "livro" em arquivos PDF
Como resolver o erro no CUPS: Unable to get list of printer drivers
Preciso resolver um erro de DPKG (1)
Melhores Práticas de Nomenclatura: Pastas, Arquivos e Código (2)
Não to conseguindo resolver este problemas ao instalar o playonelinux (1)
[Python] Automação de scan de vulnerabilidades
[Python] Script para analise de superficie de ataque
[Shell Script] Novo script para redimensionar, rotacionar, converter e espelhar arquivos de imagem
[Shell Script] Iniciador de DOOM (DSDA-DOOM, Doom Retro ou Woof!)
[Shell Script] Script para adicionar bordas às imagens de uma pasta