Flera, lite besvärligare, bivillkor

Följande exempel kommer inte från en föreläsning och det är inkluderat bara för att visa hur man kan vara tvungen att formulera om sitt problem och hur man paketerar flera bivillkor.

Problem:
Låt f(x1, x2) = 0.4 sin(3 x1 x2 + x2) + 1. Minimera f(x1, x2)(x1, x2) tillhör området som ges av |x1| + |x2| <= 1 och |x2| <= x1^2.

Steg 1: karakterisera objektfunktion och bivillkor
Objektfunktionen är ickelinjär. Vi får samma minimipunkt (men inte samma minvärde) med sin(3 x1 x2 + x2), men vi behåller ursprungsformuleringen (0.4 och 1 är valda så att plotten skall bli snygg). Bivillkoren liknar inte de i våra föregående exempel. Vi vill avlägsna beloppen eftersom de ger hörn. I dokumentationen för fmincon står nämligen:

fmincon is a gradient-based method that is designed to work on problems where the objective and constraint functions are both continuous and have continuous first derivatives. function with continuous first and second derivatives because the algorithm uses gradient-based methods.

Steg 2: skriv objektfunktion och bivillkor på standardform
Objektfunktionen är redan på standardform. Bivillkoren kräver lite arbete dock. En av övningarna i Adams går ut på att rita mängden som definieras av |x1| + |x2| <= 1, och det visar sig bli en roterad kvadrat med kantlinjer x1 + x2 = 1, -x1 + x2 = 1, -x1 - x2 = 1 samt x1 - x2 = 1. Efter lite tänkande ser man att villkoren blir:

  x1 + x2 <= 1
 -x1 + x2 <= 1
 -x1 - x2 <= 1
  x1 - x2 <= 1

De ickelinjära villkoren kan vi skriva som två villkor x2 <= x1^2 och -x2 <= x1^2. Standardformen lyder c(x) <= 0, där c är en funktion som definierar ett bivillkor, så i vårt fall:

-x1^2 + x2 <= 0
-x1^2 - x2 <= 0

Steg 3: förpackning; vi inför de vektorer och matriser som behövs för att definiera objektfunktion och bivillkor
Vi inför först x som vektorn som lagrar variablerna, x1 och x2.

Olikhetsbivillkoren definieras av en matris A och en kolonnvektor B, där A * x <= B, en rad per bivillkor. Matrisen A har fyra rader (fyra bivillkor) och två kolonner (två variabler) och ser ut som följer:


[
1
1
]


[
1
]
A =
[
-1
1
]
   
B =
[
1
]

[
-1
-1
]


[
1
]

[
1
-1
]


[
1
]


Det ickelinjära bivillkoret definieras via en funktion, precis som i föregående exempel, [in_eq, eq] = constr_fun(x). Skillnaden är att vi nu har olikhetsbivillkor och dessutom två stycken. Vi returnerar avvikelserna som en kolonnvektor.

in_eq = [-x(1)^2+x(2); -x(1)^2-x(2)];

Eftersom vi inte har något likhetsbivillkor sätter vi eq till en tom variabel []. Om vi hade flera likhetsbivillkor hade vi analogt returnerat en vektor av avvikelser från bivillkoren.

Steg 4: skriv Matlabkoden
Jag har valt att lägga de tre rutinerna i en fil .

function ex3

A    = [1 1; -1 1; -1 -1; 1 -1]; % fyra linjära olikhetsbivillkor
B    = [1; 1; 1; 1];

A_eq = [];                       % inget linjärt likhetsbivillkor
B_eq = [];

LB   = [];                       % inga enkla gränser
UB   = [];

x_guess = [-0.1; 0.6];

[x_opt, obj_val] = fmincon(@obj_fun, x_guess, A, B,  A_eq, B_eq, LB, UB, @constr_fun)

function obj_val = obj_fun(x)
obj_val = 0.4 * sin(3 * x(1) * x(2) + x(2)) + 1;

function [in_eq, eq] = constr_fun(x)
in_eq = [-x(1)^2 - x(2); -x(1)^2 + x(2)];  % ickelinjära olikhetsbivillkor
eq    = [];                                % inget ickelinjärt likhetsbivillkor



Följande bild visar några av problemets egenskaper. De tunna linjerna i x1-x2-planet visar randen till |x1| + |x2| <= 1 och de streckade linjerna visar analogt randen för |x2| <= x1^2. De tjocka linjerna visar randen för D, det område vi minimerar över. Beroende på var man startar hittar rutinen olika punkter. Om vi startar i den röda kvadraten hamnar vi i den punkt som markerats med en röd stolpe (jag har dragit upp stolpen till ytan, så att man enklare skall se var på ytan man hamnar). Notera att punkten ligger på randen (utan bivillkor hade vi inte haft lokalt minimum här). Analogt för de andra kvadraterna.

Ex3



Back