Próbuję przepisać funkcję optymalizacji Matlab fmincon w Julia.Optymalizacja Matlab do Julii: funkcja w JuMP @ SetNLObjective
Oto kod Matlab:
function [x,fval] = example3()
x0 = [0; 0; 0; 0; 0; 0; 0; 0];
A = [];
b = [];
Ae = [1000 1000 1000 1000 -1000 -1000 -1000 -1000];
be = [100];
lb = [0; 0; 0; 0; 0; 0; 0; 0];
ub = [1; 1; 1; 1; 1; 1; 1; 1];
noncon = [];
options = optimset('fmincon');
options.Algorithm = 'interior-point';
[x,fval] = fmincon(@objfcn,x0,A,b,Ae,be,lb,ub,@noncon,options);
end
function f = objfcn(x)
% user inputs
Cr = [ 0.0064 0.00408 0.00192 0;
0.00408 0.0289 0.0204 0.0119;
0.00192 0.0204 0.0576 0.0336;
0 0.0119 0.0336 0.1225 ];
w0 = [ 0.3; 0.3; 0.2; 0.1 ];
Er = [0.05; 0.1; 0.12; 0.18];
% calculate objective function
w = w0+x(1:4)-x(5:8);
Er_p = w'*Er;
Sr_p = sqrt(w'*Cr*w);
% f = objective function
f = -Er_p/Sr_p;
end
i tu jest mój kod Julia:
using JuMP
using Ipopt
m = Model(solver=IpoptSolver())
# INPUT DATA
w0 = [ 0.3; 0.3; 0.2; 0.1 ]
Er = [0.05; 0.1; 0.12; 0.18]
Cr = [ 0.0064 0.00408 0.00192 0;
0.00408 0.0289 0.0204 0.0119;
0.00192 0.0204 0.0576 0.0336;
0 0.0119 0.0336 0.1225 ]
# VARIABLES
@defVar(m, 0 <= x[i=1:8] <= 1, start = 0.0)
@defNLExpr(w, w0+x[1:4]-x[5:8])
@defNLExpr(Er_p, w'*Er)
@defNLExpr(Sr_p, w'*Cr*w)
@defNLExpr(f, Er_p/Sr_p)
# OBJECTIVE
@setNLObjective(m, Min, f)
# CONSTRAINTS
@addConstraint(m, 1000*x[1] + 1000*x[2] + 1000*x[3] + 1000*x[4] -
1000*x[5] - 1000*x[6] - 1000*x[7] - 1000*x[8] == 100)
# SOLVE
status = solve(m)
# DISPLAY RESULTS
println("x = ", round(getValue(x),4))
println("f = ", round(getObjectiveValue(m),4))
optymalizacja Julia pracuje kiedy jawnie zdefiniować funkcję celu w @setNLObjective jednak ten nie nadaje się jako dane wejściowe użytkownika mogą się zmienić, co skutkuje inną funkcją celu, którą można zobaczyć na podstawie sposobu tworzenia funkcji celu.
Problem wydaje się być ograniczenie skakać w jaki sposób funkcja celu może być wpisana do @setNLObjective argumentu:
Wszystkie wyrażenia muszą być proste operacje skalarne. Nie można używać produktów dot, matrix-vector, plasterków wektorowych itp. Przetłumacz operacje wektorowe na jawne operacje sum {}.
Czy istnieje sposób obejścia tego? Czy są jakieś inne pakiety w Julii, które rozwiązują to, mając na uwadze, że nie będę miał jacobian ani hessian.
Wielkie dzięki.
Pakiet 'NLopt' nie ma tego ograniczenia. Możesz przekazać dowolną funkcję lub funkcję anonimową. –
Spojrzałem na NLopt i wygląda na to, co chcę, ale brak przykładów powstrzymuje moje postępy. Czy mógłbyś podać mi prosty przykład używając NLopt? lub nawet moja funkcja w NLopt. Dzięki – kulsuri
zadałem pytanie na temat 'NLopt' tutaj na SO około tydzień temu, który zawiera działający przykład prostego problemu. [Tutaj] (http://stackoverflow.com/questions/34755612/nexpected-behaviour-of-ftol-abs-and-ftol-rel-in-nlopt) jest linkiem. Upewnij się, że działasz na komputerze, a jeśli nadal masz problemy, wróć do mnie tutaj, a ja zobaczę, czy mogę zapewnić dodatkową pomoc. –