进化算法(二)句子配对

来源:互联网 发布:淘宝网小众女鞋店 编辑:程序博客网 时间:2024/04/30 00:24
"""Visualize Genetic Algorithm to match the target phrase.Visit my tutorial website for more: https://morvanzhou.github.io/tutorials/"""import numpy as npTARGET_PHRASE = 'zhou long tao zui shuai he he!'       # target DNAPOP_SIZE = 300                      # population sizeCROSS_RATE = 0.4                    # mating probability (DNA crossover)MUTATION_RATE = 0.01                # mutation probabilityN_GENERATIONS = 1000DNA_SIZE = len(TARGET_PHRASE)TARGET_ASCII = np.fromstring(TARGET_PHRASE, dtype=np.uint8)  # convert string to numberASCII_BOUND = [32, 126]class GA(object):    def __init__(self, DNA_size, DNA_bound, cross_rate, mutation_rate, pop_size):        self.DNA_size = DNA_size        DNA_bound[1] += 1        self.DNA_bound = DNA_bound        self.cross_rate = cross_rate        self.mutate_rate = mutation_rate        self.pop_size = pop_size        self.pop = np.random.randint(*DNA_bound, size=(pop_size, DNA_size)).astype(np.int8)  # int8 for convert to ASCII    def translateDNA(self, DNA):                 # convert to readable string        return DNA.tostring().decode('ascii')    def get_fitness(self):                      # count how many character matches        match_count = (self.pop == TARGET_ASCII).sum(axis=1)        return match_count    def select(self):        fitness = self.get_fitness() + 1e-4     # add a small amount to avoid all zero fitness        idx = np.random.choice(np.arange(self.pop_size), size=self.pop_size, replace=True, p=fitness/fitness.sum())        return self.pop[idx]    def crossover(self, parent, pop):        if np.random.rand() < self.cross_rate:            i_ = np.random.randint(0, self.pop_size, size=1)                        # select another individual from pop            cross_points = np.random.randint(0, 2, self.DNA_size).astype(np.bool)   # choose crossover points            parent[cross_points] = pop[i_, cross_points]                            # mating and produce one child        return parent    def mutate(self, child):        for point in range(self.DNA_size):            if np.random.rand() < self.mutate_rate:                child[point] = np.random.randint(*self.DNA_bound)  # choose a random ASCII index        return child    def evolve(self):        pop = self.select()        pop_copy = pop.copy()        for parent in pop:  # for every parent            child = self.crossover(parent, pop_copy)            child = self.mutate(child)            parent[:] = child        self.pop = popif __name__ == '__main__':    ga = GA(DNA_size=DNA_SIZE, DNA_bound=ASCII_BOUND, cross_rate=CROSS_RATE,            mutation_rate=MUTATION_RATE, pop_size=POP_SIZE)    for generation in range(N_GENERATIONS):        fitness = ga.get_fitness()        best_DNA = ga.pop[np.argmax(fitness)]        best_phrase = ga.translateDNA(best_DNA)        print('Gen', generation, ': ', best_phrase)        if best_phrase == TARGET_PHRASE:            break        ga.evolve()