在你的 if 语句中,用变量替换硬编码的数字,并在每一代开始时更新它们。
您的 if 语句有效地将区间 0 到 10 分成三个箱。mutate()
调用vs crossover()
vs的概率randomlyCreate()
取决于每个 bin 的大小。您可以通过逐渐移动 bin 的边界来调整突变率。
在您的代码中,mutate()
有 20% 的时间被调用(当随机数 = 9 或 1 时),randomlyCreate()
有 10% 的时间被调用(当随机数 = 0 时),crossover()
另外 70% 的时间被调用。
下面的代码在第 0 代开始使用这些相同的比率,但突变率每代增加 1%。所以第 1 代的突变率为 21%,第 2 代的突变率为 22%,以此类推。无论突变率如何,都randomlyCreate()
被称为 1 / 7 。crossover()
您可以通过改变getMutationBoundary()
.
我在下面的代码中使用了浮点数。双打也可以。
如果您最感兴趣的是突变率,则移动突变箱使其最初位于 [0, 2] 可能更直观,然后从那里增加其上边界(2.1、2.2 等)。然后您可以轻松读取突变率(21%、22% 等)。
void mainLoop() {
// make lots of generations
for (int generation = 0; generation < MAX_GEN; generation++) {
float mutationBoundary = getMutationBoundary(generation);
float creationBoundary = getCreationBoundary(mutationBoundary);
createNewGeneration(mutationBoundary, creationBoundary);
// Do some stuff with this generation, e.g. measure fitness
}
}
void createNewGeneration(float mutationBoundary, float creationBoundary) {
// create each member of this generation
for (int i = 0; i < MAX_POP; i++) {
createNewMember(mutationBoundary, creationBoundary);
}
}
void createNewMember(float mutationBoundary, float creationBoundary) {
float random = 10 * generator.nextFloat();
if (random > mutationBoundary) {
mutate();
}
else {
if (random < creationBoundary) {
randomlyCreate();
}
else {
crossover();
}
}
}
float getMutationBoundary(int generation) {
// Mutation bin is is initially between [8, 10].
// Lower bound slides down linearly, so it becomes [7.9, 10], [7.8, 10], etc.
// Subtracting 0.1 each generation makes the bin grow in size.
// Initially the bin is 10 - 8 = 2.0 units wide, then 10 - 7.9 = 2.1 units wide,
// and so on. So the probability of mutation grows from 2 / 10 = 20%
// to 2.1 / 10 = 21% and so on.
float boundary = 8 - 0.1f * generation;
if (boundary < 0) {
boundary = 0;
}
return boundary;
}
float getCreationBoundary(float creationBoundary) {
return creationBoundary / 8; // fixed ratio
}