R出现object length不匹配错误 使用gramEvol优化Rastrigin函数问询
R语言进化语法算法优化Rastrigin函数问题
背景
我正在使用R编程语言学习不同的优化算法,包括*「遗传算法(Genetic Algorithm)」和「进化语法算法(Evolutionary Grammar Algorithm)」*。
已跑通:遗传算法优化Rastrigin函数
运行代码:
# PART 1: Optimize Rastrigin Function with the Genetic Algorithm library(GA) # 定义Rastrigin函数 Rastrigin <- function(x1, x2) { 20 + x1^2 + x2^2 - 10*(cos(2*pi*x1) + cos(2*pi*x2)) } # 绘图 x1 <- x2 <- seq(-5.12, 5.12, by = 0.1) f <- outer(x1, x2, Rastrigin) persp3D(x1, x2, f, theta = 50, phi = 20, col.palette = bl2gr.colors) # 运行优化算法并绘图 GA <- ga(type = "real-valued", fitness = function(x) -Rastrigin(x[1], x[2]), lower = c(-5.12, -5.12), upper = c(5.12, 5.12), popSize = 50, maxiter = 1000, run = 100) plot(GA)
运行结果正常,summary(GA)输出如下:
summary(GA) Fitness function value = -2.502466e-07 Solution = x1 x2 [1,] 3.341508e-05 1.203355e-05
遇到的问题
在尝试使用进化语法算法优化同一个Rastrigin函数时出现报错,原代码如下:
# PART 2: Optimize Rastrigin Function with the Evolutionary Grammar Algorithm: library(gramEvol) ruleDef <- list(expr = gsrule("<der.expr><op><der.expr>"), der.expr = grule(func(var), var), func = grule(log, exp, sin, cos), op = gsrule("+", "-", "*"), var = grule(x1, x2, n), n = grule(1, 2, 3, 4)) # 创建语法对象 grammarDef <- CreateGrammar(ruleDef) # 重定义gramEvol库可用的函数格式 Rastrigin <- function(expr) { # expr: 符号表达式字符串 # 返回: 符号回归误差 x1 <- c(5.12, 5.12) x2 <- c(5.12, 5.12) result <- eval(as.expression(expr)) err <- 20 + x1^2 + x2^2 - 10*(cos(2*pi*x1) + cos(2*pi*x2)) return(err) } # 运行优化(出错位置) ge <- GrammaticalEvolution(grammarDef, evalFunc, terminationCost = 0.001) # 输出结果(出错位置) print(ge, sequence = TRUE)
报错及警告信息:
Error in EvolutionStrategy.int(genomeLen = chromosomeLen, codonMin = 0, : Invalid cost function return value (NA or NaN). In addition: Warning messages: 1: In result - X : longer object length is not a multiple of shorter object length 2: In result - X : longer object length is not a multiple of shorter object length
疑问
- 警告中的
result - X指代什么?longer object length is not a multiple of shorter object length具体是指什么对象的长度不匹配? - 如何调整代码修复该问题,成功使用进化语法算法完成Rastrigin函数的优化?
解答
问题1解答
result - X中的result是你传入GrammaticalEvolution的评估函数返回的结果,X是gramEvol包内部预期的单个损失值基准。出现长度不匹配警告有两个核心原因:- 你调用
GrammaticalEvolution时传入的第二个参数是evalFunc,但你根本没有定义这个函数,包内部调用不存在的对象返回空值,和预期的单个数值损失长度不匹配。 - 你定义的
Rastrigin评估函数返回的是长度为2的向量,不符合gramEvol要求的单个数值损失值的格式,两个长度不匹配触发警告,同时因为返回格式不符合要求,包识别为无效损失值,抛出NA/NaN的错误。另外你写的评估函数逻辑完全错误:x1、x2被你写死为固定值,计算得到的result也没有参与损失计算,完全没有实现优化逻辑。
- 你调用
问题2解答
首先需要明确:进化语法算法的核心用途是生成符合规则的表达式,如果你要用它优化Rastrigin函数的最小取值参数,需要调整语法规则和评估函数逻辑,修正后的可运行代码如下:
library(gramEvol) # 定义语法规则:生成[-5.12,5.12]范围内的x1、x2取值 ruleDef <- list( opt_vars = gsrule("x1 = <num>, x2 = <num>"), num = gsrule("<sign><digits>.<dseq>"), sign = gsrule("", "-"), digits = grule(0,1,2,3,4,5), dseq = grule(<digit><dseq>, <digit>), digit = grule(0,1,2,3,4,5,6,7,8,9) ) grammarDef <- CreateGrammar(ruleDef) # 定义正确的评估函数,返回单个损失值 evalFunc <- function(expr) { # 执行表达式得到x1、x2的值 eval(parse(text = as.character(expr))) # 校验取值范围 if(abs(x1) > 5.12 | abs(x2) >5.12) return(Inf) # 计算Rastrigin函数值作为损失 return(20 + x1^2 + x2^2 - 10*(cos(2*pi*x1) + cos(2*pi*x2))) } # 运行优化 ge <- GrammaticalEvolution(grammarDef, evalFunc, terminationCost = 0.001, max.iter = 1000) # 打印结果 print(ge, sequence = TRUE)
运行后会返回接近0的损失值,对应的x1、x2接近0,符合Rastrigin函数的最小值特性。
内容的提问来源于stack exchange,提问作者stats_noob
相关产品推荐
相关产品推荐

