首页 > 解决方案 > 为什么我的进化模拟器中的生物表现得很愚蠢?

问题描述

我试图制作一个进化模拟器。所以我先从一个生物开始。但是,这家伙并没有走向食物,而是前后左右。那么,这有什么问题???我的代码中有两个模块,一个是主要的,另一个是我的 Think-made。它们都在下面给出。请看看有什么问题。主模块=>

import turtle,random,Think,time

world=turtle.Screen()
world.setup(400,400)#O(0,0),X(180,0),X'(-185,0),Y(0,185),Y'(0,-180)

def growfood():
food=turtle.Turtle()
food.color("green")
food.shape("circle")
food.shapesize(0.4)
food.penup()
food.speed(0)
food.goto(random.randint(-185,180),random.randint(-180,185))
return food

class Creature:
  body=None
  brain=Think.neuron()

 def __init__(self):
   self.body=turtle.Turtle()
   #self.body.penup()
   self.body.color("blue")
   self.body.shape("square")
   self.body.shapesize(0.5)

 def move(self,y,x,dely,delx):
    self.body.goto(self.body.xcor()+x*5,self.body.ycor()+y*5)
    ny=(food.ycor()-self.body.ycor())-dely
    nx=(food.xcor()-self.body.xcor())-dely
        self.brain.adjust(dely, delx, ny/5, nx/5, y, x)

 def locatefood(self):
   delx=food.xcor()-self.body.xcor()
   dely=food.ycor()-self.body.ycor()
   return dely,delx

  def think(self):
        dely,delx=self.locatefood()
        y,x=self.brain.think(dely,delx)
        print("(x,y)=("+str(x)+","+str(y)+")")
        self.move(y,x,dely,delx)

crt=Creature()      
food=growfood()
run=0
while run<120:
  world.update()
  crt.think()
  if crt.body.distance(food)<15:
    food=growfood()
  time.sleep(1)

思考模块=>

from math import tanh
from random import random


class neuron:
biasy,biasx=1,1
lr=1
weighty,weightx,weightby,weightbx=random(),random(),random(),random()
def adjust(self,dely,delx,ny,nx,y,x):
        #adjust y
        erry=ny-y
        self.weighty+=erry*dely*self.lr
    self.weightby+=erry*self.biasy*self.lr
        #adjust x
    errx=nx-x
    self.weightx+=errx*delx*self.lr
    self.weightbx+=erry*self.biasx*self.lr

def think(self,dely,delx):
    y=dely*self.weighty+self.biasy*self.weightby
        x=delx*self.weightx+self.biasx*self.weightbx
        y=tanh(y)
        print(y)
    if y>0:
       y=1
    elif y<0:
       y=-1
    else:
       y=0
        x=tanh(x)
     print(x)
    if x>0:
        x=1
    elif x<0:
        x=-1
        else:
        x=0
    return y,x

谢谢 : )

标签: pythonlinear-regressionturtle-graphicspython-turtleevolutionary-algorithm

解决方案


我看到几个代码问题,首先这里似乎有一个错字:

self.weightbx+=erry*self.biasx*self.lr

基于对称性,我会预料到errx,而不是erry。我对代码的下一个问题是:

ny=(food.ycor()-self.body.ycor())-dely
nx=(food.xcor()-self.body.xcor())-dely

除了delydelx对称性问题之外,我还希望您去掉这些数字的符号并使用您计算的符号:

ny = abs(food.ycor() - self.body.ycor()) * dely
nx = abs(food.xcor() - self.body.xcor()) * delx

为了尝试解决这些对称性问题,我在下面重写了您的代码,以尽可能进行矢量数学运算,而不是计算单个坐标。(这在某种程度上分解了,因为海龟Vec2D乘法运算是内积,而不仅仅是坐标的乘法。)

思考.py

from math import tanh, copysign
from random import random
from turtle import Vec2D

class neuron:
    lr = 1
    bias = Vec2D(1, 1)
    weight = Vec2D(random(), random())
    weightb = Vec2D(random(), random())

    def adjust(self, delta, guess, position):
        error = (guess - position) * self.lr

        self.weight += Vec2D(error[0] * delta[0], error[1] * delta[1])
        self.weightb += Vec2D(error[0] * self.bias[0], error[1] * self.bias[1])

    def think(self, delta):
        x = delta[0] * self.weight[0] + self.bias[0] * self.weightb[0]
        y = delta[1] * self.weight[1] + self.bias[1] * self.weightb[1]

        return Vec2D(copysign(1, tanh(x)), copysign(1, tanh(y)))

主程序:

from turtle import Screen, Turtle, Vec2D
from random import randint
from Think import neuron

class Creature:
    body = Turtle()
    brain = neuron()

    def __init__(self):
        self.body.hideturtle()
        self.body.color('blue')
        self.body.shape('square')
        self.body.shapesize(0.5)
        #self.body.penup()
        self.body.showturtle()

    def move(self, position, delta):
        self.body.goto(self.body.position() + position)
        guess = self.locatefood()
        guess = Vec2D(abs(guess[0]) * delta[0], abs(guess[1]) * delta[1])
        self.brain.adjust(delta, guess, position)

    def locatefood(self):
        return food.position() - self.body.position()

    def think(self):
        delta = self.locatefood()
        position = self.brain.think(delta)
        self.move(position, delta)

def growfood(previous):
    if previous:  # don't waste food!
        food = previous
        food.hideturtle()
        food.color('orange')
        food.stamp()
    else:
        food = Turtle()
        food.hideturtle()
        food.shape('circle')
        food.shapesize(0.4)
        food.penup()

    food.color('green')
    food.goto(randint(-37, 36), randint(-36, 37))
    food.showturtle()

    return food

def seek():
    global run, food

    crt.think()

    if crt.body.distance(food) < 2:
        food = growfood(food)

    if run > 0:
        run -= 1
        world.ontimer(seek, 1000)  # milliseconds

world = Screen()
world.setup(400, 400)
world.setworldcoordinates(-40, -40, 40, 40)  # scaled by 5

run = 120
food = growfood(None)
crt = Creature()

seek()

world.exitonclick()

我的代码在模拟方面可能是错误的,但主要是为了启发您在使用海龟库时了解替代技术。例如使用ontimer()而不是sleep(); 用于setworldcoordinates()构建隐式比例因子,而不是每次乘除;重用海龟,因为它们是一个不会被垃圾收集的全球实体。

在此处输入图像描述


推荐阅读