遗传算法(启发式算法)—R实现

遗传算法(Genetic Algorithm,GA)最早是由美国的 John holland于20世纪70年代提出,该算法是根据大自然中生物体进化规律而设计提出的。是模拟达尔文生物进化论的自然选择和遗传学机理的生物进化过程的计算模型,是一种通过模拟自然进化过程搜索最优解的方法。该算法通过数学的方式,利用计算机仿真运算,将问题的求解过程转换成类似生物进化中的染色体基因的交叉、变异等过程。在求解较为复杂的组合优化问题时,相对一些常规的优化算法,通常能够较快地获得较好的优化结果。遗传算法已被人们广泛地应用于组合优化、机器学习、信号处理、自适应控制和人工生命等领域。

一、启发式算法概述

启发式算法一般用于解决NP-hard问题,其中NP是指非确定性多项式。启发式算法是相对于最优化算法提出的,是基于直观或者经验构造的算法,在可接受的开销(时间和空间)内给出待解决优化问题的一个可行解。

1. TSP问题

著名的推销员旅行问题(Travel Saleman Problem or TSP):假设一个推销员需要从南京出发,经过广州,北京,上海,…,等 n 个城市, 最后返回香港。 任意两个城市之间都有飞机直达,但票价不等。假设公司只给报销 C 元钱,问是否存在一个行程安排,使得他能遍历所有城市,而且总的路费小于 C?
推销员旅行问题显然是 NP 的。因为如果你任意给出一个行程安排,可以很容易算出旅行总开销。但是,要想知道一条总路费小于 C 的行程是否存在,在最坏情况下,必须检查所有可能的旅行安排。

2.常用的启发式算法

现代启发式算法的各种具体实现方法是相对独立提出的,相互之间有一定的区别。现代启发式算法主要有:模拟退火算法(SA)、遗传算法(GA)、列表搜索算法(ST)、进化规划(EP)、进化策略(ES)、蚁群算法(ACA)、人工神经网络(ANN)。如果从决策变量编码方案的不同来考虑,可以有固定长度的编码(静态编码)和可变长度的编码(动态编码)两种方案。SA是基于Monte Carlo算法迭代求解的一种全局概率型搜索算法,具有区别于常规算法的搜索机制和特点,它是借鉴了热力学的退火原理建立起来的。GA是借鉴“优胜劣汰”生物进化与遗传思想而提出的一种全局性并行搜索算法。EP和ES不像GA注重父代与子代遗传细节而侧重父代与子代表现行为上的联系(强调物种层的行为变化)。TS是一种具有记忆功能的全局逐步优化算法。ACA是受到人们对自然界中真实的蚁群集体行为研究成果的启发而提出的一种基于种群的模拟进化算法,属于随机搜索算法。

二、遗传算法的思想

遗传算法即模拟自然界中种群优胜劣汰的过程,通过种群不断迭代之后找到最优解。它是从研究问题可能潜在解集的一个种群(Population)开始的,而一个种群则由经过基因(Gene)编码(Coding)的一定数目的个体(Individual)组成、每个个体实际上是染色体(Chromosome)带有特征的实体。染色体作为遗传物质的主要载体,即多个基因的集合,其内部表现(即基因型)是某种基因组合,它决定了个体的形状的外部表现,如黑头发的特征是由染色体中控制这一特征的某种基因组合决定的。因此,在一开始需要实现从表现型到基因型的映射即编码工作。遗传算法采纳了自然进化模型,如选择、交叉、变异、迁移、局域与邻域等。下图表示了基本遗传算法的过程,计算开始时,一定数目N个个体(父个体1、父个体2、父个体3、父个体4……)即种群随机地初始化,并计算每个个体的适应度函数,第一代也即初始代就产生了。如果不满足优化准则,开始产生新一代的计算。为了产生下一代,按照适应度选择个体,父代要求基因重组(交叉)而产生子代。所有的子代接一定概率变异。然后子代的适应度又被重新计算,子代被插入到种群中将父代取而代之,构成新的一代(子个体1、子个体2、子个体3、子个体4……)。这一过程循环执行,直到满足优化准则为止。

三、遗传算法的应用——R实现

