You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于遗传算法的莎士比亚猴子实验Python代码报错求助

修正基于遗传算法的莎士比亚猴子实验代码(索引错误修复)

原代码核心错误点

  • DNA类的genes和fitness_val是类属性,所有实例共享同一列表,导致基因数据混乱引发索引错误
  • crossover方法中创建child实例时传入长度0,导致genes为空,直接切片赋值触发索引错误;且错误地直接对实例进行切片操作,应操作实例的genes属性
  • mutate方法错误引用未定义的self.child,且未按突变概率触发突变,而是强制修改所有基因
  • get_phrase方法存在拼写错误:jon应为join
  • Population类的selection方法将索引加入交配池,而非个体本身,导致后续调用crossover方法时触发类型错误
  • Population类的select_best方法引用不存在的fit属性,且未返回最优个体的文本
  • 主循环中调用不存在的pop.get_phrase()方法,无法判断收敛状态

修正后的完整代码

import random

target_text = 'Andromeda'
population_size = 501
mutation_rate = 0.02

class DNA:
    def __init__(self, length):
        # 改为实例属性,每个个体有独立基因列表
        self.genes = []
        self.fitness_val = 0
        for _ in range(length):
            # 生成可打印ASCII字符(32-126),避免不可见字符
            self.genes.append(chr(random.randint(32, 126)))

    def calculate_fitness(self, target):
        score = 0
        for gene, target_gene in zip(self.genes, target):
            if gene == target_gene:
                score += 1
        self.fitness_val = score / len(target)

    def crossover(self, parent):
        child_length = len(self.genes)
        child = DNA(child_length)
        midpoint = random.randint(0, child_length - 1)
        # 操作child的genes属性,而非直接切片实例
        child.genes[:midpoint] = self.genes[:midpoint]
        child.genes[midpoint:] = parent.genes[midpoint:]
        return child

    def mutate(self, mutation_rate):
        for i in range(len(self.genes)):
            if random.random() < mutation_rate:
                self.genes[i] = chr(random.randint(32, 126))

    def get_phrase(self):
        return ''.join(self.genes)

class Population:
    def __init__(self, target, population_size, mutation_rate):
        self.target = target
        self.mutation_rate = mutation_rate
        self.population_size = population_size
        self.population = []
        self.mating_pool = []
        for _ in range(population_size):
            self.population.append(DNA(len(target)))
        self.calculate_all_fitness()

    def calculate_all_fitness(self):
        for individual in self.population:
            individual.calculate_fitness(self.target)

    def selection(self):
        self.mating_pool.clear()
        for individual in self.population:
            # 根据适应度值,将个体多次加入交配池(权重越高,出现次数越多)
            count = int(individual.fitness_val * 100)
            self.mating_pool.extend([individual] * count)
        # 处理交配池为空的情况(所有个体适应度为0)
        if not self.mating_pool:
            self.mating_pool = self.population.copy()

    def generate_next_generation(self):
        new_population = []
        for _ in range(self.population_size):
            # 从交配池随机选择两个父代
            parent1, parent2 = random.choices(self.mating_pool, k=2)
            child = parent1.crossover(parent2)
            child.mutate(self.mutation_rate)
            new_population.append(child)
        self.population = new_population

    def get_best_individual(self):
        best_individual = self.population[0]
        for individual in self.population:
            if individual.fitness_val > best_individual.fitness_val:
                best_individual = individual
        return best_individual

# 主程序
pop = Population(target_text, population_size, mutation_rate)
generation_count = 0

while True:
    pop.selection()
    pop.generate_next_generation()
    pop.calculate_all_fitness()
    
    best = pop.get_best_individual()
    best_phrase = best.get_phrase()
    generation_count += 1
    
    # 打印每10代的进度
    if generation_count % 10 == 0:
        print(f"第 {generation_count} 代 | 最优结果: {best_phrase} | 适应度: {best.fitness_val:.2f}")
    
    # 判断是否收敛到目标文本
    if best_phrase == target_text:
        print(f"\n收敛完成!共耗时 {generation_count} 代")
        print(f"最终结果: {best_phrase}")
        break

关键修正说明

  1. 属性作用域修正:将DNA类的genes和fitness_val改为实例属性,确保每个个体有独立的基因数据
  2. 基因生成优化:限制ASCII字符范围为32-126(可打印字符),避免生成不可见乱码
  3. 交配池逻辑修正:将个体本身加入交配池,而非索引,确保后续能正常调用crossover方法
  4. 突变逻辑修正:仅当随机概率小于突变率时才修改基因,符合遗传算法的突变规则
  5. 收敛判断修正:通过获取最优个体的文本来判断是否达到目标,修复原代码中方法不存在的问题
  6. 添加进度打印:每10代打印一次当前最优结果,方便观察算法收敛过程

内容的提问来源于stack exchange,提问作者Sai Nikhil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 18:50:23