Algorithm 如果一个结果接近正确的结果,就要比一个没有带来好结果的个体复制更多的结果。否则,它将非常类似于随机搜索
通常情况下,随机选择个体进行繁殖仍然是有用的,因为这将导致结果并非总是最好的,而是探索更大范围的搜索区域 一种常见的方法是使用一个随机选择个体进行繁殖,但基于适应值。因此,适合度高的个体(在你的例子中,那些导致结果接近正确结果的个体)繁殖的几率更高 另一种常见的方法是a,它也会选择随机个体进行繁殖,更好的个体有更高的机会繁殖,但这也将保证比平均适合度更好的个体至少繁殖一次 适应度比例选择的示例实现可能如下所示(不幸的是,这是java代码,没有C#,但它们非常相似……):Algorithm 如果一个结果接近正确的结果,就要比一个没有带来好结果的个体复制更多的结果。否则,它将非常类似于随机搜索,algorithm,genetic-algorithm,Algorithm,Genetic Algorithm,通常情况下,随机选择个体进行繁殖仍然是有用的,因为这将导致结果并非总是最好的,而是探索更大范围的搜索区域 一种常见的方法是使用一个随机选择个体进行繁殖,但基于适应值。因此,适合度高的个体(在你的例子中,那些导致结果接近正确结果的个体)繁殖的几率更高 另一种常见的方法是a,它也会选择随机个体进行繁殖,更好的个体有更高的机会繁殖,但这也将保证比平均适合度更好的个体至少繁殖一次 适应度比例选择的示例实现可能如下所示(不幸的是,这是java代码,没有C#,但它们非常相似……): import java.
import java.util.concurrent.ThreadLocalRandom;
导入com.google.common.annotations.VisibleForTesting;
/**
*一种选择器,根据被选择的概率随机选择要复制的对。
*/
公共类FitnessControlleSelector实现选择器{
/**
*选择组合以构建下一代的双亲(按索引)。
*
*@param selectionProbability
*当前群体中每个DNA被选择的概率(总和为1)。
*
*@param numPairs
*所需的成对数量(或下一代所需的个体数量)。
*
*@return返回一个大小为[numPairs*2]的整数数组,其中包括要组合以创建下一个填充的对(一对处于启用状态)
*位置[i,i+1]表示i%2=0)。
*/
@凌驾
公共整数[]选择(双[]选择概率,整数){
double[]summedProbabilities=选择器。toSummedProbabilities(selectionProbability);
int[]selectionPairs=新int[numPairs*2];
双选择概率;
对于(int i=0;i
或者是随机分布选择的解决方案(同样在java中):
import java.util.concurrent.ThreadLocalRandom;
导入com.google.common.annotations.VisibleForTesting;
/**
*一种选择器,通过随机分布的选择方法选择要复制的对。
*
*选择概率与给定的概率成正比,但可以确保选择概率高于平均值的个体
*至少一次。
*/
公共类随机分布选择器实现选择器{
/**
*选择组合以构建下一代的双亲(按索引)。
*
*@param selectionProbability
*当前群体中每个DNA被选择的概率(总和为1)。
*
*@param numPairs
*所需的成对数量(或下一代所需的个体数量)。
*
*@return返回一个大小为[numPairs*2]的整数数组,其中包括要组合以创建下一个填充的对(一对处于启用状态)
*位置[i,i+1]表示i%2=0)。
*/
@凌驾
公共整数[]选择(双[]选择概率,整数){
double[]summedProbability=选择器。ToSummedProbability(selectionProbability);
int[]selectedPairs=新int[2*numPairs];
双起点=getRandomNumber();
双加法平均值=1d/(2d*numPairs);
双重随机选择概率;
对于(int i=0;i0;i--){
swapIndex=(int)(getRandomNumber()*(i+1));
tmp=选定的对[i];
selectedPairs[i]=selectedPairs[swapIndex];
selectedPairs[swapIndex]=tmp;
}
}
@可视性测试
/*private*/double getRandomNumber(){
返回ThreadLocalRandom.current().nextDouble();
}
@凌驾
公共字符串toString(){
返回“随机分配选择器[]”;
}
}
我从我为硕士论文创建的一个遗传优化器项目中获取了这些示例代码。如果你想看一看,你可以找到它
一些进一步的改进:
- 尝试使用而不是绝对值(f(x)=绝对值(所有变量之和)-等式(结果))
- 使用选择压力是选择正确个体的另一个好方法
f(x) = absolute((sum_of_all_variables) - equation_result)
1a + 1b = 12
private static void Crossover(List<Chromosome> chromosomes, Random seed) { List<int> crossoverChromosome = new List<int>(); for (int i = 0; i < 50; i++) { decimal randomedValue = RandomizeValue(seed); if (randomedValue < Population.CrossoverRate) crossoverChromosome.Add(i); } for (int i = 0; i < crossoverChromosome.Count; i++) { int crossoverPoint = seed.Next(0, chromosomes[0].GeneValues.Count); chromosomes[crossoverChromosome[i]] = chromosomes[crossoverChromosome[i]].MixChromosome(chromosomes[crossoverChromosome[(i + 1) % crossoverChromosome.Count]], crossoverPoint); } } private static decimal RandomizeValue(Random seed) { return Math.Round((decimal)seed.NextDouble(), 5); } public Chromosome MixChromosome(Chromosome mixture, int crossoverPoint) { List<Gene> newGenes = new List<Gene>(); newGenes.AddRange(this.GetGenes(0, crossoverPoint)); newGenes.AddRange(mixture.GetGenes(crossoverPoint, this.GeneValues.Count)); return new Chromosome(DesiredValue, OperatorData, newGenes); // Ignore the DesiredValue and Operator Data, it has nothing to do with crossover } private List<Gene> GetGenes(int firstIndex, int lastIndex) { List<Gene> slicedGenes = new List<Gene>(); for (int i = firstIndex; i < lastIndex; i++) { slicedGenes.Add(Genes[i].CloneGene()); } return slicedGenes; }
import java.util.concurrent.ThreadLocalRandom; import com.google.common.annotations.VisibleForTesting; /** * A selector that randomly chooses pairs to be selected for reproduction based on their probability to be selected. */ public class FitnessProportionalSelector implements Selector { /** * Select pairs of parents (by index) that are combined to build the next generation. * * @param selectionProbability * The probability to be selected for every DNA in the current population (sums up to 1). * * @param numPairs * The number of pairs needed (or the number of individuals needed in the next generation). * * @return Returns an int-array of size [numPairs * 2] including the pairs that are to be combined to create the next population (a pair is on * position [i, i+1] for i % 2 = 0). */ @Override public int[] select(double[] selectionProbability, int numPairs) { double[] summedProbabilities = Selector.toSummedProbabilities(selectionProbability); int[] selectionPairs = new int[numPairs * 2]; double chosenProbability; for (int i = 0; i < numPairs * 2; i++) { chosenProbability = getRandomNumber(); selectionPairs[i] = Selector.getSelectedIndexByBisectionSearch(summedProbabilities, chosenProbability); } return selectionPairs; } @Override public String toString() { return "FitnessProportionalSelector []"; } @VisibleForTesting /*private*/ double getRandomNumber() { return ThreadLocalRandom.current().nextDouble(); } }
import java.util.concurrent.ThreadLocalRandom; import com.google.common.annotations.VisibleForTesting; /** * A selector that chooses the pairs to be reproduced by a stochastically distributed selection method. * * The selection probability is proportional to the given probability, but it's ensured, that individuals with a probability above average are chosen * at least once. */ public class StochasticallyDistributedSelector implements Selector { /** * Select pairs of parents (by index) that are combined to build the next generation. * * @param selectionProbability * The probability to be selected for every DNA in the current population (sums up to 1). * * @param numPairs * The number of pairs needed (or the number of individuals needed in the next generation). * * @return Returns an int-array of size [numPairs * 2] including the pairs that are to be combined to create the next population (a pair is on * position [i, i+1] for i % 2 = 0). */ @Override public int[] select(double[] selectionProbability, int numPairs) { double[] summedProbability = Selector.toSummedProbabilities(selectionProbability); int[] selectedPairs = new int[2 * numPairs]; double startPoint = getRandomNumber(); double addedAverage = 1d / (2d * numPairs); double stochasticallySelectedProbability; for (int i = 0; i < numPairs * 2; i++) { //select the pairs stochastically stochasticallySelectedProbability = startPoint + i * addedAverage; stochasticallySelectedProbability %= 1; selectedPairs[i] = Selector.getSelectedIndexByBisectionSearch(summedProbability, stochasticallySelectedProbability); } //shuffle the pairs to distribute them stochastically shuffle(selectedPairs); return selectedPairs; } @VisibleForTesting /*private*/ void shuffle(int[] selectedPairs) { //shuffle the selected pairs in place int swapIndex; int tmp; for (int i = selectedPairs.length - 1; i > 0; i--) { swapIndex = (int) (getRandomNumber() * (i + 1)); tmp = selectedPairs[i]; selectedPairs[i] = selectedPairs[swapIndex]; selectedPairs[swapIndex] = tmp; } } @VisibleForTesting /*private*/ double getRandomNumber() { return ThreadLocalRandom.current().nextDouble(); } @Override public String toString() { return "StochasticallyDistributedSelector []"; } }