python - 为什么我的进化模拟器中的生物表现得很愚蠢?
问题描述
我试图制作一个进化模拟器。所以我先从一个生物开始。但是,这家伙并没有走向食物,而是前后左右。那么,这有什么问题???我的代码中有两个模块,一个是主要的,另一个是我的 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
谢谢 : )
解决方案
我看到几个代码问题,首先这里似乎有一个错字:
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
乘法运算是内积,而不仅仅是坐标的乘法。)
思考.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()
构建隐式比例因子,而不是每次乘除;重用海龟,因为它们是一个不会被垃圾收集的全球实体。
推荐阅读
- sql-server - 我想使用时间列选择最近 7 天的数据
- python - pd.cut cannot used for range in negative value
- python - Webscraping Python 试图拉变化的“id”
- git - 用于将自动工具构建的 git 子模块添加到 cmake 项目的 Cmake 宏
- vue.js - 你可以在 Vuejs 中将参数传递给 mixin 吗?
- database - 服务器与数据库的通信
- unity3d - 如何重置 IEnumerator 变量?
- flutter - 错误:检测到 0 个或 2 个或多个 [DropdownMenuItem] 具有相同的值 I/flutter (18363):'package:flutter/src/material/dropdown.dart':
- vb.net - 在 Visual Basic 中将一个窗体的值转换为另一个窗体
- coq - 不是形式 A -> A 的共归纳?