遗传算法(Genetic Algorithm)之deap学习笔记(五):Santa Fe Ant Trail问题

本文主要是介绍遗传算法(Genetic Algorithm)之deap学习笔记(五):Santa Fe Ant Trail问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Santa Fe Ant Trail问题是一个经典的人工生命(Artificial Life)问题,用来探索生物群体行为和分布式智能的原理。这个问题是基于蚂蚁在寻找食物时的行为而建立的。问题中,蚂蚁在一个网格世界中寻找食物,并在回家时留下一条路径素,用于引导其他蚂蚁找到食物。蚂蚁在寻找食物和回家时,根据自身和周围信息做出决策,例如嗅觉、视觉等。

Santa Fe Ant Trail问题中,蚂蚁的行动是基于一组简单的规则,如蚂蚁在感知到食物的存在时朝食物方向移动,并在回家时遵循已有的路径素。通过这些规则,蚂蚁群体能够在整个网格世界中有效地搜索到食物,并且留下的路径素也能引导其他蚂蚁更快地找到食物。这个问题被广泛用于探索分布式智能和自组织行为的原理,也被用于设计优化算法、模拟群体行为等应用领域。

这篇博客具体讲述的问题是设计一个agent,它可以成功地引导一只人造蚂蚁沿着方形网格上的一条小径收集尽可能最多的食物,最大移动次数为600。

以下为此问题用到的蚂蚁移动的地图的.txt文件

S###............................
...#............................
...#.....................###....
...#....................#....#..
...#....................#....#..
...####.#####........##.........
............#................#..
............#.......#...........
............#.......#........#..
............#.......#...........
....................#...........
............#................#..
............#...................
............#.......#.....###...
............#.......#..#........
.................#..............
................................
............#...........#.......
............#...#..........#....
............#...#...............
............#...#...............
............#...#.........#.....
............#..........#........
............#...................
...##..#####....#...............
.#..............#...............
.#..............#...............
.#......#######.................
.#.....#........................
.......#........................
..####..........................
................................

以下为构建蚂蚁移动的函数

import copy
import random
import numpy
import pygraphviz as pgv
from functools import partialfrom deap import base
from deap import creator
from deap import tools
from deap import gpclass AntSimulator(object):direction = ["north","east","south","west"]dir_row = [1, 0, -1, 0]dir_col = [0, 1, 0, -1]def __init__(self, max_moves):self.max_moves = max_movesself.moves = 0self.eaten = 0self.routine = Nonedef _reset(self):self.row = self.row_start self.col = self.col_start self.dir = 1self.moves = 0  self.eaten = 0self.matrix_exc = copy.deepcopy(self.matrix)@propertydef position(self):return (self.row, self.col, self.direction[self.dir])# 将蚂蚁向左转 90 度def turn_left(self): if self.moves < self.max_moves:self.moves += 1self.dir = (self.dir - 1) % 4# 将蚂蚁向右转 90 度def turn_right(self):if self.moves < self.max_moves:self.moves += 1    self.dir = (self.dir + 1) % 4# 将蚂蚁向前移动一格 def move_forward(self):if self.moves < self.max_moves:self.moves += 1self.row = (self.row + self.dir_row[self.dir]) % self.matrix_rowself.col = (self.col + self.dir_col[self.dir]) % self.matrix_colif self.matrix_exc[self.row][self.col] == "food":self.eaten += 1self.matrix_exc[self.row][self.col] = "passed"def sense_food(self):ahead_row = (self.row + self.dir_row[self.dir]) % self.matrix_rowahead_col = (self.col + self.dir_col[self.dir]) % self.matrix_col        return self.matrix_exc[ahead_row][ahead_col] == "food"# 查看蚂蚁当前面对的方块,然后根据该方块是包含食物还是空的来执行其两个参数之一def if_food_ahead(self, out1, out2):return partial(if_then_else, self.sense_food, out1, out2)def run(self,routine):self._reset()while self.moves < self.max_moves:routine()def parse_matrix(self, matrix):self.matrix = list()for i, line in enumerate(matrix):self.matrix.append(list())for j, col in enumerate(line):if col == "#":self.matrix[-1].append("food")elif col == ".":self.matrix[-1].append("empty")elif col == "S":self.matrix[-1].append("empty")self.row_start = self.row = iself.col_start = self.col = jself.dir = 1self.matrix_row = len(self.matrix)self.matrix_col = len(self.matrix[0])self.matrix_exc = copy.deepcopy(self.matrix)

