遗传算法(二)——求单变量函数的最值

要想使用遗传算法,首要任务是定义DNA编码。
传统的 GA 中, DNA 我们能用一串二进制来表示, 比如:
DNA1 = [1, 1, 0, 1, 0, 0, 1] DNA2 = [1, 0, 1, 1, 0, 1, 1]
这里,我们仍然使用二进制编码,但是如何与我们的问题对应起来呢?
我们知道二进制很容易转十进制,再区间压缩以下,这样一个DNA和一个解一一映射。
def translateDNA(pop):
    return pop.dot(2 ** np.arange(DNA_SIZE)[::-1]) / float(2**DNA_SIZE-1) * X_BOUND[1]例如,1 0 1 0 1 0 0 1 0 0 => (4+32+128+256)/(1024-1)*(5-0)=3.3
完整代码:
"""
Visualize Genetic Algorithm to find a maximum point in a function.
Visit my tutorial website for more: https://morvanzhou.github.io/tutorials/
"""
import numpy as np
import matplotlib.pyplot as plt
DNA_SIZE = 10            # DNA length
POP_SIZE = 100           # population size
CROSS_RATE = 0.8         # mating probability (DNA crossover)
MUTATION_RATE = 0.003    # mutation probability
N_GENERATIONS = 100
X_BOUND = [0, 5]         # x upper and lower bounds
def F(x): return np.sin(10*x)*x + np.cos(2*x)*x     # to find the maximum of this function
#def F(x):  return -x*(x-2)
# find non-zero fitness for selection
def get_fitness(pred): return pred + 1e-3 - np.min(pred)
# convert binary DNA to decimal and normalize it to a range(0, 5)
# 1 0 1 0 1 0 0 1 0 0 => (4+32+128+256)/(1024-1)*(5-0)=3.3
def translateDNA(pop): return pop.dot(2 ** np.arange(DNA_SIZE)[::-1]) / float(2**DNA_SIZE-1) * (X_BOUND[1]-X_BOUND[0])
def select(pop, fitness):    # nature selection wrt pop‘s fitness
    idx = np.random.choice(np.arange(POP_SIZE), size=POP_SIZE, replace=True,
                           p=fitness/fitness.sum())
    return pop[idx]
def crossover(parent, pop):     # mating process (genes crossover)
    if np.random.rand() < CROSS_RATE:
        i_ = np.random.randint(0, POP_SIZE, size=1)                             # select another individual from pop
        cross_points = np.random.randint(0, 2, size=DNA_SIZE).astype(np.bool)   # choose crossover points
        parent[cross_points] = pop[i_, cross_points]                            # mating and produce one child
    return parent
def mutate(child):
    for point in range(DNA_SIZE):
        if np.random.rand() < MUTATION_RATE:
            child[point] = 1 if child[point] == 0 else 0
    return child
# pop是100*10的随机01矩阵
pop = np.random.randint(2, size=(POP_SIZE, DNA_SIZE))   # initialize the pop DNA
# 绘制原始函数图像
plt.ion()       # something about plotting
x = np.linspace(*X_BOUND, 200)
plt.plot(x, F(x))
for _ in range(N_GENERATIONS):
    F_values = F(translateDNA(pop))    # compute function value by extracting DNA
    # something about plotting
    if ‘sca‘ in globals(): sca.remove()
    sca = plt.scatter(translateDNA(pop), F_values, s=200, lw=0, c=‘red‘, alpha=0.5); plt.pause(0.05)
    # GA part (evolution)
    fitness = get_fitness(F_values)
    print("Generation: ", _)
    print("Most fitted DNA: ", pop[np.argmax(fitness), :])
    print("Most fitted Value: ", translateDNA(pop[np.argmax(fitness), :]))
    pop = select(pop, fitness)
    pop_copy = pop.copy()
    for parent in pop:
        child = crossover(parent, pop_copy)
        child = mutate(child)
        parent[:] = child       # parent is replaced by its child
plt.ioff(); plt.show()参考链接:莫凡PYTHON-遗传算法
相关推荐
  seekerhit    2020-01-29  
   duangduangdada    2018-12-02  
   oXiaoChong    2020-10-26  
   taiyangshenniao    2020-06-11  
   巴壁虎    2020-05-17  
   风吹夏天    2020-05-18  
   rein0    2020-04-21  
   laohyx    2020-01-23  
   ustbfym    2019-12-30  
   ustbfym    2019-11-08  
   lixiaotao    2019-11-03  
   yishujixiaoxiao    2019-11-03  
   tianbwin    2019-09-29  
   风吹夏天    2014-08-12  
   Broadview    2019-06-27  
   littletingting    2019-06-19  
   liuxiaohua    2019-06-20  
   duyifei0    2019-06-20  
   liuxiaohua    2019-06-20  
 