Noli, thanks for the confirmation.
I have attached my initial attempt (schedule.mod). As described in that file:
/***
aim: to allocate patients to linear accelerators for treatment.
patients may require linacs with certain capabilities.
patients may prefer to avoid certain times of the day.
each patient needs to be scheduled on exactly one linac (with sufficient capabilities)
a linac can only be used by up to one person at a time.
each linac only operates during a certain window during the day.
where not all patients' time preferences can be met, preference should be given to those with more flexibility
***/This runs, but I am not convinced I have specified everything correctly. In particular, I notice that the 'badness' value is nonzero for patients even where they have not provided a blackout window. ie: I believe no s.t. constraint requires them to go above zero.
Could it be that I am seeing a nonzero "badness" because my "patient" param is a number, rather than a reference to a specific member of a set?
For completeness, I have also attached a simple python file I whipped up which wraps the schedule and allows me to dynamically inject data. (the existing python libraries I saw are bitrotting, so I am wrapping the commandline tool at least for now). If I increase the number of patients (line 150 of parse.py) significantly, glpsol takes a long time and ultimately thinks it cannot find a solution, even though I believe it should be possible. My suspicion is that the "badness" calculation above is close to the root cause.
For anyone who takes pity on me and has the time to help, I would be interested in knowing whether my general approach is sound. I was not sure how to best represent the fact that each patient needs exactly one session on one machine: my approach of having a time on each machine (x) coupled with a binary flag to indicate whether this is valid (lp) feels like a hack.