Filter löschen
Filter löschen

Find minimum consecutives in an optimvar

3 Ansichten (letzte 30 Tage)
Julian
Julian am 4 Aug. 2023
Bearbeitet: Julian am 11 Sep. 2023
I try to "find" the minimum consecutives 0 or 1 in an integer optimvar.
Following a "normal logical" array, I would search for it as follows:
A = [0 0 0 1 1 0 0 1 0 1 1 1 0 0 0].';
% Find the position of the 1s
index = find(A);
% Calculate the difference between the zeros and find the indexes at wich a new block starts.
% A new Block starts at the first "index" and where the difference is bigger than 1
iStart = find([1; diff(index) >1]);
% The end of the block is always the index before the start of a new block
iEnd = [iStart(2:end)-1; size(index,1)];
% Calculate the length of the Blocks
onLength = iEnd-iStart+1;
offLength = ([index(iStart); length(A)+1] - [0; index(iEnd(1:end))] -1);
And I wanted to use this to "find" / define the minimum of a optimvar. But unfortunately this does not work, which is why I set the maximum like this:
% Define variables
prob = optimproblem;
n_max_off = 3;
N = 90;
ds_on = optimvar('ds_on', N, 'LowerBound',0, 'UpperBound', 1, 'Type','integer');
prob.Constraints.ds_max_off = optimconstr(N-n_max_off);
% The sum of the maximum +1 must be more the 1
% For more than the maximum, at least one element must be true.
for i = 1:N-n_max_off-1
prob.Constraints.ds_max_off(i) = sum(ds_on(i:i+n_max_off+1)) >= 1;
end
% Compressed code without loop
index = (0:n_max_off) + (1:N-n_max_off).';
prob.Constraints.ds_max_off(1:N-n_max_off) = sum(ds_on(index(1:N-n_max_off,:)),2) >= 1;
But to define the minimum I do not know how I can do it.
In other words:
I want to define a minimum and maximum length of zeros and ones which are my boundary conditions / constraints.
The maximum is not a problem, but to define the minimum length is my problem. So minimum and maximum length are my constraints.
My objective is someting different I left for readability.
  1 Kommentar
Julian
Julian am 4 Sep. 2023
I have found and already implemented a way to formulate the minimum number of a runtime linearly.
From the paper: "A computationally efficient mixed-integer linear formulation for the thermal unit commitment problem"
I plan to post the solution in the near future.

Melden Sie sich an, um zu kommentieren.

Akzeptierte Antwort

Julian
Julian am 7 Sep. 2023
Bearbeitet: Julian am 11 Sep. 2023
The best solution is to formulate the minimum number of consecutives with a linear approach like in the paper: "A computationally efficient mixed-integer linear formulation for the thermal unit commitment problem" DOI: 10.1109/TPWRS.2006.876672
At first define the variable:
% Define variables
prob = optimproblem;
n_min_off = 4;
n_max_off = 10;
n_min_on = 2;
n_max_on = 3;
N = 90;
I use two optimvars:
ds_on = optimvar('ds_on', N, 'LowerBound',0, 'UpperBound', 1, 'Type','integer');
ds_start = optimvar('ds_start', N, 'LowerBound',0, 'UpperBound', 1, 'Type','integer');
The maximum of the consecutives is like I implemented it in the question:
% Compressed code without loop
index = (0:n_max_off) + (1:N-n_max_off).';
prob.Constraints.ds_max_off = sum(ds_on(index(1:N-n_max_off,:)),2) >= 1;
% the same for maximum on
%...
I search for the start but in the end I musst not forget to give "ds_start" a little weight in my minimization function:
prob.Constraints.ds_start = diff(ds_on) <= ds_start(2:end);
Afterwards I say, after "ds_start" is 1, the following "ds_on"s musst be on too:
for i = 2:N-n_min_on+1:
prob.Constraints.min_off(i) = ds_start(i) * n_min_on - sum(ds_on(i:i+n_min_on-1)) <= 0;
end
% of faster:
index = (1:n_min_on) + (1:N-n_min_on).';
prob.Constraints.min_on = ds_start(2:N-n_min_on+1) * n_min_on - sum(ds_on(index),2) <=0;
And it's very siilar for "min_off":
for i = n_min_off+1:N
prob.Constraints.min_off(i) = ds_start(i) * n_min_on + sum(ds_on(i-n_min_on:i-1)) <= n_min_on;
end
% or faster:
index = (0:n_min_off-1) + (1:N-n_min_off).';
prob.Constraints.min_off = ds_start(1:N-n_min_off) * n_min_off + sum(ds_on(index),2) <= n_min_off;
With this calculation I'm able to define a minimum on and off time for a appliance in an optimization.
I am also able to make it multidemensional if I have more appliances of this kind.
With this workaround it is also possible to have different kinds of "on" values.

Weitere Antworten (1)

Matt J
Matt J am 4 Aug. 2023
Bearbeitet: Matt J am 4 Aug. 2023
It's going to be a nonlinear integer objective function, which means the solver it's going to choose is ga. You should save yourself the hassle and just implement the optimization with ga() directly.
  15 Kommentare
Julian
Julian am 28 Aug. 2023
Bearbeitet: Julian am 28 Aug. 2023
I changed it to <= instead of == and it is calculating. I hope it will calculate faster, but I have still the question what kind of "problem" is better for Matlab to calculate?
Torsten
Torsten am 28 Aug. 2023
At least it's necessary to either remove integer variables or equality constraints from your code.

Melden Sie sich an, um zu kommentieren.

Produkte


Version

R2023a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by