我正在实现与遗传算法非常相似的东西。因此,你会经历一个种群的多代——在一代结束时,你会以“随机”、“突变”和“交叉”三种不同的方式创建一个新的种群。
目前概率是静态的,但我需要使其突变的概率逐渐增加。我很欣赏任何方向,因为我有点卡住了..
这就是我所拥有的:
int random = generator.nextInt(10);
if (random < 1)
randomlyCreate()
else if (random > 1 && random < 9 )
crossover();
else
mutate();
谢谢。
最佳答案
在 if 语句中,用变量替换硬编码数字,并在每一代开始时更新它们。
您的 if 语句有效地将 0 到 10 的区间划分为三个容器。调用 mutate()
、crossover()
和 randomlyCreate()
的概率取决于每个 bin 的大小。您可以通过逐渐移动箱的边界来调整突变率。
在您的代码中,mutate()
被调用的时间为 20%(当 random = 9 或 1 时),randomlyCreate()
被调用的时间为 10%时间(当 random = 0 时),另外 70% 的时间调用 crossover()
。
下面的代码在第 0 代以相同的比率开始,但突变率每代增加 1%。因此,第 1 代的突变率为 21%,第 2 代的突变率为 22%,依此类推。无论突变率如何,randomlyCreate()
的调用次数是 crossover()
的七分之一。
您可以通过更改 getMutationBoundary()
使突变率以二次、指数或您选择的任何形式增加。
我在下面的代码中使用了 float 。 double 也同样有效。
如果突变率是您最感兴趣的,那么移动突变箱使其最初位于 [0, 2],然后从那里增加其上边界(2.1, 2.2, ETC)。然后您可以轻松读出突变率(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
}
关于java - 逐渐增加变异概率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20075698/