【问题标题】:Roulette wheel selection for function minimization轮盘选择功能最小化
【发布时间】:2012-02-04 08:07:00
【问题描述】:

This question answers pseudocode for roulette wheel selection。但这是为了最大化问题。但我的问题是最小化适应度函数的值。这意味着,适应度低的个体比适应度高的个体获得更高的被选中概率。我该如何实现?

提前致谢。

【问题讨论】:

    标签: genetic-algorithm roulette-wheel-selection


    【解决方案1】:

    使用相同的算法但使每个个体的比例=maxfitness - fitness

    【讨论】:

    • 对于现实生活中的问题,MAX_FITNESS 不太可能像 MIN_FITNESS 一样知道。
    • 我不应该使用常量指示大写字母。轮盘赌的 maxFitness 是当前一代的最大适应度,因为轮盘赌/彩票的大小是当前一代适应度的总和。
    【解决方案2】:

    将适应度更改为 Fitness_new = 1 / Fitness_old,您又遇到了最大化问题。如果fitness_old = 0是可能的,则分母加1以避免被零除。

    【讨论】:

      【解决方案3】:
      import java.util.Random;
      import java.util.Arrays;
      import java.util.Comparator;
      
      class MyComparator implements Comparator
      {
          public int compare(Object o1, Object o2)
          {
              Number n1 = (Number) o1;
              Number n2 = (Number) o2;
      
              if(n1.jump > n2.jump)
              {
                  return 1;
              }
              else if(n1.jump < n2.jump)
              {
                  return -1;
              }
              else
              {
                  return 0;
              }
          }
      }
      
      
      class Number
      {
          public double i;
          public int pos;
          public double jump = 0;
      
      
          public Random r = new Random();
      
          public Number(int pos)
          {
              this.pos = pos;
      
              i = r.nextInt();
          }
      }
      
      
      public class Temp
      {
          public static  void main(String[] args)
          {
              Number[] n = new Number[50];
      
              double total = 0;
      
              for(int i=0; i<50; i++)
              {
                  n[i] = new Number(i);
      
                  total += n[i].i;
              }
      
              for(int i=0; i<50; i++)
              {
                  n[i].jump = n[i].i/total;
              }
      
      
              Arrays.sort(n, new MyComparator());     
      
              for(int i=0; i<50; i++)
              {
                  System.out.print(n[i].pos + ", ");
              }
      
              System.out.println();
      
              for(int i=0; i<50; i++)
              {
                  n[i].jump = n[i].i / total;
                  n[i].jump = 1-n[i].jump;
              }
      
              Arrays.sort(n, new MyComparator());     
      
              for(int i=0; i<50; i++)
              {
                  System.out.print(n[i].pos + ", ");
              }
      
              System.out.println();   
          }
      }
      

      在上面的例子中,说 Number 类是你的个人类,i 是适应度,jump 是被选为父类的概率。首先,我们像以前一样计算被选为父母的概率。在这一步,适应度越高,概率越高。然后我们从 1 中减去概率。这使适应度较低的个体具有较高的适应度(为了选择而使用伪适应度)。现在重新计算概率。看,存在的顺序完全颠倒了。

      【讨论】:

        【解决方案4】:

        由于缩放,轮盘不能用于最小化。此外,当适应度为负或为空时,也不能使用它,因为它们的概率为负或为空。

        根据 Larry 的建议,您可以通过将每个个体的适应度减去您的群体的最大适应度来使用局部归一化,但您必须再次确定最大适应度,使其不具有零概率。

        p>

        我建议您使用已被证明比轮盘赌好多次的锦标赛选择。

        【讨论】:

          【解决方案5】:

          可能为时已晚,但我不推荐max_fitness - fitness,因为你会失去最糟糕的元素(它们可以帮助探索)。相反,您可以进行某种反转。

          def roulette_selection(population):
              fs = [fitness(i) for i in population]
              sum_fs = sum(fs)
              max_fs = max(fs)
              min_fs = min(fs)
              p = random()*sum_fs
              t = max_fs + min_fs
              choosen = population[0]
              for i in population:
                  if MAXIMIZATION:
                      p -= fitness(i)
                  elif MINIMIZATION:
                      p -= (t - fitness(i))
                  if p < 0:
                      choosen = i
                      break
              return choosen
          

          【讨论】:

            【解决方案6】:

            反转概率顺序的简单方法:

            假设原始概率列表[p1,p2,p3,...,pn] 是针对人口中的个体的。

            为了颠倒顺序,对于这个列表中的每个pi,我们得到new_pi = (1-pi) / (n-1)

            说明:

            由于0&lt;=pi&lt;=1(1-pi)的值使得更小的概率得到更大的值。

            由于(1-pi)i之和从1n变为n-1,除以(n-1)(归一化)后,我们确定0&lt;=new_pi&lt;=1

            代码示例:

            def rouletteWheelSelect(population):
                fitnessSum = 0
                for individual in population:
                    fitnessSum += individual.fitness
                for individual in population:
                    individual.selectProb = individual.fitness / fitnessSum
                probSum = 0
                wheelProbList = []
                if MAXIMIZATION_PROBLEM:
                    for individual in population:
                        probSum += individual.selectProb
                        wheelProbList.append(probSum)
                elif MINIMIZATION_PROBLEM:
                    for individual in population:
                        probSum += (1-individual.selectProb) / (POPULATION_SIZE-1)
                        wheelProbList.append(probSum)
                r = random.random()  # 0<=r<1
                for i, p in enumerate(wheelProbList):
                    if r < p:
                        return population[i]
                return None
            

            【讨论】:

              猜你喜欢
              • 2019-03-15
              • 2017-11-09
              • 1970-01-01
              • 2018-07-04
              • 1970-01-01
              • 2012-06-01
              • 2014-08-27
              • 2010-09-22
              • 2021-06-02
              相关资源
              最近更新 更多