How to automatically constrain some of the unknown values in an optimization problem?

Rikke (view profile)

on 20 Mar 2019
Latest activity Commented on by Rikke

on 20 Mar 2019

Torsten (view profile)

I have an optimization problem with several unknown values (x) which is a part of an array:
A=[0 0 x(1) x(2) 0 0 0 x(3) x(4) x(5) 0 0 0 x(6) 0 0 x(7) x(8)];
The x-values are to be optimized but each x-'group', which is separated by the zeros, are to be equal to each other. ex.: x(1)=x(2) and x(3)=x(4)=x(5) and so on. x(6) is not to be equal to another x because it is not in a 'group' with other x's, therfore x(6) will not be constrained.
I am supposed to write this constraint as ceq(x)=[..] in a constraint function.
Is there any automatic coding that can constrain these x-values in the way i explained?

Torsten (view profile)

on 20 Mar 2019

If you know in advance which elements of the x-vector are grouped together, you can simply use Aeq and beq to define the equality constraints. No need to use the nonlinear constraints option in ceq.

Rikke

Rikke (view profile)

on 20 Mar 2019
Thanks for your respond! I know which one is grouped together, but it will be time consuming because I actually have an array of 1740 elements with 55 of them as the unknown x-values. And I want the optimization model to work with any kind of array not only the one I have for the moment.
Matt J

Matt J (view profile)

on 20 Mar 2019
@Rikke,
How are the groupings of the 55 unknowns specified as input? Do you have some sort of binary map?

on 20 Mar 2019
Edited by Matt J

Matt J (view profile)

on 20 Mar 2019

I will assume you have some binary vector v which indicates the groupings of the variables, so for example this,
[0 0 x(1) x(2) 0 0 0 x(3) x(4) x(5) 0 0 0 x(6) 0 0 x(7) x(8)];
would be input as the vector
v=[0 0 1 1 0 0 0 1 1 1 0 0 0 1 0 0 1 1];
Then you can construct the linear equality constraint matrices Aeq, beq as follows
Aeq=diff(speye(numel(v)) ,1,1);
Aeq(:,~v)=[];
beq=zeros(size(Aeq,1),1);

Matt J

Matt J (view profile)

on 20 Mar 2019
For the 8-variable example that you posted, this should result in
>> full(Aeq), full(beq).'
ans =
-1 1 0 0 0 0 0 0
0 0 -1 1 0 0 0 0
0 0 0 -1 1 0 0 0
0 0 0 0 0 0 -1 1
ans =
0 0 0 0
indicating that the first two unknowns will be equal, the next 3 unknowns will be equal and the final two unknowns will be equal.
Rikke

Rikke (view profile)

on 20 Mar 2019
Thank you so much Matt J, it worked!