一个遗传算法的python简单实现

  参考文章:遗传算法详解 附python代码实现_重学CS的博客-CSDN博客_python遗传算法

 大致内容解释可以看上面这篇文章,本文采用浮点数编码重新实现了一下。

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm

import random

def F(x, y):
    return 3 * (1 - x) ** 2 * np.exp(-(x ** 2) - (y + 1) ** 2) - 10 * (x / 5 - x ** 3 - y ** 5) * np.exp(
        -x ** 2 - y ** 2) - 1 / 3 ** np.exp(-(x + 1) ** 2 - y ** 2)

class solo:
    def __init__(self ,x , y):
        self.gen = [x,y]
        self.lenth = len(self.gen)
        self.fit = self.get_fitness()
    def get_fitness(self):
        return float(F(self.gen[0], self.gen[1]))

class pop:
    def __init__(self, solo_num):
        self.num = solo_num
        self.member = []
        self.pop_inital()
        self.crossrate = 0.4
        self.mutation_rate = 0.1

    def mean_best_fit(self):
        x= []
        for i in range(len(self.member)):
            x.append(self.member[i].fit)
        for i in range(len(self.member)):
            if self.member[i].fit == np.max(x):
                best_solo = self.member[i]
        return np.mean(x),np.max(x),best_solo

    def pop_inital(self):
        for i in range(self.num):
            x = random.uniform(-3,3)
            y = random.uniform(-3,3)
            tmp = solo(x,y)
            self.member.append(tmp)

    def select(self):
        solo1, solo2 = random.choice(self.member), random.choice(self.member)
        return solo1, solo2

    def cross_mutation(self):
        new_pop = []
        for i in range(self.num):
            solo1, solo2 = self.select()
            for j in range(solo1.lenth):
                rate = random.random()
                if rate<self.crossrate:
                    tmp = solo2.gen[j]
                    solo2.gen[j] = solo1.gen[j]
                    solo1.gen[j] = tmp
            solo1.fit = solo1.get_fitness()
            solo2.fit = solo2.get_fitness()
            better_one = solo1 if solo1.fit>solo2.fit else solo2
            #变异
            for j in range(better_one.lenth):
                rate = random.random()
                if rate<self.mutation_rate:
                    better_one.gen[j] = random.uniform(-3,3)
            better_one.fit = better_one.get_fitness()
            new_pop.append(better_one)
        self.member = new_pop

#训练
def train(epoch):
    mean = []
    best = []
    solo_list = []
    #初始化种群
    population = pop(100)
    x1, x2 ,solo= population.mean_best_fit()
    mean.append(x1)
    best.append(x2)
    solo_list.append(solo)
    for i in range(epoch):
        population.progress_cross_mutation()
        #population.cross_mutation()
        x1, x2 ,solo= population.mean_best_fit()
        mean.append(x1)
        best.append(x2)
        solo_list.append(solo)
    x= []
    for i in range(len(solo_list)):
        x.append(solo_list[i].fit)
    for i in range(len(solo_list)):
        if solo_list[i].fit == np.max(x):
            print(str(solo_list[i].gen[0])+"...."+str(solo_list[i].gen[1])+"..."+str(solo_list[i].fit))

    #fig = plt.figure()
    plt.subplot(1, 2, 1)
    plt.plot(mean)
    plt.xlabel('mean')  # 给 x 轴添加坐标轴信息
    plt.ylabel('fitness')  # 给 y 轴添加坐标轴信息

    plt.subplot(1, 2, 2)  # 图一包含1行2列子图,当前画在第一行第一列图上
    plt.plot(best)
    plt.xlabel('best')  # 给 x 轴添加坐标轴信息
    plt.ylabel('fitness')  # 给 y 轴添加坐标轴信息
    plt.show()

train(1000)

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
扎眼的阳光的头像扎眼的阳光普通用户
上一篇 2022年5月19日 上午11:16
下一篇 2022年5月19日

相关推荐