遗传算法(模型)

一.遗传算法

遗传算法:通过模拟自然进化过程搜索最优解的方法
遗传算法执行过程: 把要解决的问题想象成一个种群,种群由经过基因编码的个体组成,根据问题域中个体的适应度大小选择个体进行组合交叉变异,产生出代表新的解集的种群,末代种群中的最优个体经过解码,可以作为问题近似最优解

遗传算法过程图解:
请添加图片描述

遗传算法的一般步骤:
1.随机产生种群。
2.根据策略判断个体的适应度,是否符合优化准则,若符合,输出最佳个体及其最优解,结束。否则,进行下一步。
3.依据适应度选择父母,适应度高的个体被选中的概率高,适应度低的个体被淘汰。
4.用父母的染色体按照一定的方法进行交叉,生成子代。
5.对子代染色体进行变异。
6.由交叉和变异产生新一代种群,返回步骤2,直到最优解产生。

遗传算法并不保证你能获得问题的最优解,但是使用遗传算法的最大优点在于你不必去了解和操心如何去“找”最优解。而只要简单的“否定”一些表现不好的个体就行了。

二.遗传算法的实现

1.三种编码

编码是应用遗传算法时要解决的首要问题,也是设计遗传算法时的一个关键步骤。编码方法影响到交叉算子、变异算子等遗传算子的运算方法,大很大程度上决定了遗传进化的效率。
迄今为止人们已经提出了许多种不同的编码方法。总的来说,这些编码方法可以分为三大类:二进制编码法、浮点编码法、符号编码法。

1.1二进制编码法

由二进制符号0和1所组成的二值符号集
优点:

  • 编码、解码操作简单易行
  • 交叉、变异等遗传操作便于实现
  • 合最小字符集编码原则
  • 利用模式定理对算法进行理论分析

缺点:
对于一些连续函数的优化问题,由于其随机性使得其局部搜索能力较差对于一些连续函数的优化问题,由于其随机性使得其局部搜索能力较差。存在着连续函数离散化时的映射误差。个体长度较时,可能达不到精度要求,而个体编码长度较长时,虽然能提高精度,但增加了解码的难度,使遗传算法的搜索空间急剧扩大。

1.2浮点编码法

个体的每个基因值用某一范围内的一个浮点数来表示。在浮点数编码方法中,必须保证基因值在给定的区间限制范围内,遗传算法中所使用的交叉、变异等遗传算子也必须保证其运算结果所产生的新个体的基因值也在这个区间限制范围内。
优点:

  • 适用于在遗传算法中表示范围较大的数
  • 适用于精度要求较高的遗传算法
  • 便于较大空间的遗传搜索
  • 改善了遗传算法的计算复杂性,提高了运算交率
  • 便于遗传算法与经典优化方法的混合使用
  • 便于设计针对问题的专门知识的知识型遗传算子
  • 便于处理复杂的决策变量约束条件

1.3符号编码法

符号编码法是指个体染色体编码串中的基因值取自一个无数值含义、而只有代码含义的符号集。
优点:

  • 符合有意义积术块编码原则
  • 便于在遗传算法中利用所求解问题的专门知识
  • 便于遗传算法与相关近似算法之间的混合使用。

2.评价个体的适应度–适应度函数

适应度函数也称评价函数,是根据目标函数确定的用于区分群体中个体好坏的标准。

评价个体适应度的一般过程为:

  • 对个体编码串进行解码处理后,可得到个体的表现型。

  • 由个体的表现型可计算出对应个体的目标函数值。

  • 根据最优化问题的类型,由目标函数值按一定的转换规则求出个体的适应度。

3.选择函数

