这是对这个问题中给出的答案的回应: How to create a good evaluation function for a game?,特别是@David(这是第一个答案)。
背景:我正在使用遗传算法来优化使用minimax / alpha beta修剪(迭代加深)的游戏代理中的超参数。特别是,我想使用遗传算法优化启发式(评估)函数参数。我使用的评估函数是:
f(w)= w * num_my_moves - (1-w)* num_opponent_moves
要优化的唯一参数是[0,1]中的w。
以下是我对遗传算法进行编程的方法:
我的问题:请评估上面的粗体点。特别是,有没有人有更好的方法来繁殖(而不是简单地平均父权重),并且有没有人有更好的方法进行变异,而不是仅仅添加random.uniform(-0.01,0.01)?
答案 0 :(得分:2)
看起来你实际上并没有将遗传算法应用于你的代理,而只是直接在表型/权重上进行简单的进化。我建议你尝试引入一个genetic representation的权重,然后改进这个基因组。一个例子是将权重表示为二进制字符串,并对字符串的每个位应用进化,这意味着每个位都有可能发生变异。这称为点突变。您可以应用许多其他突变,但它可以作为一个开始。
你会注意到你的代理人不会陷入局部最小值,因为有时候一个小的遗传变化会极大地改变表型/重量。
好的,这可能听起来很复杂,但事实并非如此。让我举个例子:
假设您在基数10中的权重为42
。这将是二进制的101010
。现在,您已在二进制表示的每个位上实现了1%的突变率。让我们说最后一位是翻转的。然后我们有二进制101011
或十进制43
。没有这么大的变化。另一方面,对第二位执行相同操作会为您提供二进制或111010
十进制的58
。注意大跳。这就是我们想要的,让您的代理人群更快地搜索解决方案空间的更大部分。
关于育种。你可以试试交叉。让我们假设您有许多权重,每个权重都有遗传编码。如果您将整个基因组(所有二进制数据)表示为一个长二进制字符串,您可以组合两个父母基因组的部分。示例,再次。以下是“父亲”和“母亲”的基因组和表型:
Weight Name: W1 W2 W3 W4 W5
Father Phenotype: 43 15 34 17 14
Father Genome: 101011 001111 100010 010001 001110
Mother Genome: 100110 100111 011001 010100 101000
Mother Phenotype: 38 39 25 20 40
您可以做的是在同一个地方通过两个基因组绘制任意线,并将这些线段任意分配给孩子。这是交叉版本。
Weight Name: W1 W2 W3 W4 W5
Father Genome: 101011 00.... ...... .....1 001110
Mother Genome: ...... ..0111 011001 01010. ......
Child Genome: 101011 000111 011001 010101 001110
Child Phenotype: 43 7 25 21 14
这里的前8位和后7位来自父亲,中间来自母亲。注意重量W1和W5完全来自父亲,而W3完全来自母亲。而W2和W4是组合。 W4几乎没有任何变化,而W2发生了巨大的变化。
我希望这能为您提供有关如何进行遗传算法的一些见解。也就是说,我建议使用现代化的库而不是自己实现它,除非你这样做是为了学习。
编辑:有关处理权重/二进制表示的更多信息:
42
和10
给出4.2
。)101010
或42
的二进制字符串,则执行42/63并获得0.667当63/63时,只能达到1.0。101010
和001000
获得W1
和W2
,则会得到42和8,然后您可以转到W1_scaled = W1 / (W1 + W2) = 0.84
和W2_scaled = W2 / (W1 + W2) = 0.16
。这应该总是给你W1_scaled + W2_scaled = 1
。答案 1 :(得分:0)
因为我被提及了。
我不是将父权重平均,而是使用父权重作为最小值/最大值来选择随机数。我另外发现我必须稍微扩大范围(当我平均两个均匀随机数,或平方(2),但我可能并不精确)抵抗拉力时,补偿标准偏差的减少接近平均水平。否则,人口会向平均值收敛,无法逃脱。
所以,如果父母'权重为0.1和0.2,它可能为孩子体重选择0.08和0.22之间的随机数。
延迟编辑:当时我还不知道的一种更为公认,研究,理解的方法是“差异进化”#34;