遗传算法

通过编码、设置种群、设置适应度函数、遗传操作、解码产生需要的解。f(x)=x*sin(x)+1,x[0,2],求f(x)的最大值、最小值。

定义函数 (即 适应度函数)

1
2
3
4
import math
import numpy as np
import matplotlib.pyplot as plt
import random
1
2
def f(x):
    return x * np.sin(x) + 1 

绘制函数图像

1
2
3
4
plt.rc_context({'axes.edgecolor':'orange', 'xtick.color':'green', 'ytick.color':'green', 'figure.facecolor':'white'})
x = np.arange(0,2,0.1)
plt.plot(x,f(x))
plt.show()

png
png

随机产生种群

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
def product_origin(population_size, length):
    """
    :population_size: 种群大小,
    :length: DNA长度
    """
    population = np.ones((population_size, length))
    #二维列表,包含染色体和基因
    for i in range(population_size):
        temporary=[]
        #染色体暂存器
        for j in range(length):
            population[i][j]= random.randint(0,1)
            #随机产生一个染色体,由二进制数组成
            #将染色体添加到种群中
    return population
            # 将种群返回,种群是个二维数组,个体和染色体两维

二进制转十进制

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
"""
def translation(num):
    return int(str(num),2)
"""
def translation(population,chromosome_length):
    temporary=[]
    for i in range(len(population)):
        total=0
        for j in range(chromosome_length):
            total+=population[i][j]*(math.pow(2,j-4))
        temporary.append(total)
    return temporary

选择

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
def cumsum(fitness1):
    for i in range(len(fitness1)-2,-1,-1):
    # range(start,stop,[step])
    # 倒计数
        total=0
        j=0
        while(j<=i):
            total+=fitness1[j]
            j+=1
        fitness1[i]=total
        fitness1[len(fitness1)-1]=1
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
def selection(population,fitness):
        new_fitness=[]
        total = np.sum(fitness)
        for i in range(len(fitness)):
            new_fitness.append(fitness[i]/ total )
        cumsum(new_fitness)
        ms=[]
    #存活的种群
        population_length=pop_len=len(population)
    #求出种群长度
    #根据随机数确定哪几个能存活
        for i in range(pop_len):
            ms.append(random.random())
    # 产生种群个数的随机值
    # ms.sort()
    # 存活的种群排序
        fitin=0
        newin=0
        new_population=new_pop=population
     #轮盘赌方式
        while newin<pop_len:
            if(ms[newin]<new_fitness[fitin]):
                    new_pop[newin]=population[fitin]
                    newin+=1
            else:
                 fitin+=1
        population=new_pop
    

交叉

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
def crossover(population, pc):
#pc是概率阈值,选择单点交叉还是多点交叉,生成新的交叉个体,这里没用
    pop_len=len(population)
    for i in range(pop_len-1):
        if(random.random()< pc):
            cpoint=random.randint(0,len(population[0]))
           #在种群个数内随机生成单点交叉点
            temporary1=[]
            temporary2=[]
            temporary1.extend(population[i][0:cpoint])
            temporary1.extend(population[i+1][cpoint:len(population[i])])
           #将tmporary1作为暂存器,暂时存放第i个染色体中的前0到cpoint个基因,
           #然后再把第i+1个染色体中的后cpoint到第i个染色体中的基因个数,补充到temporary2后面
            temporary2.extend(population[i+1][0:cpoint])
            temporary2.extend(population[i][cpoint:len(population[i])])
        # 将tmporary2作为暂存器,暂时存放第i+1个染色体中的前0到cpoint个基因,
        # 然后再把第i个染色体中的后cpoint到第i个染色体中的基因个数,补充到temporary2后面
            population[i]=temporary1
            population[i+1]=temporary2
        # 第i个染色体和第i+1个染色体基因重组/交叉完成

变异

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
def mutation(population, pm):
     # pm是概率阈值
    px=len(population)
    # 求出种群中所有种群/个体的个数
    py=len(population[0])
    # 染色体/个体基因的个数
    for i in range(px):
        if(random.random()<pm):
            mpoint=random.randint(0,py-1)
            #
            if(population[i][mpoint]==1):
               #将mpoint个基因进行单点随机变异,变为0或者1
                population[i][mpoint]=0
            else:
                population[i][mpoint]=1
 

挑选最好

1
2
3
def best(population, x_10, fitness):
    maxidx = np.argmax(fitness)
    return x_10[maxidx], fitness[maxidx]

绘图

1
2
3
def plot(results, iteration):
    plt.plot(np.arange(1,iteration+1), [i[1] for i in results])
    plt.show()

遗传算法

1
2
3
4
5
population_size = 100  #种群大小
length = 5 # DNA长度
iteration = 200 # 迭代次数
pm = 0.01 # 变异概率
pc = 0.6
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16

# 1 . 初始化种群
population = product_origin(population_size, length)
results = []
for i in range(iteration):
    x_10 = translation(population, length)
    fitness = f(x_10)
    best_individual, best_fitness = best(population,x_10, fitness)
    results.append([best_fitness, best_individual])
    selection(population, fitness)
    crossover(population, pc)
    mutation(population,pm)

results.sort()

plot(results,iteration)

png
png

1

1