我想制作一个简单的程序来提高我对这类编程的了解.
我发现了一个非常有用的库,pyeasyGA,并且我尝试使用graphics.py创建一个简单的程序,从随机生成的“pass”序列创建一个收敛到一个点的序列.
这就是它的工作原理:
@H_502_9@def create_individual(data): a = [(randint(0,5),randint(0,5)) for n in range(len(data))] print(a) return a
此函数创建一系列传递,因为graphics.py库允许您通过为对象移动它想要移动它来移动对象.那是我的“个人”.
为了计算健身,我使用了这个:
@H_502_9@def fitness(individual,data): totX=0 totY=0 for elem in individual: totX+=elem[0] totY+=elem[1] tot = (totX,totY) return distEuclidea(arrivo,tot) def distEuclidea(p1,p2): x1 = p1[0] y1 = p1[1] x2 = p2[0] y2 = p2[1] return ((x2-x1)**2+(y2-y1)**2)**(1/2)
此功能计算距所需到达点的距离.
在这些过程之后,程序会产生很多代,并且会使个体具有最低的适应度,但它不起作用.
有谁可以帮助我吗?
编辑:
该计划似乎有效.唯一的问题是几代人.
最佳答案
我发现你的健身功能最难理解.而不是平均角落或找到中心,它将角落相加然后找到距离.什么是几何解释?
此外,您的代码是指ga.logGenerations,它不是当前pyeasyga 0.3.1版本的一部分.
以下是我对你的要求的近似.如果它没有标记,那么请用示例和/或图表来扩充您的解释:
@H_502_9@from time import sleep from random import randint from itertools import cycle from graphics import * from pyeasyga import pyeasyga NUMBER_OF_RECTANGLES = 4 # make one more than what you want to see NUMBER_OF_POINTS = 2 arrivo = (90,90) colori = ["red","green","blue","cyan","magenta","yellow"] X,Y = 0,1 def distEuclidea(p1,p2): x1,y1 = p1 x2,y2 = p2 return ((x2 - x1) ** 2 + (y2 - y1) ** 2) ** 0.5 def create_individual(colors): color = next(colors) while color in rectangles and rectangles[color] is None: # skip over deleted rectangle color = next(colors) if color in rectangles: rectangle = rectangles[color] p1,p2 = rectangle.getP1(),rectangle.getP2() points = [[p1.getX(),p1.getY()],[p2.getX(),p2.getY()]] else: points = [[randint(0,20),20)] for _ in range(NUMBER_OF_POINTS)] rectangle = Rectangle(*[Point(x,y) for x,y in points]) rectangle.setOutline(color) rectangle.draw(win) rectangles[color] = rectangle return [color,points] def fitness(individual,colors): _,points = individual rectangle = Rectangle(*[Point(x,y in points]) center = rectangle.getCenter() return distEuclidea(arrivo,(center.getX(),center.getY())) def mutate(individual): _,points = individual mutate_index = randint(0,NUMBER_OF_POINTS - 1) points[mutate_index][X] += randint(-1,1) points[mutate_index][Y] += randint(-1,1) def is_point_inside_rectangle(point,rectangle): p1,rectangle.getP2() return min(p1.getX(),p2.getX()) < point.getX() < max(p1.getX(),p2.getX()) and \ min(p1.getY(),p2.getY()) < point.getY() < max(p1.getY(),p2.getY()) win = GraphWin("Genetic Graphics",500,500) win.setCoords(0,100,100) rectangles = {} color_generator = cycle(colori[0:NUMBER_OF_RECTANGLES]) arrivoC = Circle(Point(*arrivo),1) arrivoC.setFill("orange") arrivoC.draw(win) number_of_rectangles = NUMBER_OF_RECTANGLES while True: ga = pyeasyga.GeneticAlgorithm(color_generator,\ elitism=False,\ maximise_fitness=False,\ crossover_probability=0.0,\ population_size=number_of_rectangles) ga.create_individual = create_individual ga.fitness_function = fitness ga.mutate_function = mutate ga.run() for member in ga.last_generation(): my_fitness,(my_color,my_points) = member if rectangles[my_color] is None: continue # skip over deleted rectangle rectangle = Rectangle(*[Point(x,y in my_points]) rectangle.setOutline(my_color) rectangle.draw(win) rectangles[my_color] = rectangle if is_point_inside_rectangle(arrivoC.getCenter(),rectangle): rectangles[my_color] = None # delete finished rectangle number_of_rectangles -= 1 if number_of_rectangles < 2: break sleep(0.1) for value in rectangles.values(): if value is not None: value.undraw() # delete unfinished rectangle win.getMouse() win.close()
以上是粗略的代码(例如,它并不总是保持通用域点和矩形独立于graphics.py点和矩形.)但它应该给你一些实验:
它在窗口的左下角创建矩形,遗传算法在右上角向目标突变,当它们到达目标时丢弃矩形.
我的代码的一部分复杂性是pyeasyga没有提供一个功能钩子来可视化每一代发生的事情.更好的方法可能是将pyeasyga子类化为添加这样的钩子以简化代码的逻辑.