// Catalano Genetic Library
// The Catalano Framework
//
// Copyright © Diego Catalano, 2012-2019
// diego.catalano at live.com
//
//
//    This library is free software; you can redistribute it and/or
//    modify it under the terms of the GNU Lesser General Public
//    License as published by the Free Software Foundation; either
//    version 2.1 of the License, or (at your option) any later version.
//
//    This library is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//    Lesser General Public License for more details.
//
//    You should have received a copy of the GNU Lesser General Public
//    License along with this library; if not, write to the Free Software
//    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
//

package Catalano.Evolutionary.Metaheuristics.Monoobjective;

import Catalano.Core.DoubleRange;
import Catalano.Math.Tools;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Random;

/**
 * Salp Swarm Algorithm (SSA).
 * 
 * The main inspiration of SSA is the swarming behaviour of salps when navigating and foraging in oceans.
 * 
 * References:
 * S. Mirjalili, A.H. Gandomi, S.Z. Mirjalili, S. Saremi, H. Faris, S.M. Mirjalili.
 * "Salp Swarm Algorithm: A bio-inspired optimizer for engineering design problems." Advances in Engineering Software 114 (2017): 163-191.
 * 
 * @author Diego Catalano
 */
public class SalpSwarmAlgorithm extends BaseEvolutionaryOptimization{

    /**
     * Initializes a new instance of the SalpSwarmAlgorithm class.
     */
    public SalpSwarmAlgorithm() {
        this(30,1000);
    }
    
    /**
     * Initializes a new instance of the SalpSwarmAlgorithm class.
     * @param population Population size.
     * @param generations Generations.
     */
    public SalpSwarmAlgorithm(int population, int generations){
        this.populationSize = population;
        this.generations = generations;
    }

    @Override
    public void Compute(IObjectiveFunction function, List boundConstraints) {
        
        Random rand = new Random();

        //Reset variables
        minError = Double.MAX_VALUE;
        nEvals = 0;
        
        //Create the population
        List pop = Individual.CreatePopulation(populationSize, boundConstraints, function);
        Collections.sort(pop);
        
        minError = pop.get(0).getFitness();
        best = Arrays.copyOf(pop.get(0).getLocation(), boundConstraints.size());
        
        Collections.shuffle(pop);
        
        //Main algorithm
        for (int g = 0; g < generations; g++) {
            
            double c1 = 2 * Math.exp(-Math.pow(4*(g+1)/generations,2));
            
            for (int i = 0; i < pop.size(); i++) {
                
                if(i <= pop.size() / 2){
                    for (int j = 0; j < boundConstraints.size(); j++) {
                        DoubleRange range = boundConstraints.get(j);
                        if(rand.nextDouble() < 0.5)
                            pop.get(i).getLocation()[j] = best[j] + c1 * ((range.getMax() - range.getMin()) * rand.nextDouble() + range.getMin());
                        else
                            pop.get(i).getLocation()[j] = best[j] - c1 * ((range.getMax() - range.getMin()) * rand.nextDouble() + range.getMin());
                    }
                }
                else if (i > (pop.size()/2) && i < pop.size()){
                    double[] salp1 = pop.get(i-1).getLocation();
                    double[] salp2 = pop.get(i).getLocation();
                    
                    for (int j = 0; j < salp2.length; j++)
                        salp2[j] = (salp2[j] + salp1[j]) / 2;
                    
                }
            }
            
            //Clamp values
            for (int i = 0; i < pop.size(); i++)
                Tools.Clamp(pop.get(i).getLocation(), boundConstraints);
            
            
            //Calculate fitness
            for (int i = 0; i < pop.size(); i++) {
                double f = function.Compute(pop.get(i).getLocation());
                pop.get(i).setFitness(f);
                nEvals++;
                if(f < minError){
                    minError = f;
                    best = Arrays.copyOf(pop.get(i).getLocation(), boundConstraints.size());
                }
            }
            
            //Update on listener
            if(listener != null) listener.onIteration(g+1, minError);
            
        }
    }
}
 

Ads help maintain this website.