I came across this code of firefly algorithm and need to use it in my major. If any of you could explain the working of the functions, it would be of great help to me. Thanks in advance.

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>
#include<string.h>
#include<memory.h>

#defineDUMP 1
#defineMAX_FFA  1000
#defineMAX_D    1000

usingnamespacestd;

int D = 1000;           // dimension of the problem
int n = 20;         // number of fireflies
intMaxGeneration;       // number of iterations
intNumEval;         // number of evaluations
int Index[MAX_FFA];     // sort of fireflies according to fitness values

doubleffa[MAX_FFA][MAX_D];  // firefly agents
doubleffa_tmp[MAX_FFA][MAX_D]; // intermediate population
double f[MAX_FFA];      // fitness values
double I[MAX_FFA];      // light intensity
doublenbest[MAX_FFA];          // the best solution found so far
doublelb[MAX_D];        // upper bound
doubleub[MAX_D];        // lower bound

double alpha = 0.5;     // alpha parameter
doublebetamin = 0.2;           // beta parameter
doublegama = 1.0;       // gamma parameter

doublefbest;            // the best objective function

typedefdouble (*FunctionCallback)(double sol[MAX_D]);

/*benchmark functions */
doublecost(double sol[MAX_D]);
doublesphere(double sol[MAX_D]);

/*Write your own objective function */
FunctionCallback function = &cost;

// optionally recalculate the new alpha value
doublealpha_new(double alpha, intNGen)
{
    double delta;           // delta parameter
    delta = 1.0-pow((pow(10.0, -4.0)/0.9), 1.0/(double) NGen);
    return (1-delta)*alpha;
}

// initialize the firefly population
voidinit_ffa()
{
    inti, j;
    double r;

    // initialize upper and lower bounds
    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;         // initialize attractiveness
        I[i] = f[i];
    }
}

// implementation of bubble sort
voidsort_ffa()
{
    inti, j;

    // initialization of indexes
    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];    // exchange attractiveness
                I[i] = I[j];
                I[j] = z;
                z = f[i];           // exchange fitness
                f[i] = f[j];
                f[j] = z;
                int k = Index[i];   // exchange indexes
                Index[i] = Index[j];
                Index[j] = k;
            }
        }
    }
}

// replace the old population according the new Index values
voidreplace_ffa()
{
    inti, j;

    // copy original population to temporary area
    for(i=0;i<n;i++)
    {
        for(j=0;j<D;j++)
        {
            ffa_tmp[i][j] = ffa[i][j];
        }
    }

    // generational selection in sense of EA
    for(i=0;i<n;i++)
    {
        for(j=0;j<D;j++)
        {
            ffa[i][j] = ffa_tmp[Index[i]][j];
        }
    }
}

voidfindlimits(int k)
{
    inti;

    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];
    }
}

voidmove_ffa()
{
    inti, 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]) // brighter and more attractive
            {
                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)) );
                    doubletmpf = alpha*(r-0.5)*scale;
                    ffa[i][k] = ffa[i][k]*(1.0-beta)+ffa_tmp[j][k]*beta+tmpf;
                }
            }
        }
        findlimits(i);
    }
}

voiddump_ffa(int gen)
{
    cout<<"Dump at gen= "<< gen <<" best= "<<fbest<<endl;
}

/* display syntax messages */
voidhelp()
{
    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;
}

