为什么我的进化模拟器中的生物表现得很愚蠢?
Why is the creature in my evolution simulator acting dumb?
我试着做了一个进化模拟器。所以我先从一个生物开始。但是这家伙并没有走向食物,而是有点前卫,前卫。
那么,这有什么问题???
我的代码中有两个模块,一个是主要的,另一个是我自己制作的。它们都在下面给出。请看看有什么问题。
主模块=>
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
谢谢:)
我发现了几个代码问题,首先这里似乎有错别字:
self.weightbx+=erry*self.biasx*self.lr
基于对称性,我预计 errx
,而不是 erry
。我对代码的下一个问题是:
ny=(food.ycor()-self.body.ycor())-dely
nx=(food.xcor()-self.body.xcor())-dely
除了 dely
与 delx
对称性问题之外,我还希望您去除这些数字的符号并使用您计算的符号:
ny = abs(food.ycor() - self.body.ycor()) * dely
nx = abs(food.xcor() - self.body.xcor()) * delx
为了尝试解决这些对称问题,我重写了您下面的代码以尽可能进行矢量数学计算,而不是计算单个坐标。 (由于海龟 Vec2D
乘法运算是一个内积,而不是简单的坐标乘法,所以这有些不妥。)
Think.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()
我的代码在模拟方面可能是错误的,但主要是为了让您了解使用 turtle 库时的替代技术。例如。使用 ontimer()
而不是 sleep()
;使用 setworldcoordinates()
构建隐式比例因子,而不是每次乘除; resusing turtles 因为它们是一个全局实体,不会收集垃圾。
我试着做了一个进化模拟器。所以我先从一个生物开始。但是这家伙并没有走向食物,而是有点前卫,前卫。 那么,这有什么问题??? 我的代码中有两个模块,一个是主要的,另一个是我自己制作的。它们都在下面给出。请看看有什么问题。 主模块=>
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
谢谢:)
我发现了几个代码问题,首先这里似乎有错别字:
self.weightbx+=erry*self.biasx*self.lr
基于对称性,我预计 errx
,而不是 erry
。我对代码的下一个问题是:
ny=(food.ycor()-self.body.ycor())-dely
nx=(food.xcor()-self.body.xcor())-dely
除了 dely
与 delx
对称性问题之外,我还希望您去除这些数字的符号并使用您计算的符号:
ny = abs(food.ycor() - self.body.ycor()) * dely
nx = abs(food.xcor() - self.body.xcor()) * delx
为了尝试解决这些对称问题,我重写了您下面的代码以尽可能进行矢量数学计算,而不是计算单个坐标。 (由于海龟 Vec2D
乘法运算是一个内积,而不是简单的坐标乘法,所以这有些不妥。)
Think.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()
我的代码在模拟方面可能是错误的,但主要是为了让您了解使用 turtle 库时的替代技术。例如。使用 ontimer()
而不是 sleep()
;使用 setworldcoordinates()
构建隐式比例因子,而不是每次乘除; resusing turtles 因为它们是一个全局实体,不会收集垃圾。