遗传算法是一类常见的随机化搜索方法,目前被广泛应用于组合优化,机器学习,信号处理,人工智能等领域。
这里以模型参数优化为背景学习遗传算法的r语言实现
r语言中常用的实现遗传算法的包有mcga包、genalg包、rgenoud包。
其中mcga、genalg包比较简单,上手较快。rgenoud包将遗传算法和衍生的牛顿算法结合起来,可以求解复杂函数的优化问题。
这里主要学习mcga包,genalg包的用法
mcga包使用字节表示变量,而不是实值,并且基于这些用字节表示的染色体进行经典的交叉操作。即从染色体中随机选取一个字节值,并以1/2的概率通过+1或-1进行变异。。它的特点是快速,并可以处理大范围的高精度空间搜索。
mcga包主要包含两个函数:mcga、multi_mcga,其中mcga适用于单目标函数最小化问题,multi_mcga可以使用mcga的逻辑实现多目标的优化。
mcga函数定义及参数说明如下:
mcga (popsize, chsize, crossprob = 1, mutateprob = 0.01,
elitism = 1, minval, maxval, maxiter = 10, evalFunc)
这里使用mcga函数对 “求解fx=x*sinx , x∈[0,12.55]在给定区间的最大值” 的问题进行求解。
#定义适应度函数
> getAdjust <- function(x)
+ {
+ if(x>=0 && x<=12.55)
+ {
+ return(-(x*sin(x))) #由于评估函数是针对最小化问题的,因此要求最大值此处需加个负号
+ }
+ else
+ {
+ return(exp(100))
+ }
+ }
> library(mcga)
> m<-mcga(popsize = 20, chsize = 1, minval = 0, maxval = 12.55 , maxiter = 1000,
+ evalFunc = getAdjust)
> str(m)
List of 10
$ population: num [1:20, 1] 7.95 7.95 7.95 7.95 7.95 ...
$ costs : num [1:20] -7.91 -7.91 -7.91 -7.91 -7.91 ...
$ popsize : num 20
$ chsize : num 1
$ crossprob : num 1
$ mutateprob: num 0.01
$ elitism : num 1
$ minval : num 0
$ maxval : num 12.6
$ maxiter : num 1000
从population可知,我们求得的最优解为7.95。
genglg包是基于r语言用于二元和浮点染色体的遗传算法,主要包含 rbga.bin 和 rbga ,其中 rbga.bin 实现了基于二元染色体的遗传算法。
genalg 包中的 rbga 对象,可以调用 plot 函数进行可视化,展现遗传算法运行过程中的特征。
rbga函数的定义及参数说明:
rbga(stringMin = c(), stringMax = c(), suggestions = NULL,
popSize = 200, iters = 100, mutationChance = NA, elitism = NA,
monitorFunc = NULL, evalFunc = NULL, showSettings = FALSE,
verbose = FALSE)
这里使用 rbga 函数对 “求解fx=x*sinx , x∈[0,12.55]在给定区间的最大值” 的问题进行求解。
library(genalg)
#定义适应度函数
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)
## Testing the sanity of parameters...
## Not showing GA settings...
## Starting with random values in the given domains...
## Starting iteration 1
## Calucating evaluation values... ............................................
## ........................................................ done.
## Sending current state to rgba.monitor()...
## [1] 3.441201
## Creating next generation...
## sorting results...
## applying elitism...
## cannot crossover (#vars=1), using new randoms...
## applying mutations... 2 mutations applied
## Starting iteration 2
## Calucating evaluation values... ............................................
## .................................... done.
## Sending current state to rgba.monitor()...
## [1] 7.985875
#省略部分输出结果
#查看rbgaobj对象的结构
str(rbgaObj)
## List of 12
## $ type : chr "floats chromosome"
## $ stringMin : num 0
## $ stringMax : num 12.6
## $ popSize : num 100
## $ iters : num 1000
## $ suggestions : NULL
## $ population : num [1:100, 1] 7.98 7.98 7.98 7.98 7.98 ...
## $ elitism : num 20
## $ mutationChance: num 0.01
## $ evaluations : num [1:100] -7.92 -7.92 -7.92 -7.92 -7.92 ...
## $ best : num [1:1000] -7.9 -7.9 -7.9 -7.9 -7.9 ...
## $ mean : num [1:1000] 0.792 -0.491 -1.757 -2.761 -4.038 ...
## - attr(*, "class")= chr "rbga"
从population可知,求得的最优解为7.98.
对rbgaobj调用plot函数,可看出,随着迭代的次数增加,评估值先是骤降,经过一段不稳定变化后,在1000次附近趋于稳定
#绘制最佳与平均评估值
plot(rbgaObj)
#绘制直方图
plot(rbgaObj,type="hist",breaks=50)
#绘制参数图
plot(rbgaObj,type="vars")