这是基于 Tasos 建议的扩展答案(感谢 Tasos!)。
tl;dr您可以对已注册的内容使用 try-catch 语句。您还可以在全局环境中更改目标函数中的参数,但不能将它们包装在函数中。
以下有效地允许检查函数的重新定义:
function foo2( f, f1, f2 )
try
JuMP.register(:f,1,f1,f2)
end
####
# Optimization problem here using f
# Leads to some return statement
####
end
end
更好的是,您实际上可以使用 JuMP 寻找的简单方式f
来更改目标函数中的参数(尽管您每次都需要重新定义模型,因为您无法将 a@NLparameter
放入用户定义的目标中)。例如:
using JuMP
using Ipopt
f = (x) -> exp( A * x ) - x
f1 = (x) -> A * exp( A * x ) - 1.0
f2 = (x) -> A * A * exp( A * x )
# Period objective function
JuMP.register(:f, 1, f, f1, f2)
A = 1.0
mod = Model(solver=Ipopt.IpoptSolver(print_level=0))
@variable(mod, - Inf <= x <= Inf )
@NLobjective(mod, Min, f(x) )
status=solve(mod)
println("x = ", getvalue(x))
# Returns 0
A = 2.0
mod = Model(solver=Ipopt.IpoptSolver(print_level=0))
@variable(mod, - Inf <= x <= Inf )
@NLobjective(mod, Min, f(x) )
status=solve(mod)
println("x = ", getvalue(x))
# Returns -0.34657 (correct)
你甚至可以重新定义f
为完全不同的东西,这仍然有效。但是,您不能将其包装在函数中。例如:
function set_A_sol( A )
f = (x) -> exp( A * x ) - x
f1 = (x) -> A * exp( A * x ) - 1.0
f2 = (x) -> A * A * exp( A * x )
# Local redefinition of f
try
JuMP.register(:f, 1, f, f1, f2)
end
mod = Model(solver=Ipopt.IpoptSolver(print_level=0))
@variable(mod, - Inf <= x <= Inf )
@NLobjective(mod, Min, f(x) )
status=solve(mod)
return getvalue(x)
end
ans1 = set_A_sol(0.5)
ans2 = set_A_sol(1.0)
ans3 = set_A_sol(2.0)
# All return 1.38629
我不完全明白为什么,但似乎第一次A
设置在里面set_A_sol
,JuMP 注册A
一劳永逸地修复了。鉴于这是我最终想要做的事情,我仍然被困住了。欢迎提出建议!