Search code examples
c++algorithmc++11grouping

Grouping Algorithm for Temperature Range [Revised]


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?


Solution

  • 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.