GA包自定义Mutation与Crossover算子报错问题求助
错误原因及解决方法
错误原因分析
1. 突变算子报错:Error in x[idx] <- 1 - idx : object of type 'S4' is not subsettable
GA包调用自定义突变算子时,传入的是GA对象(S4类型)和个体索引两个参数,而非直接的个体向量。你定义的mutation函数仅接受单个参数x,导致第一个传入的S4对象被当作x,尝试对S4对象做子集操作时触发错误。
2. 交叉算子报错:Error in parent1 * mask : non-numeric argument to binary operator
自定义交叉算子的参数签名错误,GA包调用时传入的是GA对象和父代索引向量,而非直接的两个父代个体。你定义的crossover函数期望接收parent1和parent2两个数值向量,但实际传入的是S4对象和索引,导致无法执行数值运算。
修正后的完整代码
library(GA) # 定义问题参数 set.seed(123) assets <- c("Asset 1", "Asset 2", "Asset 3", "Asset 4", "Asset 5", "Asset 6", "Asset 7", "Asset 8", "Asset 9", "Asset 10") criteria <- c(0.5, 0.3, 0.2) # 目标选择比例 # 解的二进制表示 n <- length(assets) bin_rep <- function(...) rbinom(n, 1, 0.5) # 适应度函数(修复空选择除以0的问题) fitness <- function(x) { selected_assets <- assets[x == 1] if(length(selected_assets) == 0) return(-Inf) # 空选择直接返回最差适应度 ratio1 <- sum(selected_assets == "Asset 1")/length(selected_assets) ratio2 <- sum(selected_assets == "Asset 2")/length(selected_assets) ratio3 <- sum(selected_assets == "Asset 3")/length(selected_assets) return(-abs(ratio1 - criteria[1]) - abs(ratio2 - criteria[2]) - abs(ratio3 - criteria[3])) } # 修正突变算子:适配GA包的参数传入逻辑 mutation <- function(object, ind) { x <- object@population[ind,] # 从GA对象中提取对应个体 idx <- sample(1:n, 1) x[idx] <- 1 - x[idx] return(x) } # 修正交叉算子:适配GA包的参数传入逻辑 crossover <- function(object, parents) { parent1 <- object@population[parents[1],] # 提取第一个父代 parent2 <- object@population[parents[2],] # 提取第二个父代 mask <- rbinom(n, 1, 0.5) child1 <- parent1 * mask + parent2 * (1 - mask) child2 <- parent2 * mask + parent1 * (1 - mask) return(list(child1, child2)) } # 运行遗传算法 ga_result <- ga(type = "binary", fitness = fitness, nBits = n, lower = rep(0, n), upper = rep(1, n), mutation = mutation, crossover = crossover) # 输出结果 selected_assets <- assets[ga_result@solution == 1] selected_fitness <- fitness(ga_result@solution) print("选中的资产:") print(selected_assets) print("对应的适应度值:") print(selected_fitness)
额外优化说明
- 修复了适应度函数中空选择导致除以0的问题,当没有选中任何资产时返回
-Inf,避免程序报错。 - 突变/交叉算子通过
object@population从GA对象中提取对应个体,完全适配GA包的调用逻辑。
内容的提问来源于stack exchange,提问作者Someshwar
相关产品推荐
相关产品推荐

