我一直在尝试使用遗传算法来解决简单的替换密码,但是有一个问题我甚至没有接近预期的解决方案,拥有10000多代,人口约为200,同时对于过去8000代,我不太确定问题是否在于我的健身功能,在我培育人口的方式,或者,最有可能两者。
然后我才意识到,如果我不仅接受每组父母的第一个孩子(后来当我解释我的交叉时更多),但是两个孩子都产生了,健身值只是随机跳跃而我变得非常低"生成中的最高适应度"即使经历了很多代,这些价值也让我觉得这个问题很可能就是交叉本身。
整个程序可以在这里找到: http://pythonfiddle.com/genetic-algorithm/
使用以下字符串作为第一个参数进行测试: " iq ifcc vqqr fb rdq vfllcq na rdq cfjwhwz hr bnnb hcc hwwhbsqvqbre hwq vhlq"
应该成为:"我们将在中午在图书馆中间见面,所有的安排都是在#34;此算法中的基因材料由一个字符串组成,该字符串只包含字母表中的每个字母一次,而字母的顺序对应于加密字符串中的替换字母。所以在: " etaoinshrdlcumwfgypbvkjxqz" e代替a,t代替b等。
适应度函数结合了字母频率,双字母频率和最常见字词的匹配。
对于繁殖,我选择前20%,5%的健康较差的个体然后变异2%
交叉的工作原理如下:
# splice genes of parents together at random point in gene material
def crossover(male, female):
rand = random.randint(2,24)
child = male[:rand] + female[rand:]
child_two = male[rand:] + female[:rand]
repair_one = repair(child)
repair_two = repair(child_two)
return [repair_one, repair_two];
#repairs the child string to conform to gene standards(every gene is unique)
# cretain as much of the parent strings as possible
def repair(child):
repaired_child = child
temp = []
rand = random.randint(1,2)
omitted = []
double = []
for value in GENES:
count = child.count(value)
if count == 0:
omitted.append(value)
elif count == 2:
double.append(value)
for value in double:
if value > 1:
repaired_child = replacenth(repaired_child, value, omitted.pop(), rand)
return repaired_child;
我在2个父母的26个字母长串中选择一个随机点, 把它们切成两半,加入父母的一半。
母亲+父亲是第一个孩子父亲+母亲是第二个。当然,因为基因串中的每个字母必须是唯一的(否则密码是不可用的)我必须在之后修复基因。我这样做是首先计算每个字母出现的频率,然后用尚未使用的字母替换双字母,直到字符串只有唯一的字母。我知道遗传算法不是解决替换密码的最佳方法,但我认为尝试和测试会是一件有趣的事情,并且应该在相当长的时间内可行吗?
非常感谢任何帮助并指出错误