r语言中常用的实现遗传算法的包有mcga包、genalg包、rgenoud包,其中mcga、genalg包比较简单,上手较快。genalg包将遗传算法和衍生的牛顿算法结合起来,可以求解复杂函数的优化问题。genalg包是基于r语言用于二元和浮点染色体的遗传算法,主要函数rbga函数实现了基于二元染色体的遗传算法。genalg包中的 rbga 对象,可以调用 plot 函数进行可视化,展现遗传算法运行过程中的特征。

1. rbga函数语句

!!!默认rbga求的是函数最小值,给出该问题最优解。

rbga(stringMin = c(), stringMax = c(), suggestions = NULL, 
    popSize = 200, iters = 100, mutationChance = NA, elitism = NA, 
    monitorFunc = NULL, evalFunc = NULL, showSettings = FALSE, 
    verbose = FALSE)
参数 解释
stringMin 设置每个基因的最小值
stringMax 设置每个基因的最大值
suggestions 建议染色体的可选列表
popSize 个体数量,即染色体数目,默认为200
iters 迭代次数,默认为100
mutationChance 突变机会,默认为1/(size+1),它影响收敛速度和搜索空间的探测,低机率导致更快收敛,高机率增加了搜索空间的跨度。
elitism 精英数量,默认为20%,直接复制到下一代的染色体数目
monitorFunc 监控函数,每产生一代后运行
evalFunc 适应度函数,用于给个体进行评价
showSettings 打印设置,默认为false
verbose 打印算法运行日志,默认为false

2. 应用实例

这里使用rbga函数求\(f(x)=xsinx\),在给定区间\(x\)∈[0,12.55]的最大值。

定义适应度函数

适应度函数也称评价函数,是根据目标函数确定的用于区分群体中个体好坏的标准。适应度函数总是非负的,而目标函数可能有正有负,故需要在目标函数与适应度函数之间进行变换。

getAdjust <- function(x)
{
    if(x>=0 && x<=12.55)
    {
        return(-(x*sin(x)))
    }else{
        return(exp(100))
    }
}
定义监控函数
monitor<-function(rbga0)
{
    #输出种群中第一个个体的值pulation[1,]
    print(rbga0$population[1,])
}
求解函数
rbgaObj<-rbga(stringMin = c(0), stringMax = c(12.55), popSize = 100, 
              iters = 1000, mutationChance = 0.01, monitorFunc = monitor, 
              evalFunc = getAdjust, verbose = TRUE)

3. 计算结果

对rbgaobj调用plot函数,可看出,随着迭代的次数增加,评估值先是骤降,经过一段不稳定变化后,在1000次附近趋于稳定。

................................................................................ done.
Sending current state to rgba.monitor()...
[1] 7.976799
Creating next generation...
  sorting results...
  applying elitism...
  cannot crossover (#vars=1), using new randoms...
  applying mutations... 1 mutations applied
Starting iteration 1000 
Calucating evaluation values... .....................................  ......... done.
Sending current state to rgba.monitor()...
[1] 7.976799
绘制最佳与平均评估值
plot(rbgaObj)

绘制直方图
plot(rbgaObj,type="hist",breaks=50)

绘制参数图
plot(rbgaObj,type="vars")

四、总结

遗传算法被广泛地运用在图像处理、任务分配、信号处理等方面。由于遗传算法的整体搜索策略和优化搜索方法在计算时不依赖于梯度信息或其它辅助知识,而只需要影响搜索方向的目标函数和相应的适应度函数,所以遗传算法提供了一种求解复杂系统问题的通用框架,它不依赖于问题的具体领域,对问题的种类有很强的鲁棒性。函数优化是遗传算法的经典应用领域,也是遗传算法进行性能评价的常用算例,许多人构造出了各种各样复杂形式的测试函数:连续函数和离散函数、凸函数和凹函数、低维函数和高维函数、单峰函数和多峰函数等。对于一些非线性、多模型、多目标的函数优化问题,用其它优化方法较难求解,而遗传算法可以方便的得到较好的结果。车间调度问题是一个典型的NP-Hard问题,遗传算法作为一种经典的智能算法广泛用于车间调度中,很多学者都致力于用遗传算法解决车间调度问题,现今也取得了十分丰硕的成果。从最初的传统车间调度(JSP)问题到柔性作业车间调度问题(FJSP),遗传算法都有优异的表现,在很多算例中都得到了最优或近优解。

原创文献

  1. R语言遗传算法的实现
  2. 遗传算法的基本原理
posted @ 2022-04-29 18:30  郝hai  阅读(2093)  评论(0编辑  收藏  举报