我无法使用python中的遗传算法找到正确的答案

时间:2019-03-04 20:04:03

标签: python python-3.x algorithm artificial-intelligence genetic-algorithm

我正在尝试使用python编写一种简单的生成算法,这应该给我带来“ Hello World”的美誉。它工作正常,但无法通过“最大迭代”常量给出核心答案。它只是无限循环地工作。

这是我下面的代码:

import random

class 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 children



class 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^Ü´{J
9 > 778 X'YþH_õÏÆ
10 > 642 z¶$oKÐ{
...
172 > 1330 ê¸EïôÀ«ä£ü
173 > 1085 ÔOÕÛ½e·À×äÒU
174 > 761 OÕÛ½¤¯£+} 
175 > 903 P½?-´ëÎm|4Ô
176 > 736 àPSÈe<1
177 > 1130 ªê/*ñ¤îã¹¾^
178 > 772 OÐS8´°jÓ£
...
990 > 1017 6ó¨QøÇ?¨Úí
991 > 1006 |5ÇÐR·Ü¸í
992 > 968 ×5QÍË?1V í
993 > 747 B ªÄ*¶R·Ü$F
994 > 607  `ªLaøVLº
995 > 744 Ìx7eøi;ÄÝ[
996 > 957 ¹8/ñ^ ¤
997 > 916 Ú'dúý8}û« [
998 > 892 ÛWòeTùv­6ç®
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!

1 个答案:

答案 0 :(得分:2)

我相信,您的列表排序是您的主要问题。

popul.sort()

尝试

popul.sort(key=lambda x: x.fitness)

这将按照他们的健康水平对他们进行排序,这就是我认为您想要的。

我也将所有int(random.random()*255)更改为random.randint(30, 125)以仅获取有效字符,因为我在运行时遇到了麻烦。