下面介绍几种常用的选择算子:

  1. 轮盘赌选择(Roulette Wheel Selection):是一种回放式随机采样方法。每个个体进入下一代的概率等于它的适应度值与整个种群中个体适应度值和的比例。选择误差较大。

  2. 随机竞争选择(Stochastic Tournament):每次按轮盘赌选择一对个体,然后让这两个个体进行竞争,适应度高的被选中,如此反复,直到选满为止。

  3. 最佳保留选择:首先按轮盘赌选择方法执行遗传算法的选择操作,然后将当前群体中适应度最高的个体结构完整地复制到下一代群体中。

  4. 无回放随机选择(也叫期望值选择Excepted Value Selection):根据每个个体在下一代群体中的生存期望来进行随机选择运算。方法如下:

    (1) 计算群体中每个个体在下一代群体中的生存期望数目N。

    (2) 若某一个体被选中参与交叉运算,则它在下一代中的生存期望数目减去0.5,若某一个体未 被选中参与交叉运算,则它在下一代中的生存期望数目减去1.0。

    (3) 随着选择过程的进行,若某一个体的生存期望数目小于0时,则该个体就不再有机会被选中。

  5. 确定式选择:按照一种确定的方式来进行选择操作。具体操作过程如下:

    (1) 计算群体中各个个体在下一代群体中的期望生存数目N。

    (2) 用N的整数部分确定各个对应个体在下一代群体中的生存数目。

    (3) 用N的小数部分对个体进行降序排列,顺序取前M个个体加入到下一代群体中。至此可完全确定出下一代群体中M个个体。

  6. 无回放余数随机选择:可确保适应度比平均适应度大的一些个体能够被遗传到下一代群体中,因而选择误差比较小。

  7. 均匀排序:对群体中的所有个体按期适应度大小进行排序,基于这个排序来分配各个个体被选中的概率。

  8. 最佳保存策略:当前群体中适应度最高的个体不参与交叉运算和变异运算,而是用它来代替掉本代群体中经过交叉、变异等操作后所产生的适应度最低的个体。

  9. 随机联赛选择:每次选取几个个体中适应度最高的一个个体遗传到下一代群体中。

  10. 排挤选择:新生成的子代将代替或排挤相似的旧父代个体,提高群体的多样性。

4.遗传–染色体交叉

适用于二进制编码个体或浮点数编码个体的交叉算子:

  1. 单点交叉:指在个体编码串中只随机设置一个交叉点,然后再该点相互交换两个配对个体的部分染色体。
    两点交叉与多点交叉:

    (1) 两点交叉:在个体编码串中随机设置了两个交叉点,然后再进行部分基因交换。

    (2) 多点交叉:在个体编码串中随机设置了多个交叉点,然后再进行部分基因交换。

  2. 均匀交叉(也称一致交叉):两个配对个体的每个基因座上的基因都以相同的交叉概率进行交换,从而形成两个新个体。

  3. 算术交叉:由两个个体的线性组合而产生出两个新的个体。该操作对象一般是由浮点数编码表示的个体。

5.变异–基因突变

以下变异算子适用于二进制编码和浮点数编码的个体:

  1. 基本位变异:对个体编码串中以变异概率、随机指定的某一位或某几位仅因座上的值做变异运算。

  2. 均匀变异:分别用符合某一范围内均匀分布的随机数,以某一较小的概率来替换个体编码串中各个基因座上的原有基因值。(特别适用于在算法的初级运行阶段)

  3. 边界变异:随机的取基因座上的两个对应边界基因值之一去替代原有基因值。特别适用于最优点位于或接近于可行解的边界时的一类问题。

  4. 非均匀变异:对原有的基因值做一随机扰动,以扰动后的结果作为变异后的新基因值。对每个基因座都以相同的概率进行变异运算之后,相当于整个解向量在解空间中作了一次轻微的变动。

  5. 高斯近似变异:进行变异操作时用符号均值为P的平均值,方差为P**2的正态分布的一个随机数来替换原有的基因值。

三.建模之遗传算法

例子:采用遗传算法解决负载均衡调度问题:
假设有N个任务,需要负载均衡器分配给M个服务器节点去处理。每个任务的任务长度、每台服务器节点(下面简称“节点”)的处理速度已知,请给出一种任务分配方式,使得所有任务的总处理时间最短。


任务长度矩阵(简称:任务矩阵)
我们将所有任务的任务长度用矩阵tasks表示,如:Tasks={2,4,6,8}
那么,tasks[i]中的i表示任务的编号,而tasks[i]表示任务i的任务长度。

节点处理速度矩阵(简称:节点矩阵)
我们将所有服务器节点的处理速度用矩阵nodes表示,如:Nodes={2,1}
那么,nodes[j]中的j表示节点的编号,而nodes[j]表示节点j的处理速度。

任务处理时间矩阵
当 任务矩阵Tasks和节点矩阵Nodes确定下来之后,那么所有任务分配给所有节点的任务处理时间都可以确定了,我们用矩阵timeMatrix表示,它是一个二维数组。

timeMatrix[i][j]表示将任务i分配给节点j处理所需的时间,它通过如下公式计算:
timeMatrix[i][j] = tasks[i]/nodes[j]

