【问题标题】:java version of bat algorithm in matlabmatlab中bat算法的java版本
【发布时间】:2013-03-31 10:13:27
【问题描述】:

我有一个蝙蝠算法的 Matlab 代码,我编写了这个算法的 java 版本 蝙蝠算法是一种简单的优化算法,用于寻找任何函数的最小值 这是matlab代码和我这段代码的java版本

我的这个算法的java版本找不到像matlab版本一样的最佳结果 而且我找不到将代码从matlab转换为java的错误在哪里

谁能帮助我我的错误在哪里?

import java.util.Random;

public class Bat
{
    private int n;
    private float A, r;
    private float Qmin, Qmax;
    private int d;
    private int NofGen;
    private float fmin;
    private int fminIndex;
    private float Fnew;
    private int loopCounter;

    private float Q[], V[][], Sol[][], UL_bound[][], fitness[], S[][], Best[];

    private Random myRand;

    public Bat(
            int NBats,
            float loudness,
            float pulseRate,
            float minFreq,
            float maxFreq,
            int NofGeneration,
            int dimension
            )
    {
        n = NBats;
        A = loudness;
        r = pulseRate;
        Qmin = minFreq;
        Qmax = maxFreq;
        NofGen = NofGeneration;
        d = dimension;

        S = new float[n][d];
        Best = new float[d];
        UL_bound = new float[2][d];

        //default bounds 
        for(int i = 0 ;  i < d ; i++)
        {
            UL_bound[0][i] = -10000;
            UL_bound[1][i] =  10000;
        }

        loopCounter = 0;
        myRand = new Random();

        Q = new float[n];
        for(int i = 0 ; i < n ; i++)
            Q[i] = 0;

        V = new float[n][d];
        for(int i = 0 ; i < n ; i++)
            for(int j = 0 ; j < d ; j++)
                V[i][j] = 0;

    }



    public void intial()
    {

        Sol = new float[n][d];
        for(int i = 0 ; i < n ; i++)
            for(int j = 0 ; j < d ; j++)
            {
                float t = myRand.nextFloat();
                //(upper -lower)*rand + lower
                Sol[i][j] = t * (UL_bound[1][j] - UL_bound[0][j]) + UL_bound[0][j];
            }


        fitness = new float[n];
        for(int i = 0 ; i < n ; i++)
            fitness[i] = function(Sol[i]);

        //finding fmin
        fmin = fitness[0];
        fminIndex = 0;
        for(int i = 0 ; i < n ; i++)
        {
            if (fitness[i] < fmin)
            {
                fmin = fitness[i];
                fminIndex = i;
            }
        }

        //setting best
        for(int j = 0 ; j < d ; j++)
            Best[j] = Sol[fminIndex][j];

    }

    public void start()
    {

        while(loopCounter < NofGen)
        {

            for(int i = 0 ; i < n ; i++)
            {

                Q[i] = Qmin + (Qmin - Qmax)* myRand.nextFloat();

                for(int j = 0 ; j < d ; j++)
                    V[i][j] = V[i][j] + (Sol[i][j]-Best[j])*Q[i];

                for(int j = 0 ; j < d ; j++)
                    S[i][j] = Sol[i][j] + V[i][j]; 

                Sol[i] = simpleBounds(Sol[i]);

                if(myRand.nextFloat() > r)          
                    for(int j = 0 ; j < d ; j++)
                        S[i][j] =  (float) (Best[j] + (.001 * myRand.nextFloat()) );

                Fnew = function(S[i]);

                if(Fnew <= fitness[i] && myRand.nextFloat() < A)
                {
                    for(int j = 0 ; j < d ; j++)
                        Sol[i][j] = S[i][j];

                    fitness[i] = Fnew;
                }

                if(Fnew <= fmin)
                {
                    fmin = Fnew;
                    for(int j = 0 ; j < d ; j++)
                        Best[j] = S[i][j];
                }

            }
            loopCounter++;

        }

    }

