Find minimum consecutives in an optimvar

3 次查看(过去 30 天)
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