最多移动600次

ant = AntSimulator(600)# 打开地图
with  open("santafe_trail.txt") as trail_file:ant.parse_matrix(trail_file)

添加终端以及注册进之前的蚂蚁函数

pset = gp.PrimitiveSet("MAIN", 0)def progn(*args):for arg in args:arg()def prog2(out1, out2): return partial(progn,out1,out2)def prog3(out1, out2, out3):     return partial(progn,out1,out2,out3)def if_then_else(condition, out1, out2):out1() if condition() else out2()pset.addPrimitive(ant.if_food_ahead, 2)
pset.addPrimitive(prog2, 2)
pset.addPrimitive(prog3, 3)
pset.addTerminal(ant.move_forward)
pset.addTerminal(ant.turn_left)
pset.addTerminal(ant.turn_right)

注册个体,适应度,详情解释可以看第一篇博客

creator.create("FitnessMax", base.Fitness, weights=(1.0,))
creator.create("Individual", gp.PrimitiveTree, fitness=creator.FitnessMax)toolbox = base.Toolbox()
toolbox.register("expr_init", gp.genFull, pset=pset, min_=1, max_=2)
toolbox.register("individual", tools.initIterate, creator.Individual, toolbox.expr_init)
toolbox.register("population", tools.initRepeat, list, toolbox.individual)#toolbox.register("select", tools.selTournament, tournsize=7)
toolbox.register("select", tools.selDoubleTournament, fitness_size = 7, parsimony_size = 1.4, fitness_first = True, fit_attr='fitness' )
toolbox.register("mate", gp.cxOnePoint)
toolbox.register("expr_mut", gp.genFull, min_=0, max_=3)
toolbox.register("mutate", gp.mutUniform, expr=toolbox.expr_mut, pset=pset)

evaluation函数

def evalArtificialAnt(individual):routine = gp.compile(individual, pset)ant.run(routine)return ant.eaten,toolbox.register("evaluate", evalArtificialAnt)# 把min,max等也注册
stats_fit = tools.Statistics(lambda ind: ind.fitness.values)
stats_size = tools.Statistics(len)
stats = tools.MultiStatistics(fitness=stats_fit, size=stats_size)
stats.register("avg", numpy.mean)
stats.register("std", numpy.std)
stats.register("min", numpy.min)
stats.register("max", numpy.max)

主题程序

logbook = tools.Logbook()
pop = toolbox.population(n=500) ## 迭代200次
NGEN, CXPB, MUTPB = 200, 0.2, 0.2fitnesses = list(map(toolbox.evaluate, pop))
for ind, fit in zip(pop, fitnesses):ind.fitness.values = fitfor g in range(NGEN):print("-- Generation %i --" % g)offspring = toolbox.select(pop, len(pop))offspring = list(map(toolbox.clone, offspring))for child1, child2 in zip(offspring[::2], offspring[1::2]):if random.random() < CXPB:toolbox.mate(child1, child2)del child1.fitness.valuesdel child2.fitness.valuesfor mutant in offspring:if random.random() < MUTPB:toolbox.mutate(mutant)del mutant.fitness.valuesinvalid_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 = fitNeval = len(invalid_ind)pop[:] = offspringrecord = stats.compile(pop)logbook.record(gen=g, evals=Neval, **record)print("-- End of evolution --")

把图画出来

import matplotlib.pyplot as plt
%matplotlib inlinegen = logbook.chapters['fitness'].select("gen")
_min = logbook.chapters['fitness'].select("min")
_max = logbook.chapters['fitness'].select("max")
avgs = logbook.chapters['fitness'].select("avg")
stds = logbook.chapters['fitness'].select("std")plt.rc('axes', labelsize=14)
plt.rc('xtick', labelsize=14)
plt.rc('ytick', labelsize=14) 
plt.rc('legend', fontsize=14)fig, ax1 = plt.subplots()
line1 = ax1.plot(gen, avgs)
ax1.set_xlabel("Generation")
ax1.set_ylabel("Fitness")#line2 = ax1.plot(gen, _min)
#line3 = ax1.plot(gen, _max)

找到最佳个体

indv = tools.selBest(pop, 1)[0]
print(indv)toolbox.evaluate(indv)

以下为用树画出来的这个问题的整个流程

