朱莉娅中的NonlinearConstraintIndex是什么?

时间:2020-08-26 05:24:00

标签: julia julia-jump

我厌倦了在以下代码中更改非线性约束的右手。尽管善良的人为我提供了很多帮助,但我找不到解决方法。您能再帮我一次吗?非常感谢。

using JuMP, Ipopt, Juniper,Gurobi,CPUTime
#-----Model parameters--------------------------------------------------------
sig=0.86;
landa=50;
E=T0=T1=.0833;
T2=0.75;
gam2=1; gam1=0;
a1=5; a2=4.22; a3=977.4; ap=977.4;
C1=949.2; c0=114.24;
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(Gurobi.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.1);
@variable(ALT, L >= 0.00001);
@variable(ALT, n>=2, Int);

#---------------------------------------------------------------------------

@NLexpression(ALT,k1,h/(1-f(L-sig*sqrt(n))+f(-L - sig*sqrt(n))));

@NLexpression(ALT,k2,(1-(1+landa*h)*exp(-landa*h))/(landa*(1-exp(-landa*h))));

@NLexpression(ALT,k3,E*n+T1*gam1+T2*gam2);

@NLexpression(ALT,k4,1/landa+h/(1-f(L-sig*sqrt(n))+f(-L-sig*sqrt(n))));

@NLexpression(ALT,k5,-(1-(1+landa*h)*exp(-landa*h))/(landa*(1-exp(-landa*h)))+E*n+T1*gam1+T2*gam2);

@NLexpression(ALT,k6,(exp(-landa*h)/1-exp(-landa*h))*(a3/(2*f(-L)))+ap);

@NLexpression(ALT,k7,1-f(L-sig*sqrt(n))+f(-L-sig*sqrt(n)));

@NLexpression(ALT,F,c0/landa+C1*(k1-k2+k3)+((a1+a2*n)/h)*(k4+k5+k3)+k6);

@NLexpression(ALT,FF,k4-k2+E*n+T1+T2+(1-gam1)*((exp(-landa*h)/1-exp(-landa*h)*T0)/(2*f(-L))));

#routing constraints--------------------------------------------------------

@NLconstraint(ALT, f(-L) <= 1/400);

#objective function---------------------------------------------------------

@NLexpression(ALT,f1,F/FF);

@NLexpression(ALT,f2,1/k7);
#-------------------------------------------------------------------------
@NLparameter(ALT, rp1 == 10000);
@NLparameter(ALT, lp1 == -10000);
@NLparameter(ALT, rp2 == 10000);
@NLparameter(ALT, lp2 == -10000);

@NLconstraint(ALT,rf1,f1<=rp1);

@NLconstraint(ALT,lf1,f1>=lp1);

@NLconstraint(ALT,rf2,f2<=rp2);

@NLconstraint(ALT,lf2,f2>=lp2);
#------------------------------------------------------------------------
ZT=zeros(2,1);
ZB=zeros(2,1);
#-----------------------------------------------------------------------------
@NLobjective(ALT,Min,f2);
optimize!(ALT);

f2min=getvalue(f2);
ZB[2]=f2min;

set_value(rp2, f2min);

set_value(lp2, f2min);

@NLobjective(ALT,Min,f1);
optimize!(ALT);

ZB[1]=getvalue(f1);
#--------------------------------------------------------------------------
set_value(rp2, 10000);

set_value(lp2, ZB[2]+0.1);**

@NLobjective(ALT,Min,f1);
optimize!(ALT);

f1min=getvalue(f1);

ZT[1]=f1min;

尽管约束(**)限制了ZB(第二个目标优化时的目标值),但第一个目标优化时它的约束是949.2000589366443。您能帮我什么原因吗? 选择求解器是否有效? 这些求解器无法求解非线性模型? 非常感谢

julia> ZB
2×1 Array{Float64,2}:
 949.2000092739842
   1.0000000053425355
#--------------------------------------------------
julia> ZT
2×1 Array{Float64,2}:
 949.2000589366443
   0.0

代码已更新。实际上,这段代码试图找到pareto front的两个点。 这是一个例子

