求遗传算法最高/平均适应度:Python中Map/Reduce的替代方案
用Numpy、Scipy或Pygad替代Map/Reduce实现遗传算法适应度计算
需求说明:计算遗传算法中基因组的最高适应度与平均适应度,适应度函数为基因组字符串中1的数量,输入种群为:
['00111110011001010011', '01111101001101110010', '01100110111110000000', '01101101100111001001']
原实现代码
from functools import reduce def fitness(genome): return reduce((lambda x, y: int(x) + int(y)), list(genome)) def evaluateFitness(population): sums = list(map(lambda x: fitness(x), population)) return [max(sums), sum(sums) / len(population)] # 测试 population = ['00111110011001010011', '01111101001101110010', '01100110111110000000', '01101101100111001001'] print(evaluateFitness(population)) # 输出: [12, 9.75]
1. Numpy实现方案
Numpy的向量化操作能高效处理这类字符串统计,无需手动写map/reduce:
import numpy as np def evaluate_fitness_numpy(population): # 将所有基因组字符串转为二维整数数组 genome_array = np.array([list(genome) for genome in population], dtype=int) # 每行求和得到单个基因组的适应度 fitness_scores = genome_array.sum(axis=1) # 返回最高适应度和平均值 return [fitness_scores.max(), fitness_scores.mean()] # 测试 population = ['00111110011001010011', '01111101001101110010', '01100110111110000000', '01101101100111001001'] print(evaluate_fitness_numpy(population)) # 输出: [12, 9.75]
优势:种群规模大时,向量化运算比循环/映射更快,代码更简洁。
2. Scipy实现方案
Scipy没有专属的字符串统计函数,但可以结合Numpy+Scipy的统计工具完成任务,适合需要多维度统计信息的场景:
import numpy as np from scipy.stats import describe def evaluate_fitness_scipy(population): genome_array = np.array([list(genome) for genome in population], dtype=int) fitness_scores = genome_array.sum(axis=1) # 一次性获取最值、均值、方差等统计结果 stats_result = describe(fitness_scores) return [stats_result.minmax[1], stats_result.mean] # 测试 population = ['00111110011001010011', '01111101001101110010', '01100110111110000000', '01101101100111001001'] print(evaluate_fitness_scipy(population)) # 输出: [12, 9.75]
3. Pygad实现方案
Pygad是专门的遗传算法库,适合完整的遗传算法流程,内置适应度计算机制:
import pygad def fitness_function(ga_instance, solution, solution_idx): # solution是Numpy数组,直接求和得到适应度 return sum(solution) # 把字符串基因组转为整数列表,适配Pygad的输入格式 population = [list(map(int, genome)) for genome in ['00111110011001010011', '01111101001101110010', '01100110111110000000', '01101101100111001001']] # 初始化GA实例,仅用于评估当前种群(无需进化) ga = pygad.GA( num_generations=1, num_parents_mating=2, fitness_func=fitness_function, sol_per_pop=len(population), initial_population=population, gene_type=int ) # 计算种群适应度 ga.cal_pop_fitness() fitness_scores = ga.pop_fitness max_fitness = max(fitness_scores) avg_fitness = sum(fitness_scores) / len(fitness_scores) print([max_fitness, avg_fitness]) # 输出: [12, 9.75]
优势:如果后续需要进行选择、交叉、变异等遗传算法核心操作,Pygad能一站式完成,无需自己实现整套逻辑。
内容的提问来源于stack exchange,提问作者Shariq
相关产品推荐
相关产品推荐