nodes, edges, labels = gp.graph(indv)tree = pgv.AGraph()
tree.add_nodes_from(nodes)
tree.add_edges_from(edges)
tree.layout(prog="dot")for i in nodes:n = tree.get_node(i)n.attr["label"] = labels[i]from IPython.display import ImagetreePlot = tree.draw(format='png', prog='dot')
Image(treePlot)

以上就是人工蚂蚁问题的完整代码了,如果有问题可以随时问我,谢谢。

这篇关于遗传算法(Genetic Algorithm)之deap学习笔记(五):Santa Fe Ant Trail问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/192763

相关文章

Springboot3统一返回类设计全过程(从问题到实现)

《Springboot3统一返回类设计全过程(从问题到实现)》文章介绍了如何在SpringBoot3中设计一个统一返回类,以实现前后端接口返回格式的一致性,该类包含状态码、描述信息、业务数据和时间戳,... 目录Spring Boot 3 统一返回类设计:从问题到实现一、核心需求:统一返回类要解决什么问题?

maven异常Invalid bound statement(not found)的问题解决

《maven异常Invalidboundstatement(notfound)的问题解决》本文详细介绍了Maven项目中常见的Invalidboundstatement异常及其解决方案,文中通过... 目录Maven异常:Invalid bound statement (not found) 详解问题描述可

idea粘贴空格时显示NBSP的问题及解决方案

《idea粘贴空格时显示NBSP的问题及解决方案》在IDEA中粘贴代码时出现大量空格占位符NBSP,可以通过取消勾选AdvancedSettings中的相应选项来解决... 目录1、背景介绍2、解决办法3、处理完成总结1、背景介绍python在idehttp://www.chinasem.cna粘贴代码,出

SpringBoot整合Kafka启动失败的常见错误问题总结(推荐)

《SpringBoot整合Kafka启动失败的常见错误问题总结(推荐)》本文总结了SpringBoot项目整合Kafka启动失败的常见错误,包括Kafka服务器连接问题、序列化配置错误、依赖配置问题、... 目录一、Kafka服务器连接问题1. Kafka服务器无法连接2. 开发环境与生产环境网络不通二、序

SpringSecurity中的跨域问题处理方案

《SpringSecurity中的跨域问题处理方案》本文介绍了跨域资源共享(CORS)技术在JavaEE开发中的应用,详细讲解了CORS的工作原理,包括简单请求和非简单请求的处理方式,本文结合实例代码... 目录1.什么是CORS2.简单请求3.非简单请求4.Spring跨域解决方案4.1.@CrossOr

nacos服务无法注册到nacos服务中心问题及解决

《nacos服务无法注册到nacos服务中心问题及解决》本文详细描述了在Linux服务器上使用Tomcat启动Java程序时,服务无法注册到Nacos的排查过程,通过一系列排查步骤,发现问题出在Tom... 目录简介依赖异常情况排查断点调试原因解决NacosRegisterOnWar结果总结简介1、程序在

解决java.util.RandomAccessSubList cannot be cast to java.util.ArrayList错误的问题

《解决java.util.RandomAccessSubListcannotbecasttojava.util.ArrayList错误的问题》当你尝试将RandomAccessSubList... 目录Java.util.RandomAccessSubList cannot be cast to java.

Apache服务器IP自动跳转域名的问题及解决方案

《Apache服务器IP自动跳转域名的问题及解决方案》本教程将详细介绍如何通过Apache虚拟主机配置实现这一功能,并解决常见问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,... 目录​​问题背景​​解决方案​​方法 1:修改 httpd-vhosts.conf(推荐)​​步骤

java反序列化serialVersionUID不一致问题及解决

《java反序列化serialVersionUID不一致问题及解决》文章主要讨论了在Java中序列化和反序列化过程中遇到的问题,特别是当实体类的`serialVersionUID`发生变化或未设置时,... 目录前言一、序列化、反序列化二、解决方法总结前言serialVersionUID变化后,反序列化失

C++ 多态性实战之何时使用 virtual 和 override的问题解析

《C++多态性实战之何时使用virtual和override的问题解析》在面向对象编程中,多态是一个核心概念,很多开发者在遇到override编译错误时,不清楚是否需要将基类函数声明为virt... 目录C++ 多态性实战:何时使用 virtual 和 override?引言问题场景判断是否需要多态的三个关