Note that this is a more detailed version of a previous, closed question.
I have a scenario where I have N
items (N
is a large number), and each item has a minimum allowable temperature (min_temp
) and a maximum allowable temperature (max_temp
).
I need to find a setpoint temperature that maximizes the number of items where that setpoint is between their min_temp
and max_temp
values. Ideally, it finds the value that also gives the greatest buffer between the setpoint and the closest min/max value of the compatible items (i.e. the safest setpoint in case of fluctuations).
A brute-force approach would be to loop through possible temperatures at a certain step size, such as:
float best_temp;
size_t best_num_items = 0;
for(float t = -60; t < 100; t += 0.1) {
size_t num_items = 0;
for(auto item: items) {
if(t >= item.min_temp && t <= item.max_temp) {
num_items++;
}
}
if(num_items > best_num_items) {
best_num_items = num_items;
best_temp = t;
}
}
This would give me the best setpoint, but (a) it's obviously wildly inefficient, (b) it doesn't account for finding the value with the greatest buffer as detailed above, and (c) it negates all possible values that may be between step sizes.
Is there a non-brute-force approach that I should consider for this?
The problem of choosing a set point temperature between given minimum and maximum values that maximizes the number of items for which the chosen set point falls between each item's minimum and maximum value can be modelled as an integer linear programming problem and solved with an ILP software package.
The formulation of the model follows.
Data
SPl : minimum set point temperature
SPh : maximum set point temperature
Xil : minimum temperature for item i
Xih : maximum temperature for item i
Variables
sp : a continuous variable equal to the set point
xi : = 1 if item i is selected as part of the group; else = 0
Mixed integer program
max Σixi
subject to:
sp + (SPh-Xih)xi ≤ SPh for all i
-sp + (SPl+Xil)xi ≤ SPl for all i
sp ≤ SPh
-sp ≤ -SPl
Note that the first two groups of constraints are derived from the following, respectively.
sp ≤ Xihxi + SPh(1-xi)
which reduces to:
sp ≤ Xih if xi = 1
sp ≤ SPh if xi = 0
Similarly,
sp ≥ Xilxi - SPl(1-xi)
which reduces to:
sp ≥ Xil if xi = 1
sp ≥ SPl if xi = 0
See @havish's answer here for an example of using an ILP solver with Python.