Find minimum consecutives in an optimvar

조회 수: 3 (최근 30일)
Julian
Julian 2023년 8월 4일
편집: Julian 2023년 9월 11일
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
Julian
Julian 2023년 9월 4일
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.

댓글을 달려면 로그인하십시오.

채택된 답변

Julian
Julian 2023년 9월 7일
편집: Julian 2023년 9월 11일
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.

추가 답변 (1개)

Matt J
Matt J 2023년 8월 4일
편집: Matt J 2023년 8월 4일
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
Julian
Julian 2023년 8월 28일
편집: Julian 2023년 8월 28일
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 2023년 8월 28일
At least it's necessary to either remove integer variables or equality constraints from your code.

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Get Started with Problem-Based Optimization and Equations에 대해 자세히 알아보기

제품


릴리스

R2023a

Community Treasure Hunt

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

Start Hunting!

Translated by