python - 遗传算法不工作
python - genetic algorithm not working
我做了一个遗传算法,目标是得到 20 以上的 "organism's" y 位置。问题出在 class:
下面的部分
import random as r
class Organism(object):
def __init__(self, genes,ID):
self.genes = genes
self.position = [0,0]
self.thisTime=str()
self.geneTranslation = []
self.ID=ID
def move(self,d):
if d == "f" or d == "forward":
self.position[1] += 1
elif d == "b" or d == "back":
self.position[1] -= 1
elif d == "r" or d == "right":
self.position[0] += 1
elif d == "l" or d == "left":
self.position[0] -= 1
print(self.position)
def isInContactWith(self,point):
point = list(point)
if self.position == point:
return True
else:
return False
def run(self):
for i in range(0,4):
if i == 0:
self.geneTranslation.extend(["f"] * self.genes[0])
elif i == 1:
self.geneTranslation.extend(["b"] * self.genes[1])
elif i == 2:
self.geneTranslation.extend(["r"] * self.genes[2])
elif i == 3:
self.geneTranslation.extend(["l"] * self.genes[3])
r.shuffle(self.geneTranslation)
for x in range(1,20):
try:
self.thisTime = r.choice(self.geneTranslation)
self.move(self.thisTime)
except:
pass
population = []
yValues={}
running = True
BestOrganism=Organism([25,25,25,25],0)
for count in range(50):
for x in range(100):
a = lambda: r.randint(-3, 3)
b = BestOrganism.genes[:]
anOrganism = Organism(b[:],x)
for count in range(len(anOrganism.genes[:])):
anOrganism.genes[count] += int(a())
population.append(anOrganism)
for j in range(len(population)):
print("Organism " + str(population[j].ID) + str(population[j].genes))
population[j].run()
yValues[population[j].ID]=population[j].position[1]
if population[j].position[1]>=20:
print(population[j].genes)
running = False
break
BestOrganism=max(yValues)
for k in range(len(population[:])):
if population[k].ID==BestOrganism:
BestOrganism=population[k]
print(yValues[max(yValues)])
print(BestOrganism.genes[:])
population=[]
yValues={}
如您所见,基因决定了生物体朝某个方向前进的概率。产生较低 y 值的基因被淘汰,新一代由 BestOrganism 产生一点突变。看起来这应该会产生更多的生物体,这些生物体具有更高百分比的基因,但事实并非如此。还有其他我没有考虑的因素吗?
主要问题是您误用了 max
:您正在寻找具有最大键 (ID) 而不是最大 Y 值的有机体。试试 max(yValues, key=yValues.get)
.
您也可以尝试将 move
步数从 20
增加到更大的步数。
最后,稍微清理一下代码会让事情变得更清晰。
我做了一个遗传算法,目标是得到 20 以上的 "organism's" y 位置。问题出在 class:
下面的部分import random as r
class Organism(object):
def __init__(self, genes,ID):
self.genes = genes
self.position = [0,0]
self.thisTime=str()
self.geneTranslation = []
self.ID=ID
def move(self,d):
if d == "f" or d == "forward":
self.position[1] += 1
elif d == "b" or d == "back":
self.position[1] -= 1
elif d == "r" or d == "right":
self.position[0] += 1
elif d == "l" or d == "left":
self.position[0] -= 1
print(self.position)
def isInContactWith(self,point):
point = list(point)
if self.position == point:
return True
else:
return False
def run(self):
for i in range(0,4):
if i == 0:
self.geneTranslation.extend(["f"] * self.genes[0])
elif i == 1:
self.geneTranslation.extend(["b"] * self.genes[1])
elif i == 2:
self.geneTranslation.extend(["r"] * self.genes[2])
elif i == 3:
self.geneTranslation.extend(["l"] * self.genes[3])
r.shuffle(self.geneTranslation)
for x in range(1,20):
try:
self.thisTime = r.choice(self.geneTranslation)
self.move(self.thisTime)
except:
pass
population = []
yValues={}
running = True
BestOrganism=Organism([25,25,25,25],0)
for count in range(50):
for x in range(100):
a = lambda: r.randint(-3, 3)
b = BestOrganism.genes[:]
anOrganism = Organism(b[:],x)
for count in range(len(anOrganism.genes[:])):
anOrganism.genes[count] += int(a())
population.append(anOrganism)
for j in range(len(population)):
print("Organism " + str(population[j].ID) + str(population[j].genes))
population[j].run()
yValues[population[j].ID]=population[j].position[1]
if population[j].position[1]>=20:
print(population[j].genes)
running = False
break
BestOrganism=max(yValues)
for k in range(len(population[:])):
if population[k].ID==BestOrganism:
BestOrganism=population[k]
print(yValues[max(yValues)])
print(BestOrganism.genes[:])
population=[]
yValues={}
如您所见,基因决定了生物体朝某个方向前进的概率。产生较低 y 值的基因被淘汰,新一代由 BestOrganism 产生一点突变。看起来这应该会产生更多的生物体,这些生物体具有更高百分比的基因,但事实并非如此。还有其他我没有考虑的因素吗?
主要问题是您误用了 max
:您正在寻找具有最大键 (ID) 而不是最大 Y 值的有机体。试试 max(yValues, key=yValues.get)
.
您也可以尝试将 move
步数从 20
增加到更大的步数。
最后,稍微清理一下代码会让事情变得更清晰。