intmain(intargc, char* argv[])
{
inti;
int t = 1;      // generation  counter

// interactive parameters handling
for(inti=1;i<argc;i++)
         {
if((strncmp(argv[i], "-h", 2) == 0) || (strncmp(argv[i], "-?", 2) == 0))
            {
        help();
        return0;
            }
elseif(strncmp(argv[i], "-n", 2) == 0)         // number of fireflies
            {
        n = atoi(&argv[i][2]);
            }
elseif(strncmp(argv[i], "-d", 2) == 0)      // problem dimension
            {
        D = atoi(&argv[i][2]);
            }
elseif(strncmp(argv[i], "-g", 2) == 0)      // number of generations
            {
        MaxGeneration = atoi(&argv[i][2]);
            }
elseif(strncmp(argv[i], "-a", 2) == 0)      // alpha parameter
            {
        alpha = atof(&argv[i][2]);
            }
elseif(strncmp(argv[i], "-b", 2) == 0)      // beta parameter
            {
        betamin = atof(&argv[i][2]);
            }
elseif(strncmp(argv[i], "-c", 2) == 0)      // gamma parameter
            {
        gama = atof(&argv[i][2]);
            }
else
            {
        cerr<<"Fatal error: invalid parameter: "<<argv[i] <<endl;
        return -1;
            }
        }

// firefly algorithm optimization loop
// determine the starting point of random generator
    srand(1);

    // generating the initial locations of n fireflies
    init_ffa();
#ifdef DUMP
    dump_ffa(t);
#endif

    while(t <= MaxGeneration)
    {
        // this line of reducing alpha is optional
        alpha = alpha_new(alpha, MaxGeneration);

        // evaluate new solutions
        for(i=0;i<n;i++)
        {
f[i] = function(ffa[i]);                        // obtain fitness of solution
            I[i] = f[i];                    // initialize attractiveness
        }

        // ranking fireflies by their light intensity
        sort_ffa();
        // replace old population
        replace_ffa();

        // find the current best
        for(i=0;i<D;i++)
            nbest[i] = ffa[0][i];
        fbest = I[0];

        // move all fireflies to the better locations
        move_ffa();
#ifdef DUMP
        dump_ffa(t);
#endif
        t++;
    }

    cout<<"End of optimization: fbest = "<<fbest<<endl;

    return0;
}

// FF test function
doublecost(double* sol)
{
    double sum = 0.0;

    for(inti=0;i<D;i++)
        sum += (sol[i]-1)*(sol[i]-1);

    return sum;
}

doublesphere(double* sol) {
    int j;
    double top = 0;
    for (j = 0; j < D; j++) {
        top = top + sol[j] * sol[j];
    }
    return top;
}

Recommended Answers

All 3 Replies

Well, to begin with, this is a C++ program, not a C program, and a poorly written one at that. The header formats indicate that it probably dates back to the late 1990s, when the then-new C++ standard was still being formalized - either that, or the programmer didn't understand the standard correctly. Several critical values are hard-coded in rather than parameterized, making the implementation brittle. The choice of bubblesort for the sorting algorithm is questionable at best, though with the small range it probably isn't very performance-critical. Finally, the code is pretty badly mangled, with the return types running into the function names and so forth, which means that without many fixes it wouldn't compile cleanly.

While it could fairly easily be re-written in C, you would be a lot better off writing a new implementation of the algorithm yourself. You would waste more time trying to fix this than you would starting over from scratch.

Thanks for the early reply Schol-R-LEA. Also I wanted to know, seeing a source code how can you tell if it's C or C++ when they are so similar ? I might get down votes on this weird question but I really want to know. It would be of great help if you could find me as easily understandable code for the same.

Well, the first thing to look at is the headers, both the names and the format of them. A C program will have headers in the form of foo.h, whereas in (modern) C++, the standard library headers will be foo without the extension. Now, this isn't a foolproof method, as there's a lot of pre-standard C++ code floating around, but if you see a header without an extension, it is presumably C++.

Also, in C++, the C library headers should be prepended with a c, making (for example) <stdio.h> into <cstdio>. Again, a lot of older code doesn't match this standard, and even some current code isn't correct in this regard, but if it is like that, it is definitely C++ rather than C.

Next, the headers used may be different; C++ adds a large number of new libraries which use the C++ facilities that don't exist in C. The main ones to look for are <iostream>, <fstream>, <string>, <vector> and <algorithm>.

Fourth, C++ has namespaces, but C does not; so, if you see a reference to using namespace foo;, it will be C++. The same goes for the scoping operator, ::, which is used to indicate membership in either a class or a namespace.

Finally, if it uses cin and cout for input and output, it is going to be C++.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.