【问题标题】:genetic algorithm handling negative fitness values处理负适应值的遗传算法
【发布时间】:2020-10-11 08:58:44
【问题描述】:

我正在尝试实现遗传算法来最大化 n 个变量的函数。然而问题是适应度值可能是负数,我不确定在进行选择时如何处理负值。我读了这篇文章Linear fitness scaling in Genetic Algorithm produces negative fitness values 但我不清楚如何处理负适应度值以及如何计算缩放因子 a 和 b。

另外,从文章中我知道轮盘赌选择只适用于正适应值。锦标赛选择也一样吗?

【问题讨论】:

    标签: genetic-algorithm


    【解决方案1】:

    当您有负值时,您可以尝试在您的总体中找到最小的适应度值,并将其相反的值添加到每个值中。这样,您将不再有负值,而适应度值之间的差异将保持不变。

    【讨论】:

    • 正确:实际上,您将值标准化为正范围。
    • 如果即使在没有负值的情况下也应用这个,那也不是问题,对吧?我只是想避免检查负值。
    • @vjain27 据我所知,这应该不是问题。轮盘赌的选择已经考虑了人群的平均适应度,所以选择应该不会受到影响。
    • 不,你的标准化不一样。如果您只是将其向上移动以使每个值都为正,则最小的适应度值变为 0,因此绝对没有机会被选中,而之前它可能有机会。我并不是说有另一种方法,只是它不一样。
    • 这些天我遇到了类似的问题,我已经通过增加适应度来解决它,使得最小值的值更大(不等于)为 0,从而有机会被选中。
    【解决方案2】:

    比赛选择不受此问题的影响。它只是比较总体大小为 n 的均匀采样子集的适应度值,并取具有最佳值的那个。当然,这仍然意味着,如果您不重复抽样,那么最差的 n-1 个人将永远不会被选中。如果您重复采样,他们就有机会被选中。

    与比例选择一样:它不适用于负适应度值。您只能对您的健康值应用“窗口化”或“缩放”,在这种情况下它们会再次起作用。

    我曾经编写了一些sampling methods 作为C# IEnumerable 的扩展方法,其中有一个SampleProportional 和SampleProportionalWithoutRepetition 扩展方法。它们是 GPL 许可下 HeuristicLab 的一部分。

    【讨论】:

    • 非常感谢!我想知道重复是否会导致问题。这里重复似乎是一个不错的选择,但有什么理由不去。
    • 好吧,您确实必须使用重复,因为您需要多次选择一些解决方案,因为您需要为您的父母提供 2 * 人口规模。您可以选择每一对而无需重复,但总的来说,这并不值得关心。除非您的人口规模较小。但是,如果它们达到数百个,那么解决方案与自身交配的机会就非常渺茫了。
    【解决方案3】:

    好的,回复晚了,不过还是有人可以google一下。

    首先 - 是的,您可以使用负适应度。但是我完全不建议你这样做,因为我已经这样做了并且遇到了很多问题(仍然可行,但完全不推荐)。所以这里是解释:

    假设你有 N 个生物种群。经过模拟,它们都有一些适应度值 f(n),其中 f(n) 是适应度,n 是生物数量。在此之后,您想要建立一些概率分布来确定应该杀死哪些生物(当然您可以删除 40% 的最差生物,但如果您使用分布会更好)。你如何建立这样的分布?假设 f(a) = 50 和 f(b) = 100,所以生物 b 比生物 a 好 2 倍,所以你可能想要 生物 a 的生存概率是生物 b 的 2 倍(如果您的适应度值是线性的,则非常有意义)。如果您想知道如何操作:

    假设 sum( f (n) ) 是所有适应度值的总和。然后 生物 a 的生存概率 p(a) 为:

    p(a) = f(a) / sum( f(n) )

    这样就可以了。

    但是现在让我们允许负适应度。假设 f(a) = 50,f(b) = 100,f(c) = -1000。 b 再次比 a 好 2 倍,这是有道理的,但它比 c 好 -10 倍?没有意义。上面的绅士建议你添加最差健身价值的反对意见,这有点可以“解决”你的情况,但实际上并没有(我之前犯过同样的错误)。好的,让我们在所有适应度值上加 1000:

    f(a) = 1050, f(b) = 1100, f(c) = 0,所以现在c的生存概率为零,好吧,我们可以接受。但是现在让我们比较一下 a 和 b:

    b 现在比 a 好 1.05,这意味着 a 和 b 的适应度几乎相同,这是完全不能接受的,因为它显然比 a 好 2 倍(当然是假设适应度是线性的,但这也会弄乱非线性适应度)!你无法逃避这个问题,它会不断地妨碍你,因为概率不可能是负数,所以你可以从进化中移除概率(这不是很好的事情)或者你可以做一些例外和技巧。

    由于在我的场景中消除负面适应度为时已晚,因此这是我解决问题的方法:

    再一次,你有 N 个生物的种群。假设 neg(N) 给你所有负适应度生物和 pos(N) 正适应度生物(在这种情况下,你可以调用零负或正值)。假设你需要 D 个生物去死。现在这是诀窍:

    f( c ) ( c 是 pos 生物) 值越高,生物越好,所以我们可以用它的适应度来确定生存的概率。但是 f( m ) 越低(负数越大)(m 是 neg 生物),生物越差,所以我们可以使用它的适应度来确定死亡的概率。

    现在,如果 D > neg(N) 则所有 neg(N) 都会死亡,并且 pos(N) 的 (D-neg(N)) 将使用基于所有正生物适应度(probability生存率 p(a) = f(a) / sum( pos(n) ) )。但是如果 D dying 的概率),neg(N) 中的 D 个生物将死亡p(a) = f(a) / sum( neg(n) ) (f(a) 为负,但 sum( neg(n) ) 也为负,因此概率为正)。

    【讨论】:

      【解决方案4】:

      我知道这个问题已经存在很长时间了,但是如果新人想知道处理负值的最佳方法,那么您的问题也是最小的。这是它的代码。

      from numpy import min, sum, ptp, array 
      from numpy.random import uniform 
      
      list_fitness1 = array([-12, -45, 0, 72.1, -32.3])
      list_fitness2 = array([0.5, 6.32, 988.2, 1.23])
      
      def get_index_roulette_wheel_selection(list_fitness=None):
          """ It can handle negative also. Make sure your list fitness is 1D-numpy array"""
          scaled_fitness = (list_fitness - min(list_fitness)) / ptp(list_fitness)
          minimized_fitness = 1.0 - scaled_fitness
          total_sum = sum(minimized_fitness)
          r = uniform(low=0, high=total_sum)
          for idx, f in enumerate(minimized_fitness):
              r = r + f
              if r > total_sum:
                  return idx
      
      get_index_roulette_wheel_selection(list_fitness1)
      get_index_roulette_wheel_selection(list_fitness2)
      
      1. 确保你的健身列表是一维numpy数组
      2. 将适应度列表缩放到范围 [0, 1]
      3. 将最大问题转换为最小问题 1.0 - scaled_fitness_list
      4. 随机一个介于 0 和 sum(minimizzed_fitness_list) 之间的数字
      5. 继续在最小化适应度列表中添加元素,直到我们得到大于总和的值
      6. 你可以看到适应度是否小 --> 它在minimized_fitness 中有更大的值 --> 它有更大的机会相加并使值大于总和。

      【讨论】:

        【解决方案5】:

        我认为人们在这里遇到的主要问题是他们对健身分数的处理不当。让我们考虑一个示例健身分数,即运输冷冻货物的卡车内部的温度。卡车的内部温度应该是 -2 摄氏度……但这也是 28.4 华氏度。相对于保持冷冻的食物,它们的适合度完全相同,但是 2 * -2 = -4,而 2 * 28.4 是 56.8。 “冷两倍”在这里没有任何意义(-4 C!= 14.2 F)。与健身分数相同。

        Volot's example 中的 -1000 的情况下,50 和 100 之间的差异实际上相对较小:重要的是你会选择 -1000 以上的任何一个/两个,如果你肯定会这样做您只需从所有内容中减去 -1000。那么下一代孩子的体能分数可能是 50、100、200 和 10,比方说。现在 50 和 100 之间的差异更加明显,50 被选中的机会要低得多。请记住,遗传算法是迭代的。这也让我想起一句话:你不必跑得比熊还快。你只需要跑得比你旁边的人快。 50 只需要超过 -1000 就可以生存繁殖。

        也可以避免减去最小值导致 0 的问题。在估计概率分布时,人们会在每个(已知的)可能结果中添加 1 次,这样仍然可以捕获极其罕见的事件。健身分数变得有些棘手。你不能只加 1。如果你的健康分数是 0.01、0.02 和 -0.01 怎么办? 1.03、1.02 和 1.00 将导致选择低相对适应度。您可以改为将最低的非零值添加到所有内容中,得到 0.04、0.05 和 0.02。对于 -1000 的情况,它会产生 2150、2100 和 1050(因此,过去为 0 的所有内容将始终是被选中的下一个最低适应度的一半)

        不过,为了使事情尽可能与更典型的 GA 采样方法保持一致,我只会在存在负值时减去最小值并添加少量的适应度。当一切都是积极的,没有理由这样做。

        【讨论】:

          猜你喜欢
          • 2019-09-07
          • 2023-03-16
          • 2020-05-12
          • 2013-04-18
          • 2023-03-04
          • 1970-01-01
          • 2017-12-16
          • 1970-01-01
          • 2023-02-20
          相关资源
          最近更新 更多