You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R使用ROI求解g40/g60最优解时函数参数校验报错如何解决?

问题描述

你需要求解g40和g60的最优解,满足change=0.01的约束条件,运行代码时报错:
Error in .check_function_for_sanity(F, n) : cannot evaluate function 'F' using 'n' = 2 parameters

代码错误排查
  • 包装函数定义错误:当前wrapper仅接收1个参数,但F_objective指定参数数量n=2(对应g40、g60两个待优化变量),二者不匹配触发报错。
  • 原始基尼系数未定义:FG函数中计算change用到的Gini是原始分布的基尼系数,未提前计算赋值,运行时会出现对象未找到错误。
  • 约束定义逻辑错误:约束中直接调用的sum(L_prime)、change是FG函数内部的临时变量,不能直接作为约束参数传入,需要基于输入的待优化参数动态计算。
  • 全局data被重复修改:FG函数每次运行都会给原始data新增L_prime列,多次调用后列数累加,取第3列计算分位点的逻辑会失效,应避免修改全局data,改用临时变量存储L_prime。
  • 目标函数不明确:当前FG函数返回的是change值,但change已被设为约束条件,你需要明确目标函数需要最小化/最大化的指标。
修正后的代码示例
# 提前计算原始基尼系数(和Gini_prime计算逻辑一致)
Lp0.2_raw = data[which(abs(data$p-0.2)==min(abs(data$p-0.2))), 2]
Lp0.4_raw = data[which(abs(data$p-0.4)==min(abs(data$p-0.4))), 2]
Lp0.6_raw = data[which(abs(data$p-0.6)==min(abs(data$p-0.6))), 2]
Lp0.8_raw = data[which(abs(data$p-0.8)==min(abs(data$p-0.8))), 2]
Gini = 2*(125/288)*(1/5)*(3*(0.2-Lp0.2_raw)+2*(0.4-Lp0.4_raw)+2*(0.6-Lp0.6_raw)+3*(0.8-Lp0.8_raw))

#weights
p40=which(abs(data$p-0.4)==min(abs(data$p-0.4)))                
w40=data[p40,2]
w60=1-w40

#Non-cumulative L
L_non=data$L[1]
for(i in 2:nrow(data))
L_non[i]=data$L[i]-data$L[i-1]

#X
x1=sum(data$p*L_non)/sum(L_non)
x2=sum(data$p[1:p40]*L_non[1:p40])/sum(L_non[1:p40])

# 定义核心计算函数,返回目标值、两个约束值
calc_vals = function(g40, g60) {
  #Gammas and m
  gama=g40*w40+g60*w60
  gama40=g40
  m=gama40-gama

  #theta & delta
  theta=-m/(x2-x1)
  delta=gama+theta*x1

  #L_prime 不修改全局data
  L_prime=(1+delta-theta*data$p)*L_non

  #Gini approximated from the new distribution
  Lp0.2 = L_prime[which(abs(data$p-0.2)==min(abs(data$p-0.2)))]
  Lp0.4 = L_prime[which(abs(data$p-0.4)==min(abs(data$p-0.4)))]
  Lp0.6 = L_prime[which(abs(data$p-0.6)==min(abs(data$p-0.6)))]
  Lp0.8 = L_prime[which(abs(data$p-0.8)==min(abs(data$p-0.8)))]

  Gini_prime=2*(125/288)*(1/5)*(3*(0.2-Lp0.2)+2*(0.4-Lp0.4)+2*(0.6-Lp0.6)+3*(0.8-Lp0.8))

  #change
  change=(Gini_prime/Gini)-1
  # 示例目标:最小化g40和g60的平方和,可替换为自身实际优化目标
  obj = g40^2 + g60^2
  return(list(obj=obj, cons1=sum(L_prime), cons2=change))
}

# 包装函数:适配ROI参数要求,输入长度为2的向量
wrapper_obj <- function(x) {
  vals = calc_vals(x[1], x[2])
  return(vals$obj)
}

# 约束函数1:sum(L_prime) = 1
wrapper_cons1 <- function(x) {
  vals = calc_vals(x[1], x[2])
  return(vals$cons1)
}

# 约束函数2:change = 0.01
wrapper_cons2 <- function(x) {
  vals = calc_vals(x[1], x[2])
  return(vals$cons2)
}

#OP problem
library(ROI)
library(ROI.plugin.nloptr)

prob<-OP(
  objective = F_objective(F = wrapper_obj, n = 2),
  constraints = 
    F_constraint(F = wrapper_cons1, dir = "==", rhs = 1) + 
    F_constraint(F = wrapper_cons2, dir = "==", rhs = 0.01)
)
solve_res = ROI_solve(prob, solver = "nloptr.cobyla", start = c(0,0))
H = solution(solve_res)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 17:00:01