用于Python中的“智能点”游戏的遗传算法不工作

过去几天我一直在尝试实现所谓的“智能点”游戏。我第一次在Code Bullet的YouTube频道上看到它:https://www.youtube.com/watch?v=BOZfhUcNiqk。不幸的是,它是用Processing语言编写的,而我唯一勉强熟悉的语言是Python。我完成了游戏的Python版本,但出现了一些错误。

问题是,在第二代被选为最佳的点几乎立即停止移动。我认为这与我在面向对象编程方面的不足以及错误复制Brain类有关。步骤(我用来移动的)从开始设置的零跳到最大值(200),在主循环的第一次或第二次循环时。但问题不止于此。在下一代,当我试图将大脑步骤设置为零时,它就崩溃了,显示如下错误:

AttributeError: 'NoneType' object has no attribute 'brain'

我尝试手动设置新的大脑,但仍然得到相同的错误。如果有已经完成这个项目或有时间帮助我解决这个错误或整个项目的人,我将不胜感激。

我知道代码中有很多未使用的内容,但那只是我尝试修复它时的产物:(

注释掉的代码是我之前使用的一些旧代码。

main2.py(主循环):

import pygameimport klase2pygame.init()def main():    win = pygame.display.set_mode((klase2.WIN_W, klase2.WIN_H))    clock = pygame.time.Clock()    population = klase2.Population()    dots = population.return_dots(1000)    goal = klase2.Goal()    run = True    while run:        clock.tick(30)        for event in pygame.event.get():            if event.type == pygame.QUIT:                run = False        win.fill((255, 255, 255))        goal.draw_goal(win)        for dot in dots:            dot.draw_dot(win)            dot.update_dot()        if population.all_dots_dead():            # 自然选择            population.natural_selection()            # 变异            dots = population.mutate_dots()            population.gen += 1            print(population.gen)        pygame.display.update()main()

kase2(处理所有函数和类):

import pygameimport numpy as npfrom pygame import gfxdrawimport mathimport randompygame.init()WIN_W = 500WIN_H = 500class Brain:    def __init__(self, size):        self.step = 0        self.size = size        self.directionsx = np.array(np.random.uniform(low=-2.5, high=2.5, size=int(self.size / 2)))        self.directionsy = np.array(np.random.uniform(low=-2.5, high=2.5, size=int(self.size / 2)))    def clone(self):        self.size = self.size        self.directionsx = self.directionsx        self.directionsy = self.directionsy        self.step = 0class Goal:    def __init__(self):        self.x = WIN_W / 2        self.y = 10        self.color = (255, 20, 20)        self.r = 5    def draw_goal(self, win):        pygame.gfxdraw.aacircle(win, int(self.x), int(self.y), self.r, self.color)        pygame.gfxdraw.filled_circle(win, int(self.x), int(self.y), self.r, self.color)class Dot:    goal = Goal()    def __init__(self):        self.tick = 0        self.goal = Goal()        self.brain = Brain(400)        self.velx = 0        self.vely = 0        self.accx = 0        self.accy = 0        self.x = WIN_W / 2        self.y = WIN_H - 10        self.r = 3        self.color = (0, 0, 0)        self.alive = True        self.velLimit = 5        self.fitness = 0    def draw_dot(self, win):        pygame.gfxdraw.aacircle(win, int(self.x), int(self.y), self.r, self.color)        pygame.gfxdraw.filled_circle(win, int(self.x), int(self.y), self.r, self.color)    def move_dot(self):        if self.brain.size / 2 > self.brain.step:            self.accx = self.brain.directionsx[self.brain.step]            self.accy = self.brain.directionsy[self.brain.step]            self.brain.step += 1        else:            self.alive = False        self.velx += self.accx        self.vely += self.accy        if self.velx > self.velLimit:            self.velx = self.velLimit        elif self.velx < -self.velLimit:            self.velx = -self.velLimit        if self.vely > self.velLimit:            self.vely = self.velLimit        elif self.vely < -self.velLimit:            self.vely = -self.velLimit        self.x += self.velx        self.y += self.vely    def update_dot(self):        if not self.reached_goal():            self.tick += 1        if self.alive:            self.move_dot()            if self.x < 0 + self.r or self.x > WIN_W - self.r or self.y < 0 + self.r or self.y > WIN_H - self.r or self.reached_goal():                self.alive = False    def distance_to_goal(self):        a = abs(self.x - self.goal.x)        b = abs(self.y - self.goal.y)        return math.sqrt(a**2 + b**2)    def reached_goal(self):        if self.distance_to_goal() <= self.r + self.goal.r:            return True        return False    def fitness_dot(self):        if self.reached_goal():            self.fitness = 1 / (self.brain.step)        else:            self.fitness = 1 / (self.distance_to_goal()**2)        return self.fitnessclass Population:    def __init__(self):        self.dots = []        self.newDots = []        self.gen = 0        self.mutateChance = 800        self.size = 0        self.fitness_sum = 0    def return_dots(self, size):        self.size = size        for _ in range(size):            self.dots.append(Dot())        return self.dots    def all_dots_dead(self):        for i in range(len(self.dots)):            if self.dots[i].alive:                return False        return True    def sort_dots(self):        self.dots = sorted(self.dots, key=lambda dot: dot.fitness, reverse=True)    def sum_fitness(self):        for dot in self.dots:            self.fitness_sum += dot.fitness_dot()        return self.fitness_sum    def get_parent(self):        rand = random.uniform(0, self.fitness_sum)        running_sum = 0        for dot in self.dots:            running_sum += dot.fitness            if running_sum >= rand:                return dot    def natural_selection(self):        for dot in self.dots:            dot.fitness_dot()        self.sort_dots()        self.newDots.append(self.dots[0])        self.sum_fitness()        for i in range(1, len(self.dots)):            parent = self.get_parent()            self.newDots.append(Dot())            self.newDots[i].brain = parent.brain            self.newDots[i].brain.step = 0        self.dots = self.newDots    def mutate_dots(self):        for i in range(1, len(self.dots)):            rand = random.randint(0, 1000)            if rand > self.mutateChance:                self.dots[i].brain.directionsx = np.array(np.random.uniform(low=-2.5, high=2.5, size=int(self.dots[i].brain.size / 2)))                self.dots[i].brain.directionsy = np.array(np.random.uniform(low=-2.5, high=2.5, size=int(self.dots[i].brain.size / 2)))        return self.dots    # def natural_selection(self):    #     self.selectedDots = []    #     for dot in self.dots:    #         dot.fitness_dot()    #     self.sort_dots()    #     for i in range(0, int(len(self.dots) / 3)):    #         self.selectedDots.append(self.dots[i])    #         self.selectedDots[i].tick = 0    #         self.selectedDots[i].velx = 0    #         self.selectedDots[i].vely = 0    #         self.selectedDots[i].accx = 0    #         self.selectedDots[i].accy = 0    #         self.selectedDots[i].x = WIN_W / 2    #         self.selectedDots[i].y = WIN_H - 10    #         self.selectedDots[i].alive = True    #         self.selectedDots[i].fitness = 0    #         self.selectedDots[i].brain.step = 0    #         self.selectedDots[i].goal = Goal()    #    # def new_dots(self):    #     for i in range(len(self.selectedDots), len(self.dots)):    #         self.selectedDots.append(Dot())    #     self.dots = self.selectedDots    #    # def mutate_dots(self):    #     for i, dot in enumerate(self.dots):    #         isMutating = random.randint(0, 1000)    #         if self.mutateChance > isMutating and i > int(len(self.dots) / 3) and i < (2 * int((len(self.dots) / 3))):    #             for j in range(len(dot.brain.directionsx)):    #                 isMutatingDir = random.randint(0, 1000)    #                 if isMutatingDir >= 800:    #                     dot.brain.directionsx[j] = np.random.uniform(low=-2.5, high=2.5, size=1)    #             for j in range(len(dot.brain.directionsy)):    #                 isMutatingDir = random.randint(0, 1000)    #                 if isMutatingDir >= 800:    #                     dot.brain.directionsy[j] = np.random.uniform(low=-2.5, high=2.5, size=1)    #     return self.dots

回答:

NoneType错误是由get_parent方法引起的。它搜索子点,但如果搜索失败则没有返回值(相当于return None)。以下代码可以解决这个错误

def get_parent(self):    rand = random.uniform(0, self.fitness_sum)    running_sum = 0    for dot in self.dots:        running_sum += dot.fitness        if running_sum >= rand:            return dot    return self.dots[0]  # 搜索失败,返回第一个点

Related Posts

多维度Top-k评分

例如,在机器学习中的自然语言处理中,通常使用波束搜索来…

R – Caret train() “错误:停止” 与 “在newdata中未找到对象中使用的所有变量名”

我正在尝试为蘑菇数据构建一个简单的朴素贝叶斯分类器。我…

创建训练和测试数据集分割,数据嵌套在多个文件夹中

我正在准备数据以训练一个图像识别模型。目前我有一个文件…

我的神经网络预测出现错误:IndexError: list index out of range

我正在进行一个简单的垃圾邮件/非垃圾邮件文本分类。我的…

python 给出数组是一维的,但索引了两个维度错误

我已经为 miniBatchGradientDesce…

TensorFlow自定义训练步骤使用不同的损失函数

背景 根据TensorFlow文档,可以使用以下方式执…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注