How to solve a non-linear optimization problem with matrix and vector decision variables?
조회 수: 9 (최근 30일)
이전 댓글 표시
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
채택된 답변
Torsten
2023년 2월 8일
편집: Torsten
2023년 2월 9일
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
Torsten
2023년 2월 13일
편집: Torsten
2023년 2월 13일
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);
추가 답변 (0개)
참고 항목
카테고리
Help Center 및 File Exchange에서 Linear Least Squares에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!