染色体
一条染色体的构成如下:
chromosome={1,2,3,4}
一条染色体就是一个一位数组,一位数组的下标表示任务的编号,数组的值表示节点的编号。那么chromosome[i]=j的含义就是:将任务i分配给了节点j。
上面的例子中,任务集合为Tasks={2,4,6,8},节点集合为Nodes={2,1},那么染色体chromosome={3,2,1,0}的含义是:

  • 将任务0分配给3号节点
  • 将任务1分配给2号节点
  • 将任务2分配给1号节点
  • 将任务3分配给0号节点

适应度矩阵
在遗传算法中扮演者“上帝”角色的是适应度函数,它会评判每一条染色体的适应度,并保留适应度高的染色体、淘汰适应度差的染色体。那么在算法实现时,我们需要一个适应度矩阵,记录当前N条染色体的适应度,如下所示:
adaptability={0.6, 2, 3.2, 1.8}
adaptability数组的下标表示染色体的编号,而adaptability[i]则表示编号为i的染色体的适应度。
在负载均衡调度这个实例中,我们将N个任务执行总时长作为适应度评判的标准。当所有任务分配完后,如果总时长较长,那么适应度就越差;而总时长越短,则适应度越高。

选择概率矩阵
每次进化过程中,都需要根据适应度矩阵计算每一条染色体在下一次进化中被选择的概率,这个矩阵如下所示:
selectionProbability={0.1, 0.4, 0.2, 0.3}
矩阵的下标表示染色体的编号,而矩阵中的值表示该染色体对应的选择概率。其计算公式如下:
selectionProbability[i] = adaptability[i] / 适应度之和

遗传算法的实现

/**
 * 遗传算法
 * @param iteratorNum 迭代次数
 * @param chromosomeNum 染色体数量
 */
function gaSearch(iteratorNum, chromosomeNum) {
    // 初始化第一代染色体
    var chromosomeMatrix = createGeneration();

    // 迭代繁衍
    for (var itIndex=1; itIndex<iteratorNum; itIndex++) {
        // 计算上一代各条染色体的适应度
        calAdaptability(chromosomeMatrix);

        // 计算自然选择概率
        calSelectionProbability(adaptability);

        // 生成新一代染色体
        chromosomeMatrix = createGeneration(chromosomeMatrix);

    }
}

四.参考链接

超详细的遗传算法(Genetic Algorithm)解析
10分钟搞懂遗传算法(含源码)

  • 0
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
遗传算法是一种基于进化论原理的优化算法,常用于解决复杂的优化问题。在Python中,可以使用遗传算法来构建模型。以下是一个简单的遗传算法模型的示例: ```python import random # 定义目标函数(需要优化的函数) def fitness_function(solution): # 这里是一个示例,可以根据具体问题自定义目标函数 return sum(solution) # 生成初始种群 def generate_initial_population(population_size, chromosome_length): population = [] for _ in range(population_size): chromosome = [random.randint(0, 1) for _ in range(chromosome_length)] population.append(chromosome) return population # 选择操作(使用轮盘赌选择方法) def selection(population, num_parents): fitness_values = [fitness_function(solution) for solution in population] parents = [] for _ in range(num_parents): cumulative_prob = 0 rand_val = random.uniform(0, sum(fitness_values)) for i, fitness in enumerate(fitness_values): cumulative_prob += fitness if cumulative_prob >= rand_val: parents.append(population[i]) break return parents # 交叉操作(单点交叉) def crossover(parents, offspring_size): offspring = [] for _ in range(offspring_size): parent1, parent2 = random.sample(parents, 2) crossover_point = random.randint(1, len(parent1)-1) offspring.append(parent1[:crossover_point] + parent2[crossover_point:]) return offspring # 变异操作(位反转变异) def mutation(offspring): mutated_offspring = [] for offspring in offspring: for i in range(len(offspring)): if random.random() < mutation_rate: offspring[i] = 1 - offspring[i] mutated_offspring.append(offspring) return mutated_offspring # 主要算法逻辑 population_size = 100 chromosome_length = 10 num_generations = 50 num_parents = 50 offspring_size = population_size - num_parents mutation_rate = 0.01 population = generate_initial_population(population_size, chromosome_length) for generation in range(num_generations): parents = selection(population, num_parents) offspring = crossover(parents, offspring_size) mutated_offspring = mutation(offspring) population = parents + mutated_offspring # 打印最优解 best_solution = max(population, key=lambda x: fitness_function(x)) print("Best solution:", best_solution) print("Fitness value:", fitness_function(best_solution)) ``` 这是一个基本的遗传算法模型,你可以根据实际需求进行修改和扩展。注意,在实际应用中,你需要自定义适应度函数、选择、交叉和变异等操作,以适应具体问题的优化需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值