Julia JuMP目标函数调用max报错无匹配isless方法问题求助
报错原因定位
- 触发
MethodError的核心是,你在普通Julia函数funP中直接调用了原生Base.max()处理JuMP优化变量erro[i]。 - 原生
max()的运行逻辑是先对两个参数做大小比较(对应isless方法),但JuMP的VariableRef是表示优化决策的符号对象,没有定义和普通整数/浮点数的直接大小比较规则,当宏尝试在构造目标表达式时执行max(erro[i], 0),就会抛出方法找不到的报错。 - 你当前对
erro[i]的约束设计也和目标逻辑不匹配:现有约束erro[i] >= 残差、erro[i] >= -残差定义的是残差的绝对值形式,本质是L1损失的建模方式,并非你想要的带不对称权重的分位数pinball损失。 - 就算强行适配类型兼容,带
max的非光滑目标也超出了OSQP作为线性求解器的处理能力范围。
修正方案
按照分位数回归的标准线性规划建模方式改造,从根源上规避类型不匹配问题:
- 核心思路:把非光滑的pinball损失,通过拆分非负辅助变量转化为线性表达式,这也是分位数回归适配线性求解器的通用实现方法。
- 建模规则:
- 定义原始残差:
e_i = contratos[i] - β[0] - β[1]*spot[i] - 引入两个非负辅助变量
pos_e[i] >=0、neg_e[i] >=0,满足残差拆分关系:e_i = pos_e[i] - neg_e[i] - 目标函数直接使用线性形式的损失项,无需手动嵌套
max运算:最小化sum(τ * pos_e[i] + (1-τ) * neg_e[i])
- 定义原始残差:
- 对应可运行的核心代码片段:
τ = 0.2 modelquant = Model(with_optimizer(OSQP.Optimizer)) @variable(modelquant, β[i=0:1]) # 替换原有erro变量为拆分的非负辅助变量 @variable(modelquant, pos_e[i=1:T] >= 0) @variable(modelquant, neg_e[i=1:T] >= 0) # 残差拆分约束 @constraint(modelquant, [i=1:T], contratos[i] - β[0] - β[1]*spot[i] == pos_e[i] - neg_e[i]) # 线性目标函数,无max嵌套 @objective(modelquant, Min, sum(τ*pos_e[i] + (1-τ)*neg_e[i] for i=1:T)) optimize!(modelquant) objective_value(modelquant) 𝐁 = JuMP.value.(β)
- 原有的
funP函数、基于旧erro变量的约束可以全部删除,改造后的模型完全适配OSQP的线性求解能力,不会再触发类型不匹配报错。
内容的提问来源于stack exchange,提问作者rafael silva
相关产品推荐
相关产品推荐

