我正在尝试实现遗传算法以最大化n个变量的函数。然而问题是健身值可能是负的,我不确定如何在做选择时处理负值。我读过这篇文章Linear fitness scaling in Genetic Algorithm produces negative fitness values 但我不清楚如何处理负适应值以及如何计算比例因子a和b。
另外,从文章中我知道轮盘赌选择仅适用于积极适应值。锦标赛的选择也一样吗?
答案 0 :(得分:8)
如果您有负值,您可以尝试在人口中找到最小的适应值,并将其与每个值相反。这样您就不会有负值,而适应值之间的差异将保持不变。
答案 1 :(得分:6)
锦标赛选择不受此问题的影响。它只是比较群体大小为n的均匀采样子集的适应度值,并采用具有最佳值的那个。当然,这意味着,如果您在不重复的情况下进行采样,那么最糟糕的n-1个体将永远不会被选中。如果你重复抽样,他们有机会被选中。
与比例选择一样:它不适用于负适应值。您只能对您的健身值应用“窗口”或“缩放”,在这种情况下它们会再次起作用。
我曾经编写了一些sampling methods作为C#的IEnumerable的扩展方法,其中包括SampleProportional和SampleProportionalWithoutRepetition扩展方法。他们是GPL许可下的HeuristicLab的一部分。
答案 2 :(得分:0)
好的,答案来晚了,但是仍然有人可以用谷歌搜索它。
首先-是的,您可以使用负适应性。但我完全建议您不要这样做,因为我这样做了,并且遇到了很多问题(仍然可行,但完全不建议这样做)。所以这是解释:
假设您有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比现在好1.05,这意味着a和b的适应度几乎相同,这是完全不可接受的,因为它显然比a好2倍(当然,适应度是线性的,但这也会弄乱非线性适应度!)您无法逃脱这个问题,它会一直困扰您,因为概率不可能为负,因此您可以从进化中消除概率(这不是一件好事),也可以做一些例外,技巧。
由于在我的场景中消除负面适应能力为时已晚,因此,我采取以下方法来解决问题:
再次,您有N个生物种群。说neg(N)会给您所有否定适应性生物和pos(N)积极适应性生物(这是您要求使零为负或为正,在这种情况下没有关系)。假设您需要D个生物死亡。现在,这就是窍门:
f(c)(c是pos生物)值越高,生物越好,因此我们可以使用其适应性来确定生存的可能性。但是f(m)越低(负值越大)(m是负生物),则生物越差,因此我们可以使用其适应性来确定死亡的可能性。
现在,如果D> neg(N),则所有neg(N)将死亡,而pos(N)的(D-neg(N))将基于所有正生物适应性(概率)使用概率分布而死亡。生存概率p(a)= f(a)/ sum(pos(n)))。但是,如果D
答案 3 :(得分:0)
我知道这个问题已经存在很长时间了,但是如果新手想知道处理负值的最佳方法,那么您的问题就很少了。这是它的代码。
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)
答案 4 :(得分:0)
我认为人们遇到的主要问题是他们对健身得分的处理不当。让我们考虑一个适合性示例,例如,运送冷冻食品的卡车内部的温度。卡车的内部温度应为-2 C ...但也应为28.4F。相对于保持冷冻的食物,它们的精确度相同,但是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采样方法尽可能一致,我将只减去最小值,然后在出现负值时以少量适应度加回来。当一切都是好的时候,没有理由这样做。