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

如何在JuMP循环中收集NLexpression?场景化存储k8与k9的技术求助

解决JuMP循环中收集NLexpression结果的问题

我明白你想在循环结束后保留每个场景(i=1到N)对应的k8和k9值,而不是把它们全部累加起来。当前代码里Q=Q+k8+k9只是在做数值累加,既没办法区分不同场景的结果,还因为k8/k9是JuMP的NLexpression对象,直接这样操作本身就会出问题。

下面是调整后的完整解决方案:

步骤1:初始化结果存储容器

我们可以用一个类型明确的数组来保存每个场景的(k8, k9)对,这样后续访问和处理结果会更清晰:

Q = Tuple{Float64, Float64}[]  # 存储每个场景的(k8数值, k9数值)元组

步骤2:补全求解逻辑并收集结果

你当前的代码遗漏了最关键的模型求解步骤,必须调用optimize!(ALT)才能让JuMP计算出变量和表达式的具体值。之后我们用value()函数提取k8和k9的数值,再存入数组中。

调整后的完整代码:

using JuMP, CPUTime, Distributions, Ipopt, Juniper, Cplex 

n1=1; #the least of scenarios 
N=4; #number of scenarios 
M=20; #number of sampling 
landa=0.01; 
E=0.05 
T0=0; 
T1=2; 
T2=2; 
gam2=1; 
gam1=1; 
a1=0.5; 
a2=0.1; 
a3=50; 
ap=25; 
c0=10; 
Zn=zeros(N, 4) 
Q = Tuple{Float64, Float64}[]  # 初始化结果存储数组

for i in n1:N 
    C1=rand(100:100:300); 
    sig=rand(0.5:0.5:2); 
    f(x) = cdf(Normal(0, 1), x); 
    #--------------------------------------------------------------------------- 
    ALT= Model(optimizer_with_attributes(Juniper.Optimizer, 
        "nl_solver"=>optimizer_with_attributes(Ipopt.Optimizer, "print_level" => 0), 
        "mip_solver"=>optimizer_with_attributes(Cplex.Optimizer, "logLevel" => 0),
        "registered_functions" =>[Juniper.register( :f, 1, f; autodiff = true)]
    )); 
    # variables----------------------------------------------------------------- 
    JuMP.register(ALT, :f, 1, f; autodiff = true); 
    @variable(ALT, h >= 0.001); 
    @variable(ALT, L >= 0.000001); 
    @variable(ALT, n>=2, Int); 
    #--------------------------------------------------------------------------- 
    @NLexpression(ALT,k1,h/(1-f(L-sig*sqrt(n))+f(-L - sig*sqrt(n)))); # HARL1 
    @NLexpression(ALT,k2,(1-(1+landa*h)*exp(-landa*h))/(landa*(1-exp(-landa*h)))); #to 
    @NLexpression(ALT,k3,E*n+T1*gam1+T2*gam2); 
    @NLexpression(ALT,k8,(C1*(k1-k2+k3)));# depend on scenario 
    @NLexpression(ALT,k9,(((a1+a2*n)/h)*(k1)));#depend on scenario 

    # 关键:求解当前场景的模型
    optimize!(ALT)

    # 检查求解状态(可选但推荐,避免异常)
    if termination_status(ALT) == MOI.OPTIMAL
        # 提取数值并添加到结果集合中
        push!(Q, (value(k8), value(k9)))
    else
        @warn "场景$i 求解失败,状态:$(termination_status(ALT))"
        push!(Q, (NaN, NaN))  # 用NaN标记求解失败的场景
    end
#----------------------------------------------------------------------- 
end

# 查看最终结果
println("每个场景的(k8,k9)集合:")
for (idx, (k8_val, k9_val)) in enumerate(Q)
    println("场景$idx: k8=$k8_val, k9=$k9_val")
end

关键细节说明

  • 容器类型:Tuple{Float64, Float64}[]明确了数组存储的是浮点型元组,比空数组更规范,后续使用时也能避免类型错误。
  • 求解模型:optimize!(ALT)是必须的,JuMP不会自动计算变量和表达式的值,只有调用求解函数后,value()才能返回有效结果。
  • 数值提取:value(k8)会把JuMP的NLexpression对象转换成具体的浮点数值,这样才能存入数组中供后续使用。
  • 异常处理:添加求解状态检查,能避免因模型无解或求解出错导致程序崩溃,同时用NaN标记异常场景,方便后续排查问题。

循环结束后,Q就是一个包含所有场景(k8,k9)结果的集合,你可以通过索引访问单个场景的结果,比如Q[2]就能获取场景2的k8和k9值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.01 01:02:42