我想知道以下内容: 如何使用值编码有效地生成具有高度多样性的染色体的初始生成? 一种方法是网格初始化,但速度太慢。
到目前为止,我一直在使用.NET中的Random类来选择值编码中的随机值,但是,尽管值均匀分布,但从这些染色体计算的适应度函数值却不是。这是染色体初始化的代码:
public Chromosome(Random rand)
{
Alele = new List<double>();
for (int i = 0; i < ChromosomeLength; i++)
{
Alele.Add(rand.NextDouble() * 2000 - 1000);
}
}
所以,我开发了一个函数来计算来自新的,随机制作的染色体(上层代码)的适应度,如果适应性与染色体列表中已有的任何其他相似,则随机制作新的染色体并计算其适应度。重复这个过程,直到他的健康状况与已经在列表中的那些不完全不同。
以下是此部分的代码:
private bool CheckSimilarFitnes(List<Chromosome> chromosome, Chromosome newCandidate)
{
Boolean flag=false;
double fitFromList, fitFromCandidate;
double fitBigger,fitSmaller;
foreach (var listElement in chromosome)
{
fitFromList = listElement.CalculateChromosomeFitness(listElement.Alele);
fitFromCandidate = newCandidate.CalculateChromosomeFitness(newCandidate.Alele);
fitBigger = fitFromList >= fitFromCandidate ? fitFromList : fitFromCandidate;
fitSmaller = fitFromList < fitFromCandidate ? fitFromList : fitFromCandidate;
if ((fitFromList / fitFromCandidate) < 1.5)
return false
}
else return true;
}
但是,我在列表中的染色体越多,添加一个新的染色体就会花费更长的时间,其健康状况与已经存在的其他染色体相差甚远。
那么,有没有办法让这个网格初始化更快,像这样制作80条染色体需要几天时间?
答案 0 :(得分:2)
这里的基本问题是大多数随机生成的染色体具有相似的适应性,对吧?没关系;这个想法不是因为你的初始染色体具有完全不同的适应性;染色体本身是不同的,大概是它们。事实上,你应该期望你的第一代大多数人的初始适应度接近零,因为你还没有运行算法。
这就是为什么你的代码太慢了。让我们说第一个候选人很糟糕,基本上是零健身。如果第二个必须是1.5倍不同,那真的只是意味着它必须要好1.5倍,因为它不会真的变得更糟。然后下一个比那个好1.5倍,等等到80.所以你真正在做的是通过生成完全随机的越来越好的染色体并将它们与你的比较有。我打赌如果你记录了进展,你会发现找到后续候选人需要花费越来越多的时间,因为很难找到真正好的染色体。但找到更好的染色体是GA的用途!基本上你所做的就是先用手优化一些染色体,嗯,实际上是优化它们。
如果你想确保你的染色体是多样的,比较它们的内容,不要比较它们的适应性。比较健康是算法的工作。
答案 1 :(得分:1)
我要快速摆动,但艾萨克非常正确。您需要让GA完成其工作。你有一代个体(染色体,无论如何),而且它们在健康方面的规模都很大(或者它们都是相同的)。
你选择一些好的变异(自己)和交叉(互相)。您可以使用前10%来产生另一个完整的人口,并将最低的90%抛弃。也许你总是保持顶级人物(精英主义)。
你对此进行了一段时间的迭代,直到你的GA停止改进,因为这些人都非常相似。你最终的人口差异很小。
可能对您有帮助的是1)使您的突变更有效; 2)找到更好的方法来选择突变的个体。在我的评论中,我建议AI Techniques for Game Programmers。这是一本好书。很容易阅读。
要列出书中的几个标题,您要找的东西是:
选择技术,例如Roulette Selection (on stackoveflow)(wikipedia)和Stochastic Universal Sampling,它们控制 您选择个人的方式。我一直很喜欢轮盘选择。您可以设置选择个人的概率。这不仅仅是简单的白噪声随机采样。
我在GA之外用它来随机选择罗马字母中的4个字母。我为每个字母分配了一个从0.0到1.0的值。每当用户(孩子)正确地选择该字母时,我会将该值降低,比如0.1。这将增加选择其他字母的可能性。如果在10次之后,用户选择了正确的字母,则该值将为0.0,并且(几乎)没有机会再次出现该字母。
<磅> 健身缩放技术,如Rank Scaling,Sigma Scaling和Boltzmann Scaling (pdf on ftp!!!),可让您修改原始适应度值,以提出经过调整的适应度值。其中一些是动态的,如Boltzmann Scaling,它允许您设置随时间变化的“压力”或“温度”。增加“压力”意味着选择更适合的人。压力下降意味着可以选择人口中的任何个体。我这样想:你正在通过多维空间搜索解决方案。你达到了“巅峰”并向前迈进了一步。适合的压力非常高。你紧紧抓住那个局部最大值。现在你的健身状况无法改变。你的突变并没有让你走出巅峰。所以你开始减轻压力,哦,随机选择项目。你的健康水平开始下降,暂时还可以。然后你开始再次增加压力,并且惊喜!你跳过了当地的最大值,发现了一个可爱的新的局部最大值进入。再次增加压力!
Niching (我从未使用过,但似乎是将同类人聚集在一起的一种方式)。假设你有两个相当不错的人,但他们却截然不同。他们一直被选中。他们不断变异,并没有变得更好。现在你有一半的人口是A的轻微变种,而你的一半人口是B的轻微变种。这似乎是一种说法,嘿,整个A组的平均适应度是多少?什么B?对于你所拥有的每一个利基都是如此。然后根据每个利基的平均适合度进行选择。选择你的利基,然后从该利基中选择一个随机的个人。也许我会开始使用它了。我喜欢它!
希望你能找到一些有用的东西!
答案 2 :(得分:0)
如果您的应用需要 true 随机数,我建议您查看Random.org。他们有一个免费的HTTP API和clients for just about every language。
随机性来自大气噪声,出于多种目的,它比计算机程序中通常使用的伪随机数算法更好。
(我与Random.org无关,虽然我确实贡献了PHP客户端)。
答案 3 :(得分:0)
我认为您的问题在于您的健身功能以及您如何选择候选人,而不是随机值如何。您的过滤感觉太严格,甚至可能无法接受足够的元素。
示例
使用此健身功能,您将很快获得大多数1个“斑点”(因为您最多有100个位置),因此每个下一个需要更长时间。在某些时候会有几个微小的范围,大多数结果都会被拒绝,更糟糕的是你得到大约50个数字的位置后很有可能下一个根本无法适应。