Friday, June 14, 2013

Bat optimization algorithm with special levy jump implementation on

Searching an optimized solution of a function. on formula with 2 parameters.

The js fiddle




The source code
function ln(val) {
    return Math.log(val) / Math.log(Math.E);
}

function pollarMethod() {
    do {
        U1 = Math.random();
        U2 = Math.random();
        V1 = 2 * U1 - 1.0;
        V2 = 2 * U2 - 1.0;
        S = V1 * V1 + V2 * V2;
    }
    while (S >= 1);

    X = V1 * Math.sqrt((-2 * ln(S)) / S);
    return X;
}

function poissonProcess(lambda, T) {
    var t = 0;
    var k = 0;
    var S = new Array();
    while (t <= T) {
        var r = Math.random();
        t = t - ln(r) / lambda;
        if (t > T) return S;
        S[k] = t;
        k = k + 1;
    }
    return S;
}

function levyJump(t, b, c, lambda) {
    var L = b * t;
    L = L + Math.sqrt(c) * pollarMethod();
    var nbLoop = poissonProcess(lambda, t);
    for (var i = 0; i < nbLoop; i++) {
        L += Math.random();
    }
    return L;
}

function fOptimize(x) {
    return x[0] * x[0] + x[1] * x[1]*x[1];
}

function bat(fOptimize, nbx, nbbat, maxiter, fmin1, fmax1, fmin2, fmax2) {

    var xxh = new Array();
    var vv = new Array();
    var xx = new Array();
    var ff1 = new Array();
    var ff2 = new Array();
    var rr = new Array();
    var rrOrig = new Array();
    var AA = new Array();
    var globalSolution = 99999999;
    var XSTAR = new Array();
    for (var j = 0; j < nbx; j++)
    XSTAR[j] = Math.random();

    for (var i = 0; i < nbbat; i++) {
        xx[i] = new Array();
        vv[i] = new Array();
        ff1[i] = new Array();
        ff2[i] = new Array();
        rr[i] = Math.random();
        rrOrig[i] = rr[i];
        AA[i] = Math.random();
        for (var j = 0; j < nbx; j++) {
            xx[i][j] = Math.random() ;
            vv[i][j] = Math.random() ;
            ff1[i][j] = Math.random() ;
            ff2[i][j] = Math.random() ;
        }
    }
    var t = 0;
    while (t < maxiter) {
        var actualSolution = 99999999;
        var xstar = new Array();
        for (var j = 0; j < nbx; j++)
        xstar[j] = Math.random();
        for (var i = 0; i < nbbat; i++) {
            for (var j = 0; j < nbx; j++) {
                ff1[i][j] = fmin1 + (fmax1 - fmin1) * Math.random()+levyJump(t, 0.5, 0.9, 2.0);
                vv[i][j] = vv[i][j] + xx[i][j] - XSTAR[j] * ff1[i][j];
                xx[i][j] = xx[i][j] + vv[i][j];
                /*
                ff1[i][j] = ((fmin1 - fmax1) * t / 2 + fmax1) * Math.random();
                ff2[i][j] = ((fmin2 - fmax2) * t / 2 + fmax2) * Math.random();
                var tempx = XSTAR[j] + ff1[i][j] * xx[i][j] + ff2[i][j] * xx[i][j];
                xx[i][j] = tempx + (Math.random() - 0.5) * levyJump(1, 0.9, 20.0, 1.0);
                */
            }
            var res = fOptimize(xx[i]);
            if (res < actualSolution) {
                xstar = xx[i];
                res = actualSolution;
            }
        }
        //Local solution search
        for (var i = 0; i < nbbat; i++) {
            if (Math.random() > rr[i]) {
                for (var j = 0; j < nbbat; j++) {
                    var newX = new Array();
                    for (var k = 0; k < nbx; k++) {
                        newX = xx[j][k] + (Math.random() * 2 - 1.0) * AA[i];
                    }
                    var res = fOptimize(newX);
                    if (res < actualSolution) {
                        xstar = newX;
                        res = actualSolution;
                    }
                }
            }
        }
        //Global solution search
        for (var i = 0; i < nbbat; i++) {
            if (Math.random() > rr[i]) {
                for (var j = 0; j < nbbat; j++) {
                    var newX = new Array();
                    for (var k = 0; k < nbx; k++) {
                        newX = xx[j][k] + (Math.random() * 2 - 1.0) * rr[i];
                    }
                    var res = fOptimize(newX);
                    if (res < actualSolution) {
                        xstar = newX;
                        res = actualSolution;
                    }
                }
            }
        }
        if (actualSolution < globalSolution) {
            for (var j = 0; j < nbbat; j++) {
                AA[j] = 0.7 * AA[j];
                rr[j] = rrOrig * (1 - Math.exp(-0.7 * t));
            }
            actualSolution=globalSolution;
            XSTAR=xstar;
        }
        xxh[t] = xx;
        t = t + 1;
        
    }
    xxh[xxh.length] = XSTAR;
    return xxh;
}
var str = '<svg xmlns="http://www.w3.org/2000/svg" version="1.1">';
var previousvalue = 0;

for (var i = 0; i < 5; i++) {
    val = levyJump(i, 0.9, 20.0, 1.0);
    str += '<line x1="' + i * 10 + '" y1="' + previousvalue + '" x2="' + (i + 1) * 10 + '" y2="' + val * 10 + '" style="stroke:rgb(255,0,0);stroke-width:2" />';
    previousvalue = val * 10;

}
var previousX = 0;
var previousY = 0;
var str = '<svg xmlns="http://www.w3.org/2000/svg" version="1.1">';

var X = bat(fOptimize, 2, 50, 30, 0, 5, 0, 5);
var maxX=0;
var minX=9999999;
var maxY=0;
var minY=9999999;
for (var i = 0; i < X.length-1; i++) {
    var x = X[i][0][0];
    var y = X[i][0][1];
    if (x>maxX)
        maxX=x;
    if (y<minY)
        minY=y;
    if (y>maxY)
        maxY=y;
    if (x<minX)
        minX=x;
}
var maxouX=1;
var maxouY=1;
if (Math.abs(maxX)>maxouX)
    maxouX=Math.abs(maxX)/15;
if (Math.abs(minX)>maxouX)
    maxouX=Math.abs(minX)/15;
if (Math.abs(maxY)>maxouY)
    maxouY=Math.abs(maxY)/15;
if (Math.abs(minY)>maxouY)
    maxouY=Math.abs(minY)/15;

for (var j = 0; j < X[0].length; j++) {
    var colorq=j*5;
    var colorp=j*5;
    var colorr=j*5;
    if(Math.random()>0.5)
        colorr=0;
    if(Math.random()>0.5)
        colorp=0;
    if(Math.random()>0.5)
        colorq=0;
for (var i = 0; i < X.length-1; i++) {
    var x = Math.abs(X[i][j][0])/maxouX;
    var y = Math.abs(X[i][j][1])/maxouY;
   
    str += '<line x1="' + previousX + '" y1="' + previousY + '" x2="' + x * 10 + '" y2="' + y * 10 + '" style="stroke:rgb('+colorr+','+colorq+','+colorp+');stroke-width:2" />';
    previousX = x * 10;
    previousY = y * 10;

}
}

$("#graph").append(str + '</svg>');

$("#graph").append("Resultat=" + X[X.length - 1][0] + " " + X[X.length - 1][1]);


No comments: