【问题标题】:How is it possible to collect NLexpression in a loop?如何在循环中收集 NL 表达式?
【发布时间】:2021-11-09 10:57:05
【问题描述】:

您能帮我了解如何在循环中收集一些 NL 表达式吗? 我想为所有 i=1:10 保留 k8 和 k9 作为场景。这意味着在循环结束时,Q 等于每个场景下的 k8 和 k9 的集合( i )。我无法定义一个矩阵并将每对 k8 和 k9 作为一个元素放入其中。考虑到 Q 代码也不能正常工作。 非常感谢您的热心帮助。

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=0;
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

    Q=Q+k8+k9;
    #-----------------------------------------------------------------------
end

【问题讨论】:

  • 这个问题不遵循 StackOverflow 格式。请把它变成一个最小的工作示例,而不是你的生产代码的完整转储。见stackoverflow.com/help/how-to-ask

标签: julia julia-jump ijulia-notebook julia-plots


【解决方案1】:

您的代码中有几个问题。

  • 为什么要在每个循环中创建一个新模型?您不能像使用 Q=Q+k8+k9 那样跨模型聚合表达式
  • 您不能添加像Q=Q+k8+k9 这样的非线性表达式。所有非线性表达式都必须出现在宏内

通常,您不受限于 JuMP 的特定语法。您可以使用任何 Julia 数据结构来提供帮助。在下面的代码中,我只是将表达式推入 vec

我还没有测试过,所以可能有错别字等,但这应该为您指明正确的方向:

using JuMP, Distributions
E, landa, T1, T2, gam1, gam2, a1, a2 = 0.05, 0.01, 2, 2, 1, 1, 0.5, 0.1
ALT = Model()
f(x) = cdf(Normal(0, 1), x)
JuMP.register(ALT, :f, 1, f; autodiff = true)
@variable(ALT, h >= 0.001)
@variable(ALT, L >= 0.000001)
@variable(ALT, n >= 2, Int)
k8, k9 = Any[], Any[]
for i in 1:4
    C1 = rand(100:100:300)
    sig = rand(0.5:0.5:2)
    k1 = @NLexpression(ALT, h / (1 - f(L - sig * sqrt(n)) + f(-L - sig * sqrt(n))))
    k2 = @NLexpression(ALT, (1 - (1 + landa * h) * exp(-landa * h)) / (landa * (1 - exp(-landa * h))))
    k3 = @NLexpression(ALT, E * n + T1 * gam1 + T2 * gam2)
    push!(k8, @NLexpression(ALT, C1 * (k1 - k2 + k3))
    push!(k9, @NLexpression(ALT, k9, (a1 + a2 * n) / h * k1)
end
Q = @NLexpression(ALT, sum(k for k in k8)  + sum(k for k in k9))

【讨论】:

  • 我真的很感激。如果模型是在循环之外定义的,则会发生错误。错误说An object of name k1 is already attached to this model. If this is intended, consider using the anonymous construction syntax, e.g., x = @variable(model, [1:N], ...) where the name of the object does not appear inside the macro. 然后为了识别k1,我必须将模型放入循环中。事实上,我不是编码专家;(。我正在尝试学习和编码我的模型:)。非常感谢您的热心帮助。
  • 如果你不介意,请你帮我看看我怎么能看到k8的元素? julia> k8 4-element Array{Any,1}: "Reference to nonlinear expression #12" "Reference to nonlinear expression #12" "Reference to nonlinear expression #12" "Reference to nonlinear expression #12" 有没有可能演示 NL 表达式。
  • 1.像我的回答一样使用匿名语法,并且错误消息提示。 2. 这在最近的跳转版本中已修复。
  • 非常感谢您。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-16
相关资源
最近更新 更多