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

Julia/JuMP非线性约束中使用自定义函数的问题求助

问题描述

在Julia/JuMP中定义了如下函数:

T=1:6

function Vini(t)
    if t==1
        return V0
    else
        return V[t-1]
    end
end

其中变量定义为:

@variable(model, 6000 <= V[T] <= 18000)

V0为标量。该函数在线性约束中可正常运行,例如:

@constraint(model, c2[t in 1:6], V[t] == Vini(t) + n*(INF-Q[t]))

但将其用于非线性约束@NLconstraint时出现错误:

@NLconstraint(model, c5_2[t=1:6], PH[t] == 20000*(Q[t]-260*W[t])/(220000-(V[t]+Vini(t))))

PH、Q、W均为变量,INF为标量。目标是复刻AMPL中的实现逻辑:

subject to c5_2{t in T}: PH[t] = 20000*(Q[t]-260*W[t])/(220000-(V[t]+(if t=1 then V0 else V[t-1])) 

报错信息:

LoadError: Unsupported operation Vini
in expression starting at C:\Users\clopezsalgado\Documents\JULIA Models\Jump Models\second_optexample.jl:57
error(s::String) at error.jl:33
_process_expr!(expr::MathOptInterface.FileFormats.NL._NLExpr, args::Vector{Any}) at NLExpr.jl:434
_process_expr!(expr::MathOptInterface.FileFormats.NL._NLExpr, arg::Expr) at NLExpr.jl:397
_process_expr!(expr::MathOptInterface.FileFormats.NL._NLExpr, args::Vector{Any}) at NLExpr.jl:446
_process_expr!(expr::MathOptInterface.FileFormats.NL._NLExpr, arg::Expr) at NLExpr.jl:397
_process_expr!(expr::MathOptInterface.FileFormats.NL._NLExpr, args::Vector{Any}) at NLExpr.jl:446
_process_expr!(expr::MathOptInterface.FileFormats.NL._NLExpr, arg::Expr) at NLExpr.jl:397
_process_expr!(expr::MathOptInterface.FileFormats.NL._NLExpr, args::Vector{Any}) at NLExpr.jl:446
_process_expr!(expr::MathOptInterface.FileFormats.NL._NLExpr, arg::Expr) at NLExpr.jl:397
_process_expr!(expr::MathOptInterface.FileFormats.NL._NLExpr, args::Vector{Any}) at NLExpr.jl:446
_process_expr!(expr::MathOptInterface.FileFormats.NL._NLExpr, arg::Expr) at NLExpr.jl:397
_process_expr!(expr::MathOptInterface.FileFormats.NL._NLExpr, args::Vector{Any}) at NLExpr.jl:446
_process_expr!(expr::MathOptInterface.FileFormats.NL._NLExpr, arg::Expr) at NLExpr.jl:397
MathOptInterface.FileFormats.NL._NLExpr(expr::Expr) at NLExpr.jl:365
MathOptInterface.FileFormats.NL._NLConstraint(expr::Expr, bound::MathOptInterface.NLPBoundsPair) at NL.jl:75
copy_to(dest::MathOptInterface.FileFormats.NL.Model, model::MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}) at NL.jl:280
copy_to at AmplNLWriter.jl:248 [inlined]
optimize! at MathOptInterface.jl:86 [inlined]
optimize!(m::MathOptInterface.Utilities.CachingOptimizer{AmplNLWriter.Optimizer, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}) at cachingoptimizer.jl:316
解决思路
  • 直接替换函数调用为条件表达式:JuMP的@NLconstraint不支持解析自定义函数,把Vini(t)直接替换成AMPL风格的三元条件逻辑,避免函数调用:
    @NLconstraint(model, c5_2[t in T], PH[t] == 20000*(Q[t]-260*W[t])/(220000-(V[t] + (t == 1 ? V0 : V[t-1]))))
    
  • 提前定义辅助变量(可选):如果需要复用该逻辑,可先定义辅助变量V_prev[T],再代入非线性约束,提升代码可读性:
    @variable(model, V_prev[T])
    @constraint(model, [t in T], V_prev[t] == (t == 1 ? V0 : V[t-1]))
    @NLconstraint(model, c5_2[t in T], PH[t] == 20000*(Q[t]-260*W[t])/(220000-(V[t]+V_prev[t])))
    
  • 核心原因:线性约束@constraint会在宏展开阶段解析函数返回的表达式,但非线性约束的NL解析器仅支持原生的表达式结构(如三元运算符、变量、标量运算),无法识别自定义Julia函数。

内容的提问来源于stack exchange,提问作者CJ Lopez-Salgado

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 18:05:34