You need to enable JavaScript to run this app. R语言mco库nsga2优化报错:向量化目标函数返回矩阵格式异常
优惠活动
大模型
产品
解决方案
定价
更多

R语言mco库nsga2优化报错:向量化目标函数返回矩阵格式异常

报错原因
  • 核心原因和你的猜测一致:存在变量作用域问题。n5、n6、n7是目标函数funct_set的内部局部变量,仅在目标函数调用时有效,约束函数gn作为独立的外部函数完全无法访问这三个变量。如果全局环境中存在同名变量,会导致gn返回错误的结果,进而引发维度匹配错误。
  • 第二个原因是nsga2默认启用向量化调用,每次会将整个种群(共100个个体,每个个体7个参数,组成7行100列的矩阵)传入目标函数和约束函数,但你的两个函数都是按照单个个体(输入为长度7的向量)编写的,运行时自然会出现维度不匹配的问题,你看到的「期望4行100列但得到7行100列」的报错就是该问题的直接表现。
  • 第三个原因是上下界参数写法错误:rep()函数的语法为rep(待重复值, 重复次数),你写的rep(80,80,80,80, 100,200,300)不符合语法要求,应该直接使用向量传入7个参数对应的上下界。
修复方案
  1. 首先关闭向量化调用,在nsga2的参数中添加vectorized = FALSE,让算法每次仅传入单个个体的参数向量给目标函数和约束函数。
  2. 抽离公共计算逻辑,解决变量作用域问题:将目标函数中分箱、计算指标、统计分箱行数的逻辑抽为公共函数,目标函数和约束函数分别调用该公共函数获取需要的结果,避免跨函数访问局部变量。
  3. 修正约束函数的写法:mco库要求约束返回值中所有值<=0时代表满足约束,不能直接返回逻辑值,需要将计数约束转换为数值型约束。
  4. 修正上下界参数的写法,直接用向量传入7个参数对应的上下限。

修复后的参考代码如下:

# 抽离公共计算逻辑
calc_f_and_counts <- function(x) {
  x1 <- x[1]; x2 <- x[2]; x3 <- x[3] ; x4 <- x[4]; x5 <- x[5]; x6 <- x[6]; x7 <- x[7]
  f <- numeric(4)
  
  train_data <- train_data %>%
    mutate(cat = ifelse(a1 <= x1 & b1 <= x3, "a",
                        ifelse(a1 <= x2 & b1 <= x4, "b", "c")))
  
  a_table = filter(train_data, cat == "a")
  b_table = filter(train_data, cat == "b")
  c_table = filter(train_data, cat == "c")
  
  table_a = mutate(a_table, quant = ifelse(c1 > x[5],1,0 ))
  table_b = mutate(b_table, quant = ifelse(c1 > x[6],1,0 ))
  table_c = mutate(c_table, quant = ifelse(c1 > x[7],1,0 ))
  
  f[1] = mean(table_a$quant)
  f[2] = mean(table_b$quant)
  f[3] = mean(table_c$quant)
  f[4] = mean(c(table_a$quant, table_b$quant, table_c$quant))
  
  n5 = nrow(a_table)
  n6 = nrow(b_table)
  n7 = nrow(c_table)
  
  return(list(f = f, counts = c(n5, n6, n7)))
}

# 改写目标函数
funct_set <- function (x) {
  calc_f_and_counts(x)$f
}

# 改写约束函数
gn <- function(x) {
  counts = calc_f_and_counts(x)$counts
  n5 = counts[1]; n6 = counts[2]; n7 = counts[3]
  g1 <- x[3] - x[1] 
  g2<- x[4] - x[2] 
  g3 <- x[7] - x[6]
  g4 <- x[6] - x[5] 
  # 约束转换:要求n>20对应20 - n <= 0,符合mco的约束规则
  g5 <- 20 - n5
  g6 <- 20 - n6
  g7 <- 20 - n7
  return(c(g1,g2,g3,g4, g5, g6, g7))
}

# 修正后优化调用
optimization <- nsga2(funct_set, idim = 7, odim = 4 , constraints = gn, cdim = 7,
                      generations=150,
                      popsize=100,
                      cprob=0.7,
                      cdist=20,
                      mprob=0.2,
                      mdist=20,
                      vectorized = FALSE,
                      lower.bounds = c(80,80,80,80, 100,200,300),
                      upper.bounds = c(120,120,120,120,200,300,400)
)

内容的提问来源于stack exchange,提问作者stats_noob

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.12 09:36:03