目录
  • 什么是遗传算法?
  • 如何使用GA进行优化问题?
    • GA机制优化过程的阶段
  • 安装必要的软件包
    • 使用遗传算法实现解决方案
      • 生成位模式
      • 符号回归问题

    本章详细讨论了人工智能的遗传算法。

    什么是遗传算法?

    遗传算法(GA)是基于自然选择和遗传概念的基于搜索的算法。GA是更大的计算分支的子集,称为进化计算。

    GA由John Holland及其密歇根大学的学生和同事开发,最着名的是David E. Goldberg。从那以后,已经尝试了各种优化问题并取得了很大的成功。

    在GA中,我们有一组可能的解决方案来解决给定的问题。然后这些溶液经历重组和突变(如在天然遗传学中),产生新的儿童,并且该过程重复多代。为每个个体(或候选解决方案)分配适合度值(基于其目标函数值),并且使得更健康的个体具有更高的交配和产生更健康的个体的机会。这符合达尔文适者生存理论。

    因此,它不断发展更好的个人或解决方案,直到它达到停止标准。

    遗传算法在本质上具有足够的随机性,但它们比随机局部搜索(我们只是尝试随机解决方案,跟踪迄今为止的最佳解决方案)表现得更好,因为它们也利用了历史信息。

    如何使用GA进行优化问题?

    优化是使设计,情境,资源和系统尽可能有效的行动。以下框图显示了优化过程 –

    AI与Python人工智能遗传算法

    GA机制优化过程的阶段

    以下是用于优化问题的GA机制的一系列步骤。

    • 第1步 – 随机生成初始种群。
    • 第2步 – 选择具有最佳适合度值的初始解决方案。
    • 步骤3 – 使用突变和交叉算子重新组合所选解决方案。
    • 第4步 – 将后代插入人口。
    • 步骤5 – 现在,如果满足停止条件,则返回具有最佳适合度值的解决方案。否则转到第2步。

    安装必要的软件包

    为了通过Python中的遗传算法解决问题,我们将使用一个名为DEAP的功能强大的GA包。它是一个新的进化计算框架库,用于快速原型设计和思想测试。我们可以在命令提示符下使用以下命令安装此软件包 –

    pip install deap
    

    如果您使用的是anaconda环境,则可以使用以下命令安装deap –

    conda install -c conda-forge deap
    

    使用遗传算法实现解决方案

    本节将介绍使用遗传算法实现解决方案的过程。

    生成位模式

    以下示例显示如何根据One Max问题生成包含15个字符串的位字符串。

    如图所示导入必要的包 –

    import random
    from deap import base, creator, tools
    

    定义评估功能。这是创建遗传算法的第一步。

    def eval_func(individual):
       target_sum = 15
       return len(individual) - abs(sum(individual) - target_sum),
    

    现在,使用正确的参数创建工具箱 –

    def create_toolbox(num_bits):
       creator.create("FitnessMax", base.Fitness, weights=(1.0,))
       creator.create("Individual", list, fitness=creator.FitnessMax)
    

    初始化工具箱

    toolbox = base.Toolbox()
    toolbox.register("attr_bool", random.randint, 0, 1)
    toolbox.register("individual", tools.initRepeat, creator.Individual,
       toolbox.attr_bool, num_bits)
    toolbox.register("population", tools.initRepeat, list, toolbox.individual)
    

    注册评估运营商 –

    toolbox.register("evaluate", eval_func)
    

    现在,注册交叉运算符 –

    toolbox.register("mate", tools.cxTwoPoint)
    

    注册变异算子 –

    toolbox.register("mutate", tools.mutFlipBit, indpb = 0.05)
    

    定义繁殖的运营商 –

    toolbox.register("select", tools.selTournament, tournsize = 3)
    return toolbox
    if __name__ == "__main__":
       num_bits = 45
       toolbox = create_toolbox(num_bits)
       random.seed(7)
       population = toolbox.population(n = 500)
       probab_crossing, probab_mutating = 0.5, 0.2
       num_generations = 10
       print('\nEvolution process starts')
    

    评估整个人口 –

    fitnesses = list(map(toolbox.evaluate, population))
    for ind, fit in zip(population, fitnesses):
       ind.fitness.values = fit
    print('\nEvaluated', len(population), 'individuals')
    

    创造和迭代几代人 –

    for g in range(num_generations):
       print("\n- Generation", g)
    

    选择下一代个人 –

    offspring = toolbox.select(population, len(population))
    

    现在,克隆选定的个人 –

    offspring = list(map(toolbox.clone, offspring))
    

    在后代上应用交叉和变异 –

    for child1, child2 in zip(offspring[::2], offspring[1::2]):
       if random.random() < probab_crossing:
       toolbox.mate(child1, child2)
    

    删除孩子的健身价值

    del child1.fitness.values
    del child2.fitness.values
    

    现在,应用变异 –

    for mutant in offspring:
       if random.random() < probab_mutating:
       toolbox.mutate(mutant)
       del mutant.fitness.values
    

    评估健康状况不佳的人 –

    invalid_ind = [ind for ind in offspring if not ind.fitness.valid]
    fitnesses = map(toolbox.evaluate, invalid_ind)
    for ind, fit in zip(invalid_ind, fitnesses):
       ind.fitness.values = fit
    print('Evaluated', len(invalid_ind), 'individuals')
    

    现在,用下一代个人取代人口 –

    population[:] = offspring
    

    打印当前世代的统计数据 –

    fits = [ind.fitness.values[0] for ind in population]
    length = len(population)
    mean = sum(fits) / length
    sum2 = sum(x*x for x in fits)
    std = abs(sum2 / length - mean**2)**0.5
    print('Min =', min(fits), ', Max =', max(fits))
    print('Average =', round(mean, 2), ', Standard deviation =',
    round(std, 2))
    print("\n- Evolution ends")
    

    打印最终输出 –

     best_ind = tools.selBest(population, 1)[0]
       print('\nBest individual:\n', best_ind)
       print('\nNumber of ones:', sum(best_ind))
    Following would be the output:
    Evolution process starts
    Evaluated 500 individuals
    - Generation 0
    Evaluated 295 individuals
    Min = 32.0 , Max = 45.0
    Average = 40.29 , Standard deviation = 2.61
    - Generation 1
    Evaluated 292 individuals
    Min = 34.0 , Max = 45.0
    Average = 42.35 , Standard deviation = 1.91
    - Generation 2
    Evaluated 277 individuals
    Min = 37.0 , Max = 45.0
    Average = 43.39 , Standard deviation = 1.46
    … … … …
    - Generation 9
    Evaluated 299 individuals
    Min = 40.0 , Max = 45.0
    Average = 44.12 , Standard deviation = 1.11
    - Evolution ends
    Best individual:
    [0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 
     1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0,
     1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1]
    Number of ones: 15
    

    符号回归问题

    这是遗传编程中最着名的问题之一。所有符号回归问题都使用任意数据分布,并尝试使用符号公式拟合最准确的数据。通常,像RMSE(均方根误差)这样的度量用于衡量个体的适应度。这是一个经典的回归问题,在这里我们使用等式5x 3 -6x 2 + 8x = 1。我们需要遵循上面示例中的所有步骤,但主要部分是创建原始集,因为它们是个人的构建块,因此评估可以开始。在这里,我们将使用经典的基元集。

    以下Python代码详细解释了这一点 –

    import operator
    import math
    import random
    import numpy as np
    from deap import algorithms, base, creator, tools, gp
    def division_operator(numerator, denominator):
       if denominator == 0:
          return 1
       return numerator / denominator
    def eval_func(individual, points):
       func = toolbox.compile(expr=individual)
       return math.fsum(mse) / len(points),
    def create_toolbox():
       pset = gp.PrimitiveSet("MAIN", 1)
       pset.addPrimitive(operator.add, 2)
       pset.addPrimitive(operator.sub, 2)
       pset.addPrimitive(operator.mul, 2)
       pset.addPrimitive(division_operator, 2)
       pset.addPrimitive(operator.neg, 1)
       pset.addPrimitive(math.cos, 1)
       pset.addPrimitive(math.sin, 1)
       pset.addEphemeralConstant("rand101", lambda: random.randint(-1,1))
       pset.renameArguments(ARG0 = 'x')
       creator.create("FitnessMin", base.Fitness, weights = (-1.0,))
       creator.create("Individual",gp.PrimitiveTree,fitness=creator.FitnessMin)
       toolbox = base.Toolbox()
       toolbox.register("expr", gp.genHalfAndHalf, pset=pset, min_=1, max_=2)
       toolbox.expr)
       toolbox.register("population",tools.initRepeat,list, toolbox.individual)
       toolbox.register("compile", gp.compile, pset = pset)
       toolbox.register("evaluate", eval_func, points = [x/10. for x in range(-10,10)])
       toolbox.register("select", tools.selTournament, tournsize = 3)
       toolbox.register("mate", gp.cxOnePoint)
       toolbox.register("expr_mut", gp.genFull, min_=0, max_=2)
       toolbox.register("mutate", gp.mutUniform, expr = toolbox.expr_mut, pset = pset)
       toolbox.decorate("mate", gp.staticLimit(key = operator.attrgetter("height"), max_value = 17))
       toolbox.decorate("mutate", gp.staticLimit(key = operator.attrgetter("height"), max_value = 17))
       return toolbox
    if __name__ == "__main__":
       random.seed(7)
       toolbox = create_toolbox()
       population = toolbox.population(n = 450)
       hall_of_fame = tools.HallOfFame(1)
       stats_fit = tools.Statistics(lambda x: x.fitness.values)
       stats_size = tools.Statistics(len)
       mstats = tools.MultiStatistics(fitness=stats_fit, size = stats_size)
       mstats.register("avg", np.mean)
       mstats.register("std", np.std)
       mstats.register("min", np.min)
       mstats.register("max", np.max)
       probab_crossover = 0.4
       probab_mutate = 0.2
       number_gen = 10
       population, log = algorithms.eaSimple(population, toolbox,
          probab_crossover, probab_mutate, number_gen,
          stats = mstats, halloffame = hall_of_fame, verbose = True)
    

    请注意,所有基本步骤与生成位模式时使用的步骤相同。该程序将在10代之后给出输出为min,max,std(标准偏差)。

    以上就是AI与Python人工智能遗传算法的详细内容,更多关于AI Python遗传算法的资料请关注其它相关文章!

    声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。