python 我的遗传算法在上一代没有提高适应度得分

ajsxfq5m  于 2023-01-19  发布在  Python
关注(0)|答案(1)|浏览(121)

我写了一个简单的遗传算法,代码如下
适应度函数定义为

def fitness(a, b, c, d, e):
    return a**2 + b**2 + c**2 + d**2 + e**2

生成第一群体的函数

def generate_pop(numInd, numGene):
    population = []
    for i in range(numInd):
        individual = [random.uniform(-10, 10) for _ in range(numGene)]
        population.append(individual)
    return population

选择和交叉功能

def randomCrossover(population):
    offspring = []
    for i in range(len(population)//2):
        Ind1_index = random.randint(0, len(population)-1)
        Ind2_index = random.randint(0, len(population)-1)
        while Ind2_index == Ind1_index:
            Ind2_index = random.randint(0, len(population)-1)

        Ind1 = population[Ind1_index]
        Ind2 = population[Ind2_index]

        crossPoint = random.randint(1, len(Ind1))
        child1 = Ind1[:crossPoint] + Ind2[crossPoint:]
        child2 = Ind2[:crossPoint] + Ind1[crossPoint:]
        offspring.append(child1)
        offspring.append(child2)
    return offspring

结束此函数中的所有函数

def geneticAlgorithm(mutation=0.1, numGeneration=100):
    population = generate_pop(12, 5)
    maxFitnessScoreGen = []
    minFitnessScoreGen = []
    avgFitnessScoreGen = []
    for _ in range(numGeneration):
        fitScore = [fitness(a, b, c, d, e) for a, b, c, d, e in population]
        maxFitnessScoreGen.append(max(fitScore))
        minFitnessScoreGen.append(min(fitScore))
        avgFitnessScoreGen.append(mean(fitScore))
        # population = [population[i] for i in range(len(population)) if fitness[i] == min(fitness)] # should individual that have lowest fitness score
        
        offspring = randomCrossover(population)
            
        for i in range(len(offspring)):
            if random.uniform(0, 1) < mutation:
                offspring[i] = [random.uniform(-10, 10), random.uniform(-10, 10), random.uniform(-10, 10), random.uniform(-10, 10), random.uniform(-10, 10)]

        population = offspring
        # print(f'gen {_} maxScore = {maxFitnessScoreGen}, avgScore = {avgFitnessScoreGen}')
        # print(population)

    return maxFitnessScoreGen, minFitnessScoreGen ,avgFitnessScoreGen

但优化的结果是振荡,似乎没有改善。我不知道我做错了我的代码。

xtfmy6hx

xtfmy6hx1#

问题在于,种群成员参与繁殖的机会必须以某种方式与适应度相关联-a适应度越高的个体繁殖的机会越大,但你的randomCrossover函数只是随机选择种群成员,而不考虑适应度。
你需要做的是以这样一种方式对人口进行抽样,即不是每个人都有同样的机会被选中。
您可能可以自己解决这个问题,但无论如何,我将展示我认为采样应该如何工作(从这里修改Java/伪代码):

int sampleFromPopulation(fitnessArray) { 
       double[] probs = normalize(fitnessArray); // normalize so sum of fitness values is 1 -> gives a probability distribution
        double currentProb = 0;
        int individualToBeChosen= 0;
        double rand = random.nextDouble();
        for (double prob : probs) {   // add up probabilities until you reach the random value
            currentProb += prob;
            if (rand < currentProb) {
                break;
            }
            individualToBeChosen++;
        }
        return Math.min(individualToBeChosen, fitnessArray.length()- 1);
}

相关问题