Problem 177193 · hard · Level 01 Prerequisites & Setup

Design the Thermostat

on/off control · hysteresis · trade-off · noise · lag

Now you are the thermostat. A hidden room is simulated minute by minute for 12 hours, and every minute the simulator calls your function

controller(temperature, setpoint, heater_on) -> bool

with the thermometer's reading (°C), the desired temperature, and whether the 3 kW heater is on right now. Return True to have the heater on for the next minute and False to have it off.

What you are up against:

  • the room leaks heat to the outside with a time constant of 100 minutes, or 60 minutes while a window is open (two to four times a day, for 5 to 25 minutes);
  • the outside temperature drifts slowly over the day, somewhere between about −1 and 12 °C;
  • the heater lags: its output takes about 3 minutes to rise after you switch it on and to die away after you switch it off, so the room keeps warming for a while after you turn it off;
  • the thermometer is noisy: each reading is the true temperature plus a random error of a few hundredths of a degree, rounded to 0.01 °C;
  • the room starts cold, so the first 90 minutes are a warm-up that is not judged.

Each test calls run_room(controller, seed) (it is defined for you, so you can try it with Run), which returns a summary of the 630 judged minutes, for example

{"setpoint": 19.5, "minutes_outside_band": 0, "rms_error": 0.094933,
 "switches_per_hour": 27.238095, "worst_error": 0.2957}

for the naive lambda temperature, setpoint, heater_on: temperature < setpoint on seed 1. Your function may remember values between calls in a global variable (for example the previous reading); run_room gives no signal when a new room starts, so make sure stale values only matter for a minute or two.

How this problem is scored

  • A test passes when the room stays within setpoint ± 1 °C for every judged minute.
  • Its quality is 100 - 100 * rms_error - 2 * switches_per_hour (at least 0), where rms_error is the root-mean-square difference between the room and the setpoint over the judged minutes: every 0.1 °C of typical error costs 10 points, and every switch per hour costs 2 points, for the wear it puts on the heater.
  • The naive controller above passes seed 1 but scores only 36: the noise makes it switch 27 times an hour. Comfort and few switches pull in opposite directions; the best controllers find a good balance.

Constraints

  • return a bool (or a value that is clearly true or false); None counts as off
  • the result must not depend on the clock; each call should take well under a millisecond

Goals

  • Write a feedback controller that is called once per time step by a simulator
  • Keep a room inside a comfort band despite noise, lag, open windows and changing weather
  • Balance comfort against wear on the heater
Starting Python…