我正在研究一个python脚本来测试遗传编程。 作为一个练习,我做了一个试图猜测的简单脚本 没有整个人口部分的字符串。
我的代码是:
# acts as a gene
# it has three operations:
# Mutation : One character is changed
# Replication: a sequencepart is duplicated
# Extinction : A sequencepart is lost
# Crossover : the sequence is crossed with another Sequence
import random
class StringGene:
def __init__(self, s):
self.sequence = s
self.allowedChars = "ABCDEFGHIJKLMOPQRSTUVWXYZ/{}[]*()+-"
def __str__(self):
return self.sequence
def Mutation(self):
x = random.randint(0, len(self.sequence)-1)
r = random.randint(0, len(self.allowedChars)-1)
d = self.sequence
self.sequence = d[:x-1]+ self.allowedChars[r] + d[x:]
def Replication(self):
x1 = random.randint(0, len(self.sequence)-1)
x2 = random.randint(0, len(self.sequence)-1)
self.sequence =self.sequence[:x1]+ self.sequence[x1:x2] + self.sequence[x2:]
self.sequence = self.sequence[:32]
def Extinction(self):
x1 = random.randint(0, len(self.sequence)-1)
x2 = random.randint(0, len(self.sequence)-1)
self.sequence = self.sequence[:x1] + self.sequence[x2:]
def CrossOver(self, s):
x1 = random.randint(0, len(self.sequence)-1)
x2 = random.randint(0, len(s)-1)
self.sequence = self.sequence[:x1+1]+ s[x2:]
#x1 = random.randint(0, len(self.sequence)-1)
#self.sequence = s[:x2 ] + self.sequence[x1+1:]
if __name__== "__main__":
import itertools
def hamdist(str1, str2):
if (len(str2)>len(str1)):
str1, str2 = str2, str1
str2 = str2.ljust(len(str1))
return sum(itertools.imap(str.__ne__, str1, str2))
g = StringGene("Hi there, Hello World !")
g.Mutation()
print "gm: " + str(g)
g.Replication()
print "gr: " + str(g)
g.Extinction()
print "ge: " + str(g)
h = StringGene("Hello there, partner")
print "h: " + str(h)
g.CrossOver(str(h))
print "gc: " + str(g)
change = 0
oldres = 100
solutionstring = "Hello Daniel. Nice to meet you."
best = StringGene("")
res = 100
print solutionstring
while (res > 0):
g.Mutation()
g.Replication()
g.Extinction()
res = hamdist(str(g), solutionstring)
if res<oldres:
print "'"+ str(g) + "'"
print "'"+ str(best) + "'"
best = g
oldres = res
else :
g = best
change = change + 1
print "Solution:" + str(g)+ " " + str(hamdist(solutionstring, str(g))) + str (change)
我有一个粗糙的汉明距离作为衡量解决方案字符串的距离 与现在不同。但是我希望能够有所不同 在猜测的长度,所以我介绍了复制和删除部分 的字符串。
现在,字符串无限增长,解决方案字符串永远不会 找到。你能指出我错在哪里吗?
你能建议改进吗?
欢呼声
答案 0 :(得分:1)
您的StringGene
个对象是可变的,这意味着当您执行best = g
之类的操作时,您正在使g
和best
引用相同的对象。由于在第一步之后你只有一个对象,每个变异都会被永久地应用,无论它是否成功,g
和best
之间的所有比较都是同一个对象之间的比较。
您需要实现复制运算符,或使实例不可变,并让每个变异运算符返回'基因'的修改版本。
此外,如果第一个突变无法改善字符串,则将g
设置为best
,这是一个空字符串,完全丢弃您的起始字符串。
最后,规范测试字符串是“Methinks它就像一个黄鼠狼”。
答案 1 :(得分:0)
最简单的方法可能是限制猜测字符串的持续时间。不要超过一定长度的猜测。
我查看了你的代码,我在Python中找不到任何错误,但是你可能只是错误地引用或索引数组,导致总是在猜测字符串中添加新字符,所以你的字符串总是在增加...我不知道这是不是错误,但之前发生过这样的事情,所以请仔细检查你的数组指标。 ;)
答案 2 :(得分:0)
我认为你的健身功能太简单了。我会玩两个变量,一个是大小距离,另一个是你的“hamdist”。尺寸差异越大,它对总体健康的影响就越大。所以将两者加在一起,加上一些百分比常数。
我对python也不是很熟悉,但我认为这不是你正在做的事情。
答案 3 :(得分:0)
首先,你所做的是遗传算法,而不是遗传编程(这是一个相关但不同的概念)。
我不懂Python,但看起来你的灭绝功能存在一个主要问题。据我所知,如果x1&gt; x2它导致字符串的大小增加而不是减少(x1和x2之间的部分实际上加倍)。当x1&gt;时,复制功能会发生什么? x2,我不知道如何不知道Python。
还要记住,维持人口是有效解决遗传算法问题的关键。交叉是算法的重要组成部分,如果它们不是在人口成员之间产生的话,它们几乎没有意义(同样,人口越多,越多越好,大部分时间)。您提供的代码取决于单个样本的突变以达到预期的结果,因此与简单的强力方法相比,极不可能产生任何有用的东西。