    public float[] simpleBounds(float p[])
    {
        for(int i = 0 ; i < d ; i++)
        {
            if(p[i] < UL_bound[0][i])
                p[i] = UL_bound[0][i];

            if(p[i] > UL_bound[1][i])
                p[i] = UL_bound[1][i];
        }
        return p;
    }
    float function(float p[])
    {
        // Sphere function with fmin=0 at (0,0,...,0)
        float sum = 0;
        for(int i = 0 ;  i < p.length  ; i++)
            sum = sum + p[i]*p[i];
        return sum;

    }
    public float printResult()
    {
        System.out.println("After " + loopCounter + "Repeats :");

        for(int i = 0 ; i < d ; i++)
            System.out.print(Best[i] + ", ");

        System.out.println ( "F(x)  = " + fmin);
        return fmin;
    }

    public void set_UL_Bound(int n, float L, float U)
    {
        if( n < d && n >= 0)
        {
            UL_bound[0][n] = L;
            UL_bound[1][n] = U;
        }
    }   




}

这是matlab版本

function [best,fmin,N_iter]=bat_algorithm(para)
% Display help
 help bat_algorithm.m

% Default parameters
if nargin<1,  para=[20 1000 0.5 0.5];  end
n=para(1);      % Population size, typically 10 to 40
N_gen=para(2);  % Number of generations
A=para(3);      % Loudness  (constant or decreasing)
r=para(4);      % Pulse rate (constant or decreasing)
% This frequency range determines the scalings
% You should change these values if necessary
Qmin=0;         % Frequency minimum
Qmax=2;         % Frequency maximum
% Iteration parameters
N_iter=0;       % Total number of function evaluations
% Dimension of the search variables
d=5;           % Number of dimensions 
% Lower limit/bounds/ a vector
Lb=-3*ones(1,d);
% Upper limit/bounds/ a vector
Ub=6*ones(1,d);
% Initializing arrays
Q=zeros(n,1);   % Frequency
v=zeros(n,d);   % Velocities
% Initialize the population/solutions
for i=1:n,
  Sol(i,:)=Lb+(Ub-Lb).*rand(1,d);
  Fitness(i)=Fun(Sol(i,:));
end
% Find the initial best solution
[fmin,I]=min(Fitness);
best=Sol(I,:);


for t=1:N_gen, 
% Loop over all bats/solutions
        for i=1:n,
          Q(i)=Qmin+(Qmin-Qmax)*rand;
          v(i,:)=v(i,:)+(Sol(i,:)-best)*Q(i);
          S(i,:)=Sol(i,:)+v(i,:);
          % Apply simple bounds/limits
          Sol(i,:)=simplebounds(Sol(i,:),Lb,Ub);
          % Pulse rate
          if rand>r
          % The factor 0.001 limits the step sizes of random walks 
              S(i,:)=best+0.001*randn(1,d);
          end

     % Evaluate new solutions
           Fnew=Fun(S(i,:));
     % Update if the solution improves, or not too loud
           if (Fnew<=Fitness(i)) & (rand<A) ,
                Sol(i,:)=S(i,:);
                Fitness(i)=Fnew;
           end

          % Update the current best solution
          if Fnew<=fmin,
                best=S(i,:);
                fmin=Fnew;
          end
        end
        N_iter=N_iter+n;
end
% Output/display
disp(['Number of evaluations: ',num2str(N_iter)]);
disp(['Best =',num2str(best),' fmin=',num2str(fmin)]);

% Application of simple limits/bounds
function s=simplebounds(s,Lb,Ub)
  % Apply the lower bound vector
  ns_tmp=s;
  I=ns_tmp<Lb;
  ns_tmp(I)=Lb(I);

  % Apply the upper bound vector 
  J=ns_tmp>Ub;
  ns_tmp(J)=Ub(J);
  % Update this new move 
  s=ns_tmp;