using JuMP,CPLEX,CPUTime
#----------------------------------------------------------------------
WES=Model(CPLEX.Optimizer)
#-----------------------------------------------------------------------
@variable(WES,x[i=1:4]>=0);
@variable(WES,y[i=5:6]>=0,Int);
@variable(WES,xp[i=1:4]>=0);
@variable(WES,yp[i=5:6]>=0,Int);
#-----------------------------------------------------------------------
ofv1=[3 6 -3 -5]
ofv2=[-15 -4 -1 -2];
f1=sum(ofv1[i]*x[i] for i=1:4);
f2=sum(ofv2[i]*x[i] for i=1:4);
f1p=sum(ofv1[i]*xp[i] for i=1:4);
f2p=sum(ofv2[i]*xp[i] for i=1:4);
#------------------------------------------------------------------------

@constraint(WES,con1,-x[1]+3y[5]<=0);
@constraint(WES,con2,x[1]-6y[5]<=0);
@constraint(WES,con3,-x[2]+3y[5]<=0);
@constraint(WES,con4,x[2]-6y[5]<=0);
@constraint(WES,con5,-x[3]+4y[6]<=0);
@constraint(WES,con6,x[3]-4.5y[6]<=0);
@constraint(WES,con7,-x[4]+4y[6]<=0);
@constraint(WES,con8,x[4]-4.5y[6]<=0);
@constraint(WES,con9,y[5]+y[6]<=5);
@constraint(WES,con14,-xp[1]+3yp[5]<=0);
@constraint(WES,con15,xp[1]-6yp[5]<=0);
@constraint(WES,con16,-xp[2]+3yp[5]<=0);
@constraint(WES,con17,xp[2]-6yp[5]<=0);
@constraint(WES,con18,-xp[3]+4yp[6]<=0);
@constraint(WES,con19,xp[3]-4.5yp[6]<=0);
@constraint(WES,con20,-xp[4]+4yp[6]<=0);
@constraint(WES,con21,xp[4]-4.5yp[6]<=0);
@constraint(WES,con22,yp[5]+yp[6]<=5);
#------------------------------------------------------------------------
ZT=zeros(2,1);
ZB=zeros(2,1);
#--------------------------------------------------------------------------------
@objective(WES,Min,f2);
optimize!(WES);
f2min=JuMP.value(f2)
set_normalized_rhs(rf2,f2min);
set_normalized_rhs(lf2,f2min);

ZB[2]=getvalue(f2);
@objective(WES,Min,f1);
optimize!(WES);
ZB[1]=getvalue(f1);

#----------------
JuMP.setRHS(rf2,10000);
JuMP.setRHS(lf2,ZB[2]);
@objective(WES,Min,f1);
optimize!(WES);
set_normalized_rhs(rf1,getvalue(f1));
set_normalized_rhs(lf1,getvalue(f1));
ZT[1]=getvalue(f1);

@objective(WES,Min,f2);
optimize!(WES);
ZT[2]=getvalue(f2);

但是当运行右侧功能时,它再次出现该错误。

set_normalized_rhs(rf2,f2min)
ERROR: MethodError: no method matching set_normalized_rhs(::ConstraintRef{Model,NonlinearConstraintIndex,ScalarShape}, ::Float64)
Closest candidates are:
  set_normalized_rhs(::ConstraintRef{Model,MathOptInterface.ConstraintIndex{F,S},Shape} where Shape<:AbstractShape, ::Any) where {T, S<:Union{MathOptInterface.EqualTo{T}, MathOptInterface.GreaterThan{T}, MathOptInterface.LessThan{T}}, F<:Union{MathOptInterface.ScalarAffineFunction{T}, MathOptInterface.ScalarQuadraticFunction{T}}} at C:\Users\admin\.julia\packages\JuMP\YXK4e\src\constraints.jl:478
Stacktrace:
 [1] top-level scope at none:1

我找不到问题所在。此示例在Julia 0.6.4.2中运行。 ZB和ZT是:

julia>ZB
2×1 Array{Float64,2}:
 270.0
 -570.0
julia> ZT
2×1 Array{Float64,2}:
 -180.0
 -67.5.0

的确感谢。

1 个答案:

答案 0 :(得分:3)

is there any possibility to change the RHS of non-linear constraints in julia?重复。

您可以使用set_value更新非线性参数的值。 https://jump.dev/JuMP.jl/v0.21.3/nlp/#JuMP.set_value-Tuple{NonlinearParameter,Number}

这是一个例子

using JuMP
model = Model()
@variable(model, x)
@NLparameter(model, p == 1)
@NLconstraint(model, sqrt(x) <= p)
# To make RHS p=2
set_value(p, 2)