« Découvrir Scilab/Optimisation d'une fonction » : différence entre les versions

Un livre de Wikilivres.
Contenu supprimé Contenu ajouté
DannyS712 (discussion | contributions)
m <source> -> <syntaxhighlight> (phab:T237267)
 
Ligne 11 : Ligne 11 :


L'optimisation non linéaire est le cas général. On utilise pour cela la fonction <code>optim</code> :
L'optimisation non linéaire est le cas général. On utilise pour cela la fonction <code>optim</code> :
<source lang="scilab">
<syntaxhighlight lang="scilab">
[fopt, xopt] = optim(costf, x0)
[fopt, xopt] = optim(costf, x0)
</syntaxhighlight>
</source>
* <code>costf</code> est la « fonction de coût » de ƒ ; c'est une fonction qui renvoit la valeur de la fonction ƒ en '''x''' et le gradient de ƒ en '''x''', défini sous la forme<br /><code>function [f, g, ind] = costf(x, ind)</code><br />où <code>f</code> désigne ƒ('''x'''), <code>g</code> est le gradient et <code>ind</code> est un index, un entier permettant de modifier le comportement de <code>costf</code> ;
* <code>costf</code> est la « fonction de coût » de ƒ ; c'est une fonction qui renvoit la valeur de la fonction ƒ en '''x''' et le gradient de ƒ en '''x''', défini sous la forme<br /><code>function [f, g, ind] = costf(x, ind)</code><br />où <code>f</code> désigne ƒ('''x'''), <code>g</code> est le gradient et <code>ind</code> est un index, un entier permettant de modifier le comportement de <code>costf</code> ;
Ligne 20 : Ligne 20 :
* <code>fopt</code> = ƒ(<code>xopt</code>), valeur estimée du minimum.
* <code>fopt</code> = ƒ(<code>xopt</code>), valeur estimée du minimum.
On peut indiquer des bornes inférieures et supérieure de '''x''', sous al forme de vecteurs '''x'''<sub>inf</sub> et '''x'''<sub>sup</sub> :
On peut indiquer des bornes inférieures et supérieure de '''x''', sous al forme de vecteurs '''x'''<sub>inf</sub> et '''x'''<sub>sup</sub> :
<source lang="scilab">
<syntaxhighlight lang="scilab">
[fopt, xopt] = optim(f, x0, "b", xinf, xsup)
[fopt, xopt] = optim(f, x0, "b", xinf, xsup)
</syntaxhighlight>
</source>


La fonction <code>optim()</code> est une [[w:fr:Méthode de quasi-Newton|méthode de quasi-Newton]] utilisant les [[w:fr:Critères de Wolfe|critères de Wolfe]].
La fonction <code>optim()</code> est une [[w:fr:Méthode de quasi-Newton|méthode de quasi-Newton]] utilisant les [[w:fr:Critères de Wolfe|critères de Wolfe]].
Ligne 30 : Ligne 30 :
[[Fichier:Minimum fonction scilab.svg|vignette|upright=2|Minimum de la fonction pseudo-convexe différentiable <math>y = x^2 + 5 \sin x</math> avec scilab.]]
[[Fichier:Minimum fonction scilab.svg|vignette|upright=2|Minimum de la fonction pseudo-convexe différentiable <math>y = x^2 + 5 \sin x</math> avec scilab.]]


<source lang="scilab">
<syntaxhighlight lang="scilab">
function [f, g, ind] = cout(x, ind)
function [f, g, ind] = cout(x, ind)
f = x.*x + 5*sin(x);
f = x.*x + 5*sin(x);
Ligne 46 : Ligne 46 :
plot(x, y);
plot(x, y);
plot(xopt, fopt, "k+");
plot(xopt, fopt, "k+");
</syntaxhighlight>
</source>


Si l'on ne connaît pas de forme analytique de la fonction dérivée, on peut utiliser la fonction <code>numderivative()</code> :
Si l'on ne connaît pas de forme analytique de la fonction dérivée, on peut utiliser la fonction <code>numderivative()</code> :


<source lang="scilab">
<syntaxhighlight lang="scilab">
function [y] = fonction(x)
function [y] = fonction(x)
y = x.*x + 5*sin(x);
y = x.*x + 5*sin(x);
Ligne 72 : Ligne 72 :
plot(xopt, fopt, "k+");
plot(xopt, fopt, "k+");


</syntaxhighlight>
</source>


== Optimisation linéaire ==
== Optimisation linéaire ==
Ligne 86 : Ligne 86 :


La syntaxe la plus simple permet de résoudre le problème sur la frontière du polyèdre, donc avec des égalités partout :
La syntaxe la plus simple permet de résoudre le problème sur la frontière du polyèdre, donc avec des égalités partout :
<source lang="scilab">
<syntaxhighlight lang="scilab">
xopt = karmarkar(Ae, be, c)
xopt = karmarkar(Ae, be, c)
</syntaxhighlight>
</source>
résout
résout
: <math>\begin{cases}
: <math>\begin{cases}
Ligne 102 : Ligne 102 :


La solution s'obtient donc par
La solution s'obtient donc par
<source lang="scilab">
<syntaxhighlight lang="scilab">
Aeq = [1, -1, 0 ; 1, 1,1];
Aeq = [1, -1, 0 ; 1, 1,1];
beq = [0 ; 2];
beq = [0 ; 2];
c = [-1 ; -1 ; 0];
c = [-1 ; -1 ; 0];
xopt = karmarkar(Aeq, beq, c)
xopt = karmarkar(Aeq, beq, c)
</syntaxhighlight>
</source>
et le résultat est :
et le résultat est :
<source lang="scilab">
<syntaxhighlight lang="scilab">
xopt =
xopt =


Ligne 115 : Ligne 115 :
0.9999949
0.9999949
0.0000102
0.0000102
</syntaxhighlight>
</source>


On peut y ajouter un système d'inéquations<ref>les cinq paramètres vides <code>[]</code> sont des paramètres que nous ne présentons pas ici à l'exception du premier, '''x<sub>0</sub>''' ci-dessous. Ils sont décrits dans la page d'aide : {{lien web | url = https://help.scilab.org/docs/6.0.0/fr_FR/karmarkar.html | titre = karmarkar: Solves a linear optimization problem. | langue = en | site = help.scilab.org | consulté le = 2017-02-13}}</ref> :
On peut y ajouter un système d'inéquations<ref>les cinq paramètres vides <code>[]</code> sont des paramètres que nous ne présentons pas ici à l'exception du premier, '''x<sub>0</sub>''' ci-dessous. Ils sont décrits dans la page d'aide : {{lien web | url = https://help.scilab.org/docs/6.0.0/fr_FR/karmarkar.html | titre = karmarkar: Solves a linear optimization problem. | langue = en | site = help.scilab.org | consulté le = 2017-02-13}}</ref> :
<source lang="scilab">
<syntaxhighlight lang="scilab">
xopt = karmarkar(Ae, be, c, [], [], [], [], [], Ai, bi)
xopt = karmarkar(Ae, be, c, [], [], [], [], [], Ai, bi)
</syntaxhighlight>
</source>
résout
résout
: <math>\begin{cases}
: <math>\begin{cases}
Ligne 128 : Ligne 128 :
\end{cases}</math>
\end{cases}</math>
et si l'on n'a que des inéquations :
et si l'on n'a que des inéquations :
<source lang="scilab">
<syntaxhighlight lang="scilab">
xopt = karmarkar([], [], c, [], [], [], [], [], Ai, bi)
xopt = karmarkar([], [], c, [], [], [], [], [], Ai, bi)
</syntaxhighlight>
</source>
résout
résout
: <math>\begin{cases}
: <math>\begin{cases}
Ligne 138 : Ligne 138 :


On peut indiquer un vecteur de départ '''x<sub>0</sub>''' :
On peut indiquer un vecteur de départ '''x<sub>0</sub>''' :
<source lang="scilab">
<syntaxhighlight lang="scilab">
xopt = karmarkar(A, b, c, x0)
xopt = karmarkar(A, b, c, x0)
xopt = karmarkar(A, b, c, x0, [], [], [], [], Ai, bi)
xopt = karmarkar(A, b, c, x0, [], [], [], [], Ai, bi)
xopt = karmarkar([], [], c, x0, [], [], [], [], Ai, bi)
xopt = karmarkar([], [], c, x0, [], [], [], [], Ai, bi)
</syntaxhighlight>
</source>
et l'on peut demander de calculer la valeur de ƒ('''x<sub>opt</sub>''') :
et l'on peut demander de calculer la valeur de ƒ('''x<sub>opt</sub>''') :
<source lang="scilab">
<syntaxhighlight lang="scilab">
[xopt,fopt] = karmarkar(…)
[xopt,fopt] = karmarkar(…)
</syntaxhighlight>
</source>


; Voir aussi
; Voir aussi
Ligne 175 : Ligne 175 :


La commande <code>qpsolve</code>, sous la forme :
La commande <code>qpsolve</code>, sous la forme :
<source lang="scilab">
<syntaxhighlight lang="scilab">
[x] = qpsolve(Q, p, C, b, ci, cs, me)
[x] = qpsolve(Q, p, C, b, ci, cs, me)
</syntaxhighlight>
</source>
utilise la fonction Fortran <code>qpgen1.f</code> (également appelée <code>QP.solve.f</code>), developpée par Berwin A. Turlach selon l'algorithme de Goldfarb/Idnani.
utilise la fonction Fortran <code>qpgen1.f</code> (également appelée <code>QP.solve.f</code>), developpée par Berwin A. Turlach selon l'algorithme de Goldfarb/Idnani.


Ligne 185 : Ligne 185 :


La commande <code>qld</code>, sous la forme :
La commande <code>qld</code>, sous la forme :
<source lang="scilab">
<syntaxhighlight lang="scilab">
[x, lagr] = qld(Q, p, C, b, ci, cs, me)
[x, lagr] = qld(Q, p, C, b, ci, cs, me)
</syntaxhighlight>
</source>
utilise la méthode de Powell modifiée par Schittkowski.
utilise la méthode de Powell modifiée par Schittkowski.



Version actuelle du 16 avril 2020 à 09:59

Table des matièresIndex



Optimisation d'une fonction


Soit une fonction ƒ de . L'optimisation consiste à trouver le vecteur x (vecteur à n composantes) donnant la valeur minimale de ƒ.

Optimisation non linéaire[modifier | modifier le wikicode]

L'optimisation non linéaire est le cas général. On utilise pour cela la fonction optim :

[fopt, xopt] = optim(costf, x0)

  • costf est la « fonction de coût » de ƒ ; c'est une fonction qui renvoit la valeur de la fonction ƒ en x et le gradient de ƒ en x, défini sous la forme
    function [f, g, ind] = costf(x, ind)
    f désigne ƒ(x), g est le gradient et ind est un index, un entier permettant de modifier le comportement de costf ;
  • x0 est une estimation de la solution ;
  • xopt est le vecteur trouvé ;
  • fopt = ƒ(xopt), valeur estimée du minimum.

On peut indiquer des bornes inférieures et supérieure de x, sous al forme de vecteurs xinf et xsup :

[fopt, xopt] = optim(f, x0, "b", xinf, xsup)

La fonction optim() est une méthode de quasi-Newton utilisant les critères de Wolfe.

Par exemple :

Minimum de la fonction pseudo-convexe différentiable avec scilab.
function [f, g, ind] = cout(x, ind)
    f = x.*x + 5*sin(x);
    g = 2*x + 5*cos(x);
endfunction

n = 40;
x = linspace(-2*%pi, 2*%pi, n);
y = cout(x);

x0 = 0;

[fopt, xopt] = optim(cout, x0);

plot(x, y);
plot(xopt, fopt, "k+");

Si l'on ne connaît pas de forme analytique de la fonction dérivée, on peut utiliser la fonction numderivative() :

function [y] = fonction(x)
    y = x.*x + 5*sin(x);
endfunction


function [f, g, ind] = cout(x, ind)
    f = fonction(x);
    g = numderivative(fonction, x);
endfunction

n = 40;
x = linspace(-2*%pi, 2*%pi, n);
y = cout(x);

x0 = 0;

[fopt, xopt] = optim(cout, x0);

plot(x, y);
plot(xopt, fopt, "k+");

Optimisation linéaire[modifier | modifier le wikicode]

La fonction ƒ est une application linéaire ; elle peut donc s'écrire :

c est un vecteur de et ct est sa transposée. On peut par ailleurs restreindre le domaine de recherche à un polyèdre convexe décrit par m inéquations :

  • A est une matrice m×n ;
  • b est un vecteur de m dimensions.

Scilab dispose de la commande karmarkar() qui permet de résoudre le problème avec l'algorithme de Karmarkar.

La syntaxe la plus simple permet de résoudre le problème sur la frontière du polyèdre, donc avec des égalités partout :

xopt = karmarkar(Ae, be, c)

résout

Exemple

Si l'on veut minimiser la fonction ƒ(x1, x2, x3) = –x1x2 avec pour contraintes x1x2 = 0 et x1 + x2 + x2 = 2, on a :

La solution s'obtient donc par

Aeq = [1, -1, 0 ; 1, 1,1];
beq = [0 ; 2];
c = [-1 ; -1 ; 0];
xopt = karmarkar(Aeq, beq, c)

et le résultat est :

xopt  = 

   0.9999949
   0.9999949
   0.0000102

On peut y ajouter un système d'inéquations[1] :

xopt = karmarkar(Ae, be, c, [], [], [], [], [], Ai, bi)

résout

et si l'on n'a que des inéquations :

xopt = karmarkar([], [], c, [], [], [], [], [], Ai, bi)

résout

On peut indiquer un vecteur de départ x0 :

xopt = karmarkar(A, b, c, x0)
xopt = karmarkar(A, b, c, x0, [], [], [], [], Ai, bi)
xopt = karmarkar([], [], c, x0, [], [], [], [], Ai, bi)

et l'on peut demander de calculer la valeur de ƒ(xopt) :

[xopt,fopt] = karmarkar()
Voir aussi

Optimisation quadratique[modifier | modifier le wikicode]

Soit ƒ une fonction quadratique de n variables (xi)1 ≤ in, c'est-à-dire une combinaison linéaire de xixj. Cette fonction peut se décrire par deux matrices, Q, définie positive de dimension n×n, et p, matrice colonne de dimension n :

si l'on appelle x la matrice colonne [x1 ; x2 ; … ; xn]
ƒ(x1, …, xn) = ½txQx + tpx
tM est la transposée de la matrice M.

L'optimisation quadratique consiste à trouver le vecteur x donnant la valeur minimum de ƒ, en imposant de plus que la solution se trouve dans un espace convexe, ce qui se traduit par m contraintes linéaires : me conditions d'égalité

1 ≤ jnCijxj = bi, 1 ≤ ime

et m - me conditions d'inégalité

1 ≤ jnDijxjdi, 1 ≤ im - me

soit sous forme matricielle

C1x = b1
C2xb2

  • C1 est une matrice me×n ;
  • b1 est une matrice colonne de dimension me ;
  • C2 est une matrice (m - men ;
  • b2 est une matrice colonne de dimension (m - me).

On rassemble les matrices :

  • C = [C1 ; C2] ;
  • b = [b1 ; b2].

Pour résoudre un tel système, Scilab propose deux commandes.

La commande qpsolve, sous la forme :

[x] = qpsolve(Q, p, C, b, ci, cs, me)

utilise la fonction Fortran qpgen1.f (également appelée QP.solve.f), developpée par Berwin A. Turlach selon l'algorithme de Goldfarb/Idnani.

Les paramètres ci et cs sont des vecteurs colonne de dimension n contenant les limites inférieures et supérieures aux valeurs des xi

cixcs.

Si l'on n'impose pas de limite, on utilise des matrices vides [].

La commande qld, sous la forme :

[x, lagr] = qld(Q, p, C, b, ci, cs, me)

utilise la méthode de Powell modifiée par Schittkowski.

La variable lagr est un vecteur de multiplicateurs lagrangiens.

Notes[modifier | modifier le wikicode]

  1. les cinq paramètres vides [] sont des paramètres que nous ne présentons pas ici à l'exception du premier, x0 ci-dessous. Ils sont décrits dans la page d'aide : (en) « karmarkar: Solves a linear optimization problem. », sur help.scilab.org (consulté le 13 février 2017)

Résolution d'équations < > Matrices creuses