Sto tentando di riscrivere una funzione di ottimizzazione fmincon di Matlab in Julia.Ottimizzazione da Matlab a Julia: funzione in JuMP @SetNLObjective
Ecco il codice 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
e qui è il mio codice Giulia:
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))
Julia ottimizzazione funziona quando definisco esplicitamente la funzione obiettivo in @setNLObjective tuttavia questo non è adatto come il l'input dell'utente può cambiare risultando in una funzione obiettivo diversa, che puoi vedere da come viene creata la funzione obiettivo.
Il problema sembra essere la limitazione di salto nel modo in cui la funzione obiettivo può essere inserito nella discussione @setNLObjective:
Tutte le espressioni devono essere semplici operazioni scalari. Non è possibile utilizzare i prodotti a punti, a matrice vettoriale, le sezioni vettoriali, ecc. Tradurre le operazioni vettoriali in operazioni esplicite di somma {}.
C'è un modo per aggirare questo? O ci sono altri pacchetti in Julia che risolvono questo, tenendo presente che non avrò il jacobian o hessian.
Molte grazie.
Il pacchetto 'NLopt' non ha questa limitazione. Puoi passare a qualsiasi funzione o funzione anonima. –
Ho dato un'occhiata a NLopt e sembra essere quello che sto cercando, ma la mancanza di esempi sta fermando i miei progressi. Potresti darmi un esempio semplice usando NLopt? o anche la mia funzione in NLopt. Grazie – kulsuri
Ho fatto una domanda su 'NLopt' qui su SO circa una settimana fa che includeva un esempio funzionante di un problema semplice. [Qui] (http://stackoverflow.com/questions/34755612/unexpected-behaviour-of-ftol-abs-and-ftol-rel-in-nlopt) è il collegamento. Assicurati di averlo funzionante sulla tua macchina, quindi se hai ancora problemi, torna da me qui e vedrò se posso fornire ulteriore aiuto. –