JuMP: LoadError: Неизвестная функция: f1 используется в нелинейном выражении

Мне нужно сгенерировать все точки Парето, но я получил эту ошибку.

using JuMP
using Gurobi
using Gadfly
using Ipopt

m = Model(solver=IpoptSolver(print_level=0))
@variable(m, 0.1 <= x <= 1.0)
@variable(m, 0.0 <= y <= 1.0)

pareto_x = Float16[]
pareto_y = Float16[]

for i in 0.0:0.1:1.0
    for j in 0.0:0.1:1.0

      f1(x,y) = x
      f2(x,y) = (2.0-exp(-((y-0.2)/0.004)^2)-0.8*exp(-((y-0.6)/0.4)^2) )/x

      @NLobjective(m, Min, i*f1(x,y) + j*f2(x,y) ) ## <<-- ERROR HERE

      status = solve(m)

      println("Objective value: ", getobjectivevalue(m))
      x_opt = getvalue(x)
      y_opt = getvalue(y)
      println("x = ", x_opt)
      println("y = ", y_opt)

      push!(pareto_x,f1(x_opt,y_opt))
      push!(pareto_y,f2(x_opt,y_opt))
    end
end
plot(x=pareto_x, y=pareto_y)

person sparkle    schedule 10.07.2016    source источник
comment
Что произойдет, если вы замените все экземпляры f1 на x? Моя интуиция подсказывает мне, что вам не разрешены произвольные вызовы функций в @NLobjectives   -  person Lyndon White    schedule 11.07.2016
comment
Да, но я бы использовал произвольную функцию, чтобы повторно использовать эту функцию для создания точек Парето.   -  person sparkle    schedule 11.07.2016
comment
В этом случае, поскольку ваши функции представляют собой просто выражения в закрытой форме, вы должны просто использовать @NLexpression вместо пользовательских функций. Как правило, это будет работать лучше, потому что JuMP в настоящее время не вычисляет производные второго порядка, если присутствуют пользовательские функции.   -  person mlubin    schedule 12.07.2016


Ответы (1)


http://jump.readthedocs.io/en/latest/nlp.html#user-defined-functions

mysquare(x) = x^2
myf(x,y) = (x-1)^2+(y-2)^2

JuMP.register(:myf, 2, myf, autodiff=true)
JuMP.register(:mysquare, 1, mysquare, autodiff=true)

m = Model()

@variable(m, x[1:2] >= 0.5)
@NLobjective(m, Min, myf(x[1],mysquare(x[2])))

РЕШЕНО с этим

f1(x,y) = x
f2(x,y) = (2.0-exp(-((y-0.2)/0.004)^2)-0.8*exp(-((y-0.6)/0.4)^2) )/x

isdefined(:f1) || JuMP.register(:f1, 2, f1, autodiff=true)
isdefined(:f2) || JuMP.register(:f2, 2, f2, autodiff=true)

@objective(m, Min, f1(x,y) )
person sparkle    schedule 11.07.2016
comment
Обратите внимание, что JuMP.register определяет только функции для использования в нелинейных выражениях, например, @NLobjective или @NLconstraint. Приведенный выше пример работает случайно, потому что f1 — это линейная функция, используемая в @objective. - person mlubin; 12.07.2016