How to solve a non-linear optimization problem with matrix and vector decision variables?
9 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
Oliver Pohl
am 8 Feb. 2023
Kommentiert: Oliver Pohl
am 14 Feb. 2023
Hey folks. I'm somewhat new to optimizations and got stuck trying to solve an optimization problem where I have two decision variables: one is a matrix and the other is a vector. While my objective function is a rather simple linear cost function, and most of my constraints are also rather easy to handle, there is one somewhat lengthy non-linear constraint that seems to cause issues.
The problem looks as follows:
In the following, capital symbols are matrices, vectors are indicated by arrows, and everything else is a scalar. Dimensions of the vectors and matrix variables are as follows:
In my specific example, the values of L and N are 39 and 46, but in other examples they may go up to several hundreds.
Objective function: minimize total costs resulting from changes in b and p
![min C = sum(b_ll * c_l) + sum(p_n * c_n), with b_ll as an element of matrix B [LxL] and p_n as an element of p [Nx1]](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1289490/image.png)
Constraints:
- Min and max allowed values for elements of DeltaB-matrix:

- All elements outside of the diagonal of DeltaB-matrix must remain zero:

- Min and max allowed values in elements of p-vector:

- Changes in p-elements must sum up to zero:

- And now the somewhat convoluted non-linear constraint which is rather difficult to explain:
Here's an MWE to showcase how I hoped to solve this using ga (I originally started with fmincon but that threw errors and recommended ga):
%% Input values
B = [ 10 -1 -2 -3 -4;...
-1 19 -5 -6 -7;...
-2 -5 24 -8 -9;...
-3 -6 -8 27 -10;...
-4 -7 -9 -10 30];
A = [ 1 -1 0 0;...
0 1 -1 0;...
0 0 1 -1;...
1 0 0 -1;...
0 1 0 -1];
p = [-60; 160; -200; 100];
L = size(B,1); % = 5
N = size(A,2); % = 4
cost_per_b = 0.01; % same for all b_ij
delta_B_min = diag(-10*ones(L,1));
delta_B_max = diag(10*ones(L,1));
delta_p_min = -5*ones(N,1);
delta_p_max = 5*ones(N,1);
m = 120*ones(L,1);
cost_per_p = 1; % same for all elements of delta_p
mstart = -B * A * (A' * B * A)^-1 * p; % to give an idea for m-ranges
%% Optimization problem
% Decision variables
delta_B = optimvar('delta_B',L,L);
delta_p = optimvar('delta_p',N,1);
% Starting points
x0.delta_B = zeros(L);
x0.delta_p = zeros(N,1);
% Constraints
delta_B.LowerBound = delta_B_min;
delta_B.UpperBound = delta_B_max;
delta_p.LowerBound = delta_p_min;
delta_p.UpperBound = delta_p_max;
pbalance_cons = sum(delta_p) == 0;
nonlincons_pos = ...
((B + delta_B) * A * (A' * (B + delta_B) * A)^(-1)) * (p + delta_p)...
<= m;
nonlincons_neg = ...
((B + delta_B) * A * (A' * (B + delta_B) * A)^(-1)) * (p + delta_p)...
>= -m;
% Objective
objective = cost_per_b*sum((delta_B(:)')) + cost_per_p*sum(delta_p');
% Create optimization problem
prob = optimproblem('Objective',objective);
prob.Constraints.pbalance = pbalance_cons;
prob.Constraints.nonlincons_pos = nonlincons_pos;
prob.Constraints.nonlincons_neg = nonlincons_neg;
opts = optimoptions('ga');
show(prob);
% Solve optimization problem
[sol,fval,exitflag,output] = solve(prob,x0,opts);
While the output of show() looks fine (imo), the last line unfortunately produces an output error:
Error using optim.internal.problemdef.ProblemImpl/solveImpl
The value of 'GlobalSolver' is invalid. GlobalSolver must be a MultiStart or GlobalSearch object.
Error in optim.problemdef.OptimizationProblem/solve
Error in mwe_optimization (line 57)
[sol,fval,exitflag,output] = solve(prob,x0,opts);
I've tried to understand how to turn this into a MultiStart or GlobalSearch but I don't quite get what makes my optimization problem so difficult for just regular ga or other solvers. Why do I need MultiStart or GlobalSearch for this? And if it is really necessary, how do I set GlobalSolver accordingly?
0 Kommentare
Akzeptierte Antwort
Torsten
am 8 Feb. 2023
Bearbeitet: Torsten
am 9 Feb. 2023
I turned deltaB into a diagonal matrix.
I changed m to 130 and it works. Are you sure a solution exists for m = 120 ?
%% Input values
B = [ 10 -1 -2 -3 -4;...
-1 19 -5 -6 -7;...
-2 -5 24 -8 -9;...
-3 -6 -8 27 -10;...
-4 -7 -9 -10 30];
A = [ 1 -1 0 0;...
0 1 -1 0;...
0 0 1 -1;...
1 0 0 -1;...
0 1 0 -1];
p = [-60; 160; -200; 100];
L = size(B,1); % = 5
N = size(A,2); % = 4
cost_per_b = 0.01; % same for all b_ij
delta_B_min = -10*ones(L,1);
delta_B_max = 10*ones(L,1);
delta_p_min = -5*ones(N,1);
delta_p_max = 5*ones(N,1);
m = 130*ones(L,1);
cost_per_p = 1; % same for all elements of delta_p
mstart = -B * A * (A' * B * A)^-1 * p % to give an idea for m-ranges
%% Optimization problem
% Decision variables
delta_B = optimvar('delta_B',L,1);
delta_p = optimvar('delta_p',N,1);
% Starting points
x0.delta_B = zeros(L,1);
x0.delta_p = zeros(N,1);
% Constraints
delta_B.LowerBound = delta_B_min;
delta_B.UpperBound = delta_B_max;
delta_p.LowerBound = delta_p_min;
delta_p.UpperBound = delta_p_max;
pbalance_cons = sum(delta_p) == 0;
nonlincons_pos = ...
((B + diag(delta_B)) * A * (A' * (B + diag(delta_B)) * A)^(-1)) * (p + delta_p)...
<= m;
nonlincons_neg = ...
((B + diag(delta_B)) * A * (A' * (B + diag(delta_B)) * A)^(-1)) * (p + delta_p)...
>= -m;
% Objective
objective = cost_per_b*sum(delta_B') + cost_per_p*sum(delta_p');
% Create optimization problem
prob = optimproblem('Objective',objective);
prob.Constraints.pbalance = pbalance_cons;
prob.Constraints.nonlincons_pos = nonlincons_pos;
prob.Constraints.nonlincons_neg = nonlincons_neg;
%opts = optimoptions('ga');
show(prob);
% Solve optimization problem
[sol,fval,exitflag,output] = solve(prob,x0);%,opts);
6 Kommentare
Torsten
am 13 Feb. 2023
Bearbeitet: Torsten
am 13 Feb. 2023
Next time you ask a question please supply a complete executable code for which the problem appears so that we don't need to puzzle together the parts in order to test a possible solution.
%% Input values
B = [ -10 0 0 0 0;...
0 -11 0 0 0;...
0 0 -12 0 0;...
0 0 0 -13 0;...
0 0 0 0 -14];
p = [1.32; -1.7; -2.0; 2.3];
A = [ 1 -1 0 0;...
0 1 -1 0;...
0 0 1 -1;...
1 0 0 -1;...
0 1 0 -1];
L = size(B,1); % = 5
N = size(A,2); % = 4
cost_per_b = 0.01; % same for all b_ij
delta_b_min = -10*ones(L,1);
delta_b_max = 10*ones(L,1);
delta_p_min = -5*ones(N,1);
delta_p_max = 5*ones(N,1);
cost_per_p = 1; % same for all elements of delta_p
mstart = -B * A * (A' * B * A)^-1 * p; % to give an idea for m-ranges
% Give the elements 1,3,4,5 some room but restrict element 2
[~,m_max_idx] = max(abs(mstart));
m = abs(mstart) * 2;
m(m_max_idx) = 0.9*abs(mstart(m_max_idx));
%% Optimization problem
% Decision variables
delta_b = optimvar('delta_b',L,1);
delta_p = optimvar('delta_p',N,1);
% Starting points
x0.delta_b = zeros(L,1);
x0.delta_p = zeros(N,1);
% Constraints
delta_b.LowerBound = delta_b_min;
delta_b.UpperBound = delta_b_max;
delta_p.LowerBound = delta_p_min;
delta_p.UpperBound = delta_p_max;
pbalance_cons = sum(delta_p) == 0;
inv(A'*(B+x0.delta_b)*A)
rank(A'*(B+x0.delta_b)*A)
nonlincons = @(x,y)abs(((B + diag(x)) * A * pinv(A' * (B + diag(x)) * A) ) * (p + y));
nonlincons = fcn2optimexpr(nonlincons,delta_b,delta_p);
nonlincons_abs = nonlincons <= m;
% Objective
objective = cost_per_b*sum(delta_b') + cost_per_p*sum(delta_p');
% Create optimization problem
prob = optimproblem('Objective',objective);
prob.Constraints.pbalance = pbalance_cons;
prob.Constraints.nonlincons_pos = nonlincons_abs;
show(prob);
% Solve optimization problem
options = optimoptions(prob);
options.MaxFunctionEvaluations = 3e4;
options.MaxIterations = 1500;
[sol,fval,exitflag,output] = solve(prob,x0,'Options',options);
Weitere Antworten (0)
Siehe auch
Kategorien
Mehr zu Linear Least Squares finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!
