遗传算法之:排序

遗传算法之 : 排序

用遗传算法来对数组进行排序,这个效率很低,要迭代很多次,而且不稳定,所以这里只对长度为10的数组进行了排序,并尝试了几种随机突变操作.

import random
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline
1. 初始化随机无序序列
def generate_initial_seq(length, geneSet):
    #random.seed(2021)
    geneSeq = random.sample(geneSet, length)
    return geneSeq
geneSet = list(range(100))
# parent gene
initialSeq = generate_initial_seq(10, geneSet)
# targe seq
target = sorted(initialSeq)

初始化无序数组(Initial Seq 和 Targe Seq)
在这里插入图片描述

2.计算适应度

这里的适应度用相邻两个元素,是否有序的个数来表示,即:∑i=0N(xi<xi+1)\sum_{i = 0}^N (x_i < x_{i+1})i=0N(xi<xi+1)

def get_fitness(geneSeq):
    fitness = np.sum([geneSeq[i] > geneSeq[i-1] for i in range(1, len(geneSeq))])
    fitness = fitness+1
    return fitness
get_fitness([81, 53, 91, 61, 54, 55, 74, 50, 31, 24])
4
3.突变
  1. 生成两个随机索引,调换两个位置元素(不相邻位置交换)
  2. 生成一个随机索引,调换索引前面元素(相邻位置交换)
  3. 生成一个随机索引,调换索引前后元素(间隔一个元素交换)
  4. 生成两个随机索引,调换索引前面元素(相邻位置交换)[1.的变种]
  5. 生成两个随机索引,调换索引前后元素(间隔一个元素交换)[1.的变种]
def mutate_v1(geneSeq):
    indices = random.sample(list(range(len(geneSeq))), 2)
    childSeq = geneSeq.copy()
    childSeq[indices[0]] = geneSeq[indices[1]]
    childSeq[indices[1]] = geneSeq[indices[0]]
    return childSeq

def mutate_v2(geneSeq):
    index = random.sample(list(range(1,len(geneSeq))), 1)[0]
    childSeq = geneSeq.copy()
    childSeq[index-1] = geneSeq[index]
    childSeq[index] = geneSeq[index-1]
    return childSeq

def mutate_v3(geneSeq):
    index = random.sample(list(range(1,len(geneSeq)-1)), 1)[0]
    childSeq = geneSeq.copy()
    childSeq[index-1] = geneSeq[index+1]
    childSeq[index+1] = geneSeq[index-1]
    return childSeq
4. 进化
def evolution(length, initialSeq, mutate_func):
    seq_list = []
    fit_list = []
    #initialSeq = generate_initial_seq(length, geneSet)
    initialFitness = get_fitness(initialSeq)
    targetSeq = sorted(initialSeq)
    targetFitness = get_fitness(targetSeq)
    seq_list.append(initialSeq)
    fit_list.append(initialFitness)
    print('First Generation Fitness is : %d'%initialFitness)
    generation_count = 1
    bestFitness = initialFitness
    bestSeq = initialSeq
    if initialFitness == targetFitness:
        return initialSeq
    while True:
    #for i in range(2000):
        childSeq = mutate_func(bestSeq)
        childFitness = get_fitness(childSeq)
        seq_list.append(childSeq)
        fit_list.append(childFitness)
        if bestFitness > childFitness:
            continue
        generation_count += 1
        if (generation_count%200 ==0):
            print("%d's Generation fitness : %d"%(generation_count,childFitness))
        if (childFitness == targetFitness) or (generation_count >=1400):
            break
        # update
        bestSeq = childSeq
        bestFitness = childFitness
    return seq_list, fit_list
# 初始化无序数组
initialSeq = generate_initial_seq(10, geneSet)
initialSeq
[88, 54, 80, 48, 40, 93, 58, 84, 75, 20]
# 第一种随机突变
seqs_1, fitness_1 = evolution(10, initialSeq, mutate_v1)
First Generation Fitness is : 4
200's Generation fitness : 9
400's Generation fitness : 9
600's Generation fitness : 9
800's Generation fitness : 9
# 第三种随机突变
seqs_3, fitness_3 = evolution(10, initialSeq, mutate_v3)
First Generation Fitness is : 4
200's Generation fitness : 7
400's Generation fitness : 7
600's Generation fitness : 7
800's Generation fitness : 7
1000's Generation fitness : 7
1200's Generation fitness : 7
1400's Generation fitness : 7
#seqs_4, fitness_4 = evolution(10, geneSet, mutate_v4)
#seqs_5, fitness_5 = evolution(10, geneSet, mutate_v5)

遗传若干代后的效果对比
在这里插入图片描述

结果证明随机交换两个位置元素,最终收敛了,其他2,3,4,5都不行,遗传多代还是会陷入僵局.

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值