【问题标题】:Creating a genetic algorithm创建遗传算法
【发布时间】:2021-04-27 23:46:27
【问题描述】:

我正在尝试重新创建此代码:https://github.com/Code-Bullet/Smart-Dots-Genetic-Algorithm-Tutorial/tree/master/BestTutorialEver,但在 python 中,它不起作用,它不断变异最好的点,每一代都从更少的点开始。 下面是代码(我用 pygame 做图形):

大脑类:

class Brain(object):

    def __init__(self, size):
        self.size = size
        self.step = 0
        self.directions = [[0.0, 0.0] for j in range(size)]
        for i in range(len(self.directions)):
            randomAngle = random.uniform(0, 2 * math.pi)
            self.directions[i][0] = math.sin(randomAngle)
            self.directions[i][1] = math.cos(randomAngle)

    def mutate(self):
        mutationRate = 1
        for i in range(self.size):
            rand = random.random()
            if rand < mutationRate:
                dirAngle = math.acos(self.directions[i][1]) * (1.0 + random.random())
                self.directions[i][0] = math.sin(dirAngle)
                self.directions[i][1] = math.cos(dirAngle)

人口类别:

class Population(object):

    def __init__(self, size, win):
        self.bestDot = 0
        self.fitnessSum = 0.0
        self.win = win
        self.size = size
        self.dots = [Dot(win) for i in range(size)]

    def show(self):
        for i in range(self.size-1):
            self.dots[i+1].show()
        self.dots[0].show()

    def updt(self):
        for i in range(self.size):
            self.dots[i].updt()

    def calculateFitness(self):
        for i in range(self.size):
            self.dots[i].calculateFitness()


    def allDotsDead(self):
        for i in range(self.size):
            if not self.dots[i].dead and not self.dots[i].reachGoal:
                return False
        return True

    def naturalSelection(self):
        newDots = [Dot(self.win) for i in range(self.size)]
        self.setBestDot()
        self.calculateFitnessSum()
        newDots[0] = self.dots[self.bestDot].baby()
        newDots[0].isBest = True
        for i in range(self.size-1):
            parent = self.selectParent()
            newDots[i+1] = parent.baby()

        print(newDots[1])
        self.dots = newDots

    def calculateFitnessSum(self):
        self.fitnessSum = 0.0
        for i in range(self.size):
            self.fitnessSum += self.dots[i].fitness
        print(self.fitnessSum)

    def selectParent(self):
        rand = random.uniform(0, self.fitnessSum)
        runningSum = 0.0
        for i in range(self.size):
            runningSum += self.dots[i].fitness
            if runningSum >= rand:
                return self.dots[i]
        return None

    def mutate(self):
        for i in range(self.size):
            if not self.dots[i].isBest:
                self.dots[i].brain.mutate()

    def setBestDot(self):
        max = 0.0
        maxIndex = 0
        for i in range(len(self.dots)):
            if self.dots[i].fitness > max:
                max = self.dots[i].fitness
                maxIndex = i
        self.bestDot = maxIndex

点类:

WIDTH, HEIGHT = 720, 640
GOAL = (WIDTH / 2, 50)


class Dot(object):
    def __init__(self, win):
        self.win = win
        self.fitness = 0
        self.reachGoal = False
        self.dead = False
        self.brain = Brain(200)
        self.pos = [WIDTH / 2, HEIGHT - 50]
        self.vel = [0, 0]
        self.acc = [0, 0]
        self.isBest = False

    def move(self):
        if len(self.brain.directions) > self.brain.step:
            self.acc = self.brain.directions[self.brain.step]
            self.brain.step += 1
        else:
            self.dead = True

        for i in range(len(self.vel)): self.vel[i] += self.acc[i]
        if self.vel[0] >= 5: self.vel[0] = 5
        if self.vel[1] >= 5: self.vel[1] = 5
        for i in range(len(self.pos)): self.pos[i] += self.vel[i]

    def show(self):
        if self.isBest:
            pygame.draw.circle(self.win, (0, 255, 0), self.pos, 4)
        else:
            pygame.draw.circle(self.win, (200, 100, 0), self.pos, 2)

    def updt(self):
        if not self.dead and not self.reachGoal:
            self.move()
            if self.pos[0] < 4 or self.pos[1] < 4 or self.pos[0] > WIDTH - 4 or self.pos[1] > HEIGHT - 4:
                self.dead = True
            elif math.hypot(self.pos[0] - GOAL[0], self.pos[1] - GOAL[1]) < 5:
                self.reachGoal = True

    def calculateFitness(self):
        distToGoal = math.hypot(self.pos[0] - GOAL[0], self.pos[1] - GOAL[1])
        self.fitness = 1.0 / 16.0 + 10000.0 / (distToGoal * distToGoal)

    def baby(self):
        baby = Dot(self.win)
        baby.brain.directions = self.brain.directions
        return baby

问题是我指出最好的点不会变异,但它会变异或变成最差的点,而且,我不知道为什么,但在每一代中产生的点都更少(或者点的大脑完全相同,但不会变异甚至一点也不),突变率是 100%,但在每次运行中,点越来越少。 这里是第一代和第五代的截图:https://imgur.com/a/675Jxit

另外,如果有人在 python 中有一些遗传算法可以作为模型,那会有所帮助。

【问题讨论】:

    标签: python machine-learning genetic-algorithm


    【解决方案1】:

    我没有尝试您提到的项目。您可以尝试PyGAD,这是一个用于构建遗传算法和训练机器学习算法的 Python 3 库。它是开源的,您可以在 GitHub 找到代码。

    它使用简单,允许您以简单的方式控制交叉、变异和父选择运算符。您还可以使用 PyGAD 控制遗传算法的许多参数。

    PyGAD 还适用于用户定义的适应度函数,因此您可以对其进行调整以适应各种问题。

    安装 PyGAD (pip install pygad) 后,下面是一个简单的入门示例,它试图找到满足以下等式的 W1、W2 和 W3 的最佳值:

    44 = 4xW_1 - 2xW_2 + 1.2xW_3

    import pygad
    import numpy
    
    function_inputs = [4,-2, 1.2]
    desired_output = 44
    
    def fitness_func(solution, solution_idx):
        output = numpy.sum(solution*function_inputs)
        fitness = 1.0 / (numpy.abs(output - desired_output) + 0.000001)
    
        return fitness
    
    def on_generation(ga_instance):
        print(ga_instance.population)
    
    ga_instance = pygad.GA(num_generations=50,
                           num_parents_mating=2,
                           fitness_func=fitness_func,
                           num_genes=3,
                           sol_per_pop=5)
    
    ga_instance.run()
    ga_instance.plot_result()
    
    solution, solution_fitness, _ = ga_instance.best_solution()
    print("Parameters of the best solution : {solution}".format(solution=solution))
    print("Fitness value of the best solution = {solution_fitness}".format(solution_fitness=solution_fitness))
    

    【讨论】:

      猜你喜欢
      • 2021-11-21
      • 2019-06-22
      • 2017-08-27
      • 2011-01-11
      • 2012-04-26
      • 1970-01-01
      • 2012-07-07
      • 2011-07-22
      • 1970-01-01
      相关资源
      最近更新 更多