我试图用Python编写一个简单的生成算法,希望得到答案“Hello World”。它运行得不错,但在“最大迭代次数”恒定时无法给出正确答案。它只是在无限循环中运行。
这是我的代码:
import randomclass GAHello(): POPULATION_SIZE = 1000 ELITE_RATE = 0.1 SURVIVE_RATE = 0.5 MUTATION_RATE = 0.2 TARGET = "Hello World!" MAX_ITER = 1000 def InitializePopulation(self): tsize: int = len(self.TARGET) population = list() for i in range(0, self.POPULATION_SIZE): str = '' for j in range(0, tsize): str += chr(int(random.random() * 255)) citizen: Genome = Genome(str) population.append(citizen) return population def Mutation(self, strng): tsize: int = len(self.TARGET) ipos: int = int(random.random() * tsize) delta: chr = chr(int(random.random() * 255)) return strng[0: ipos] + delta + strng[ipos + 1:] def mate(self, population): esize: int = int(self.POPULATION_SIZE * self.ELITE_RATE) tsize: int = len(self.TARGET) children = self.select_elite(population, esize) for i in range(esize, self.POPULATION_SIZE): i1: int = int(random.random() * self.POPULATION_SIZE * self.SURVIVE_RATE) i2: int = int(random.random() * self.POPULATION_SIZE * self.SURVIVE_RATE) spos: int = int(random.random() * tsize) strng: str = population[i1][0: spos] + population[i2][spos:] if(random.random() < self.MUTATION_RATE): strng = self.Mutation(strng) child = Genome(strng) children.append(child) return children def go(self): popul = self.InitializePopulation() for i in range(0, self.MAX_ITER): popul.sort() print("{} > {}".format(i, str(popul[0]))) if(popul[0].fitness == 0): break popul = self.mate(popul) def select_elite(self, population, esize): children = list() for i in range(0, esize): children.append(population[i]) return childrenclass Genome(): strng = "" fitness = 0 def __init__(self, strng): self.strng = strng fitness = 0 for j in range(0, len(strng)): fitness += abs(ord(self.strng[j]) - ord(GAHello.TARGET[j])) self.fitness = fitness def __lt__(self, other): return self.fitness - other.fitness def __str__(self): return "{} {}".format(self.fitness, self.strng) def __getitem__(self, item): return self.strng[item]
谢谢您的建议。我在这方面真的是个新手,我只是在尝试和实验这些算法和优化方法来探索人工智能的方法。
更新
运行的地方
if __name__ == '__main__': algo = GAHello() algo.go()
我的输出:
0 > 1122 Ü<pñsÅá׺Ræ¾1 > 1015 ÷zËÔ5AÀ©«2 > 989 "ÆþõZi±Pmê3 > 1076 ØáíAÀ©«4 > 1039 #ÆþÕRæ´Ìosß5 > 946 ×ZÍG¤'ÒÙË6 > 774 $\àPÉ7 > 1194 A®Ä§öÝÖ Ð8 > 479 @r=q^Ü´{J9 > 778 X'YþH_õÏÆ10 > 642 z¶$oKÐ{...172 > 1330 ê¸EïôÀ«ä£ü173 > 1085 ÔOÕÛ½e·À×äÒU174 > 761 OÕÛ½¤¯£+} 175 > 903 P½?-´ëÎm|4Ô176 > 736 àPSÈe<1177 > 1130 ªê/*ñ¤îã¹¾^178 > 772 OÐS8´°jÓ£...990 > 1017 6ó¨QøÇ?¨Úí991 > 1006 |5ÇÐR·Ü¸í992 > 968 ×5QÍË?1V í993 > 747 B ªÄ*¶R·Ü$F994 > 607 `ªLaøVLº995 > 744 Ìx7eøi;ÄÝ[996 > 957 ¹8/ñ^ ¤997 > 916 Ú'dúý8}û« [998 > 892 ÛWòeTùv6ç®999 > 916 õg8g»}à³À
应该有的样本输出:
0 > 419 Un~?z^Kr??p┬1 > 262 Un~?z^Kr?j?↨2 > 262 Un~?z^Kr?j?↨…15 > 46 Afpdm'Ynosa"16 > 46 Afpdm'Ynosa"17 > 42 Afpdm'Ynoia"18 > 27 Jfpmm↓Vopoa"…33 > 9 Ielmo▼Wnole"34 > 8 Ielmo▲Vopld"35 > 8 Ielmo▲Vopld"…50 > 1 Hello World"51 > 1 Hello World"52 > 0 Hello World!
回答:
我认为你的主要问题在于列表排序。
popul.sort()
尝试
popul.sort(key=lambda x: x.fitness)
这将根据它们的适应度水平进行排序,我认为这是你想要的效果。
我还将所有int(random.random()*255)
改成了random.randint(30, 125)
,以便只获取有效字符,因为我运行时遇到了问题。