function z=Fun(u)
% Sphere function with fmin=0 at (0,0,...,0)
z=sum(u.^2);
%%%%% ============ end ====================================

【问题讨论】:

  • 在调试器中同时运行并逐步执行它们直到结果不同?
  • 结果的差异可能是由于(某些)变量的精度不同造成的。在 Java 中你声明了很多浮点数,在 Matlab 中你的变量默认是双精度的;我没有看到任何证据表明您已将任何 Matlab 变量设为非默认类型。
  • 谢谢你,我会把所有的花车都换成双倍的

标签: java algorithm matlab random


【解决方案1】:
  • 两个代码之间的差异

在 Matlab 代码中:

S(i,:)=最佳+0.001*randn(1,d);

randn=>标准正态分布。

在 Java 代码中:

S[i][j] = (float) (Best[j] + (.001 * myRand.nextFloat()) );

java.util.Random.nextFloat()=>均匀分布介于 0.0 和 1.0 之间的浮点值。

【讨论】:

    【解决方案2】:

    我正在寻找 C# 中的解决方案并偶然发现了这一点。这足以完成工作。这是从 java 中翻译过来的 C# 解决方案,其中变量重命名,还有一个额外的适应度函数,用于找到两个 x,y 方程 xy=6 和 x+y = 5 的解。还包括找到 .3 的平方根:

        using System;
    
        namespace BatAlgorithmC
    
        namespace BatAlgorithmC
        {
            class Program
            {
                static void Main(string[] args)
                {
               //     Mybat x = new Mybat(100, 1000, 0.5, 0.5, 5, Mybat.sphere);
            //      Mybat x = new Mybat(1000, 1000, 0.5, 0.5, 1, Mybat.squareRoot);
    
                Mybat x = new Mybat(1000, 1000, 0.5, 0.5, 2, Mybat.RootOfXYEquations);
                    Console.WriteLine("Hit any key to continue.");
                    Console.ReadLine();
    
    
                }
    
    
    
            }
    
            public class Mybat
            {
        /**
         * @param args the command line arguments
         */
                public int _numberOfBats, _generations, Qmin, Qmax, N_iter, _dimension;
                public double _volume, _pulseRate, min, max, fnew, fmin;
                public double[][] _lowerBound, _upperBound, _velocity, _solution, S;
                public double[] _fitness, _tempSolution, _bestSolution, Q;
                public Random random;
        //public static void main(String[] args) {
        //   Mybat x = new Mybat(20,1000,0.5,0.5,5, Mybat.sphere);
    
        //}
    
                public static void initJagged(double[][] array, int n, int d)
                {
                    for (int i = 0; i < n; i++) array[i] = new double[d];
                }
    
                public Mybat(
                    int bats,
                    int generations,
                    double loud,
                    double pulse,
                    int dimension,
                    Func<double[], int, double> function
                    )
                {
                    //initialization of variables
                    _numberOfBats = bats;
                    _generations = generations;
                    _volume = loud;
                    _pulseRate = pulse;
                    _dimension = dimension;
    
                    Random random = new Random();
    
                    //plan to change later and added as parameter
                    min = -15;
                    max = 15;
    
    
                    fmin = 0;
                    //decleration for the bounds
                    _lowerBound = new double[1][];
                    _upperBound = new double[1][];
    
                    Q = new double[_numberOfBats]; // frequency
                    _velocity = new double[_numberOfBats][]; //velocity
    
                    initJagged(_velocity, _numberOfBats, _dimension);
                    initJagged(_lowerBound, 1, _dimension);
                    initJagged(_upperBound, 1, _dimension);
    
    
                    //initialize solution array 
                    _solution = new double[_numberOfBats][];
                    S = new double[_numberOfBats][];
                    _fitness = new double[_numberOfBats]; // fitness container
                    _bestSolution = new double[_dimension];
                    _tempSolution = new double[_dimension]; //temporary holder for a row in array _solution
    
                    initJagged(_solution, _numberOfBats, _dimension);
                    initJagged(S, _numberOfBats, _dimension);
    
                    for (int i = 0; i < _numberOfBats; i++)
                    {
                        // for minimal coding : added initialize Q[]array with '0' as element
                        Q[i] = 0;
    
                        for (int x = 0; x < _dimension; x++)
                        {
                            // for minimal coding : added initialize _velocity[][] array with '0' as element
                            _velocity[i][x] = 0;
    
                            //find random double values from LB to UB
                            _solution[i][x] = (random.NextDouble()*(max - min)) + min;
                            _tempSolution[x] = _solution[i][x];
                            //Console.WriteLine("sol["+i+"]["+x+"] = "+_solution[i][x]); //test line
                            //Console.WriteLine(rand.nextDouble()); //test line
                        }
                        _fitness[i] = function(_tempSolution, _dimension);
    
                        //initialize best and the fmin
                        if (i == 0 || fmin > _fitness[i])
                        {
                            fmin = _fitness[i];
    
                            for (int x = 0; x < _dimension; x++)
                            {
                                _bestSolution[x] = _solution[i][x];
                            }
                        }
                        Console.WriteLine("fitness[" + i + "]" + _fitness[i]); //test
                    }
                    Console.WriteLine("fmin = " + fmin); //test
    
                    // special note to these variables (below)
                    // change if required for maximum effectivity
                    Qmin = 0;
                    Qmax = 2;
                    N_iter = 1; //number of function evaluation
    
                    // bat proper
                    for (int loop = 0; loop < N_iter; loop++)
                    {
                        // loop over all bats/solutions
                        for (int nextBat = 0; nextBat < _numberOfBats; nextBat++)
                        {
                            Q[nextBat] = Qmin + ((Qmin - Qmax)*random.NextDouble());
    
                            // loop for velocity
                            for (int vel = 0; vel < _dimension; vel++)
                            {
                                _velocity[nextBat][vel] = _velocity[nextBat][vel] +
                                                          ((_solution[nextBat][vel] - _bestSolution[vel])*Q[nextBat]);
                            }
    
                            //new solutions
                            for (int nextDimension = 0; nextDimension < _dimension; nextDimension++)
                            {
                                S[nextBat][nextDimension] = _solution[nextBat][nextDimension] +
                                                            _velocity[nextBat][nextDimension];
                            }
    
                            /**
                     * RESERVED SPOT for the QUESTIONABLE AREA ON THE 
                     * MATLAB CODE (i think it is not needed for the java equivalent)
                     */
    
                            // pulse rate
                            if (random.NextDouble() > _pulseRate)
                            {
                                for (int nextDimension = 0; nextDimension < _dimension; nextDimension++)
                                {
                                    S[nextBat][nextDimension] = _bestSolution[nextDimension] + (0.001*random.NextGaussian());
                                }
                            }
    
                            //putting current row of _solution to a temp array
                            for (int nextDimension = 0; nextDimension < _dimension; nextDimension++)
                            {
                                _tempSolution[nextDimension] = S[nextBat][nextDimension];
                            }
                            fnew = function(_tempSolution, _dimension);
    
                            // update if solution is improved, and not too loud
                            if ((fnew <= _fitness[nextBat]) && (random.NextDouble() < _volume))
                            {
                                for (int x = 0; x < _dimension; x++)
                                {
                                    _solution[nextBat][x] = S[nextBat][x];
                                    _fitness[nextBat] = fnew;
                                }
                            }
    
                            //update current best solution
                            if (fnew <= fmin)
                            {
                                for (int nextDimension = 0; nextDimension < _dimension; nextDimension++)
                                {
                                    _bestSolution[nextDimension] = S[nextBat][nextDimension];
                                    fmin = fnew;
                                }
                            }
                        }
                    }
    
                    Console.WriteLine(" ");
                    Console.WriteLine("new fitness");
                    for (int i = 0; i < _numberOfBats; i++)
                    {
                        Console.WriteLine("fitness[" + i + "]" + _fitness[i]);
                    }
    
                    for (int nextDimension = 0; nextDimension < _dimension; nextDimension++)
                    {
                        Console.WriteLine("best[" + nextDimension + "]" + _bestSolution[nextDimension]);
                    }
                    Console.WriteLine("Fmin = " + fmin);
                }
    
        //possible that this function is not needed in java
                public void set_bounds(int x, double L, double U)
                {
                    //double temp_Lb[x];
                    //double temp_Ub[x];
                    for (int i = 0; i < x; i++)
                    {
                        _lowerBound[0][i] = L;
                        _upperBound[0][i] = U;
                    }
                }
    
                public static double sphere(double[] value, int d)
                {
                    // sphere function where fmin is at 0
                    double result = 0;
    
                    for (int i = 0; i < d; i++)
                    {
                        result += (value[i]*value[i]);
                    }
                    return result;
                }
    
                public static double squareRoot(double[] value, int d)
                {
                    // find the square root of .3
                    double result = 0;
    
                    for (int i = 0; i < d; i++)
                    {
                        result += Math.Abs(.3 - (value[i]*value[i]));
                    }
                    return result;
                }
    
        public static double RootOfXYEquations(double[] value, int d)
        {
            // solve for x and y  xy = 6  and x+y = 5
            double result = 0;
    
            result += Math.Abs(5 - (value[0] + value[1]));
            result += Math.Abs(6 - (value[0] * value[1]));
    
    
            return result;
        }
            }
    
    
            static class MathExtensiionns
            {
                public static double NextGaussian(this Random rand)
                {
                double u1 = rand.NextDouble(); //these are uniform(0,1) random doubles
                double u2 = rand.NextDouble();
                double mean = 0, stdDev = 1;
                double randStdNormal = Math.Sqrt(-2.0 * Math.Log(u1)) *
                             Math.Sin(2.0 * Math.PI * u2); //random normal(0,1)
                double randNormal =
                             mean + stdDev * randStdNormal; //random normal(mean,stdDev^2)
                return randNormal;
                }
            }
        }
    

    【讨论】:

      【解决方案3】:

      这将是我第一次出现堆栈溢出,所以如果我的回答有点模棱两可并且有很多问题,我会事先说抱歉。我只是希望我的这个答案能帮助这个线程上想要通过java学习蝙蝠算法的未来访问者。

      无论如何,我确实看过你的代码,因为我目前正在研究蝙蝠算法。 尝试运行它,与 matlab 版本相比,它确实给出了很远的结果。

      我注意到的是,您只是“从字面上”尝试转换 matlab 代码而没有完全理解每个 matlab 行。我想指出你错过的所有东西,但我现在感觉很懒,所以我将把我的 bat 算法版本留在 java 中。

      注意:我刚刚在 java 中做了一个运行中的 bat 算法。不是一个高效的、完全调试的、matlab 的 java 等效 bat 算法。

      import java.util.Random;
      
       public class Mybat {
      
      /**
       * @param args the command line arguments
       */
      public int n, N_gen, Qmin, Qmax, N_iter, d;
      public double A,r,min,max,fnew,fmin;
      public double Lb[][],Ub[][],Q[],v[][],Sol[][],S[][],fitness[],temp[],best[];
      public Random random;
      public static void main(String[] args) {
         Mybat x = new Mybat(20,1000,0.5,0.5,5);
      
      }
      
      public Mybat(
              int bats,
              int generations,
              double loud,
              double pulse,
              int dimension
              ){
      
          //initialization of variables
          n=bats;
          N_gen = generations;
          A = loud;
          r = pulse;
          d = dimension;
      
          Random rand = new Random();
      
          //plan to change later and added as parameter
          min = -15;
          max = 15;
      
      
          fmin = 0;
              //decleration for the bounds
          Lb = new double[1][d];
          Ub = new double[1][d];
      
          Q = new double[n]; // frequency
          v = new double[n][d]; //velocity
      
      
          //initialize solution array 
          Sol = new double[n][d];
          S = new double[n][d];
          fitness = new double[n]; // fitness container
          best =new double[d];
          temp = new double[d];  //temporary holder for a row in array Sol
      
          for(int i=0;i<n;i++){
      
              // for minimal coding : added initialize Q[]array with '0' as element
              Q[i] = 0;
      
              for(int x=0;x<d;x++){
      
                  // for minimal coding : added initialize v[][] array with '0' as element
                  v[i][x] = 0;
      
                  //find random double values from LB to UB
                  Sol[i][x]= (rand.nextDouble()*(max - min)) + min;
                  temp[x] = Sol[i][x];
                  //System.out.println("sol["+i+"]["+x+"] = "+Sol[i][x]); //test line
                  //System.out.println(rand.nextDouble()); //test line
              }
              fitness[i] = function(temp);
      
              //initialize best and the fmin
              if(i==0 || fmin > fitness[i]){
                  fmin = fitness[i];
      
                  for(int x=0;x<d;x++){
                      best[x] = Sol[i][x];
                  }
              }
              System.out.println("fitness["+i+"]"+fitness[i]); //test
          }
          System.out.println("fmin = "+fmin); //test
      
              // special note to these variables (below)
              // change if required for maximum effectivity
          Qmin = 0;
          Qmax = 2;
          N_iter = 1; //number of function evaluation
      
          // bat proper
          for(int loop=0;loop<N_iter;loop++){
      
              // loop over all bats/solutions
              for(int i=0;i<n;i++){
                  Q[i] = Qmin+((Qmin-Qmax)*rand.nextDouble());
      
                  // loop for velocity
                  for(int vel=0;vel<d;vel++){
                      v[i][vel] = v[i][vel]+((Sol[i][vel]-best[vel])*Q[i]);  
                  }
      
                  //new solutions
                  for(int x=0;x<d;x++){
                      S[i][x] = Sol[i][x] + v[i][x];
                  }
      
                  /**
                   * RESERVED SPOT for the QUESTIONABLE AREA ON THE 
                   * MATLAB CODE (i think it is not needed for the java equivalent)
                   */
      
                  // pulse rate
                  if(rand.nextDouble()>r){
                      for(int x=0;x<d;x++){
                          S[i][x] = best[x]+(0.001*rand.nextGaussian());
                      }
                  }
      
                  //putting current row of Sol to a temp array
                  for(int x=0;x<d;x++){
                      temp[x] = S[i][x];
                  }
                  fnew = function(temp);
      
                  // update if solution is improved, and not too loud
                  if((fnew<=fitness[i]) && (rand.nextDouble()<A)){
                      for(int x=0;x<d;x++){
                          Sol[i][x] = S[i][x];
                          fitness[i] = fnew;
                      }
                  }
      
                  //update current best solution
                  if(fnew<=fmin){
                      for(int x=0;x<d;x++){
                          best[x] = S[i][x];
                          fmin = fnew;
                      }
                  }
              }
      
          }
      
          System.out.println(" ");
          System.out.println("new fitness");
          for(int i=0;i<n;i++){
      
              System.out.println("fitness["+i+"]"+fitness[i]);
          }
          System.out.println("Fmin = "+fmin);
      }
      
      //possible that this function is not needed in java
      public void set_bounds(int x, double L, double U){
          //double temp_Lb[x];
          //double temp_Ub[x];
          for(int i=0; i<x; i++){
              Lb[0][i] = L;
              Ub[0][i] = U;
          }
      
      }
      
      public double function(double value[]){
          // sphere function where fmin is at 0
          double result = 0;
      
          for(int i=0;i<d;i++){
              result += (value[i]*value[i]);
          }
          return result;
      }
      
      
      }
      

      【讨论】:

        猜你喜欢
        • 2018-10-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-07
        相关资源
        最近更新 更多