I am working through this discrete optimization problem that I've defined as an exercise. It is scheduling classes against one classroom.
https://github.com/thomasnield/optimized-scheduling-demo
I've been using ojAlgo which has worked great when I modeled correctly.
However, I have structured this problem into discrete binaries of 15 minute blocks. So if I have a $1$ hour class, that would require $4$ blocks which would grab four boolean values for those blocks and turn them to $1$.
This worked fine until I tried to make the needed blocks for a class contiguous, as I don't want to grab blocks that are scattered throughout the day.
For a class session that requires $4$ blocks, here is a fail and success case. The failed case has four $1$'s scattered throughout the day. The success (desired) case has four contiguous $1$'s.
+--------+---------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
| | Result | 01:00 | 01:15 | 01:30 | 01:45 | 02:00 | 02:15 | 02:30 | 02:45 | 03:00 |
+--------+---------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
| Case 1 | FAIL | 1 | 0 | 1 | 1 | 0 | 0 | 1 | 0 | 0 |
| Case 2 | SUCCESS | 0 | 0 | 1 | 1 | 1 | 1 | 0 | 0 | 0 |
+--------+---------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
So how do I mathematically express this? I reasoned that (for a class that needs four blocks), I can break the case into rolling groups of $4 $ blocks like this:
+--------+--------+---------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
| | Result | | 01:00 | 01:15 | 01:30 | 01:45 | 02:00 | 02:15 | 02:30 | 02:45 | 03:00 |
+--------+--------+---------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
| Case 1 | | | 1 | 0 | 1 | 1 | 0 | 0 | 1 | 0 | 0 |
| | 0 | Group 1 | 1 | 0 | 1 | 1 | | | | | |
| | 0 | Group 2 | | 0 | 1 | 1 | 0 | | | | |
| | 0 | Group 3 | | | 1 | 1 | 0 | 0 | | | |
| | 0 | Group 4 | | | | 1 | 0 | 0 | 1 | | |
| | 0 | Group 5 | | | | | 0 | 0 | 1 | 0 | |
| | 0 | Group 6 | | | | | | 0 | 1 | 0 | 0 |
+--------+--------+---------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
+--------+--------+---------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
| | Result | | 01:00 | 01:15 | 01:30 | 01:45 | 02:00 | 02:15 | 02:30 | 02:45 | 03:00 |
+--------+--------+---------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
| Case 2 | | | 0 | 0 | 1 | 1 | 1 | 1 | 0 | 0 | 0 |
| | 0 | Group 1 | 0 | 0 | 1 | 1 | | | | | |
| | 0 | Group 2 | | 0 | 1 | 1 | 1 | | | | |
| | 1 | Group 3 | | | 1 | 1 | 1 | 1 | | | |
| | 0 | Group 4 | | | | 1 | 1 | 1 | 0 | | |
| | 0 | Group 5 | | | | | 1 | 1 | 0 | 0 | |
| | 0 | Group 6 | | | | | | 1 | 0 | 0 | 0 |
+--------+--------+---------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
Note above I have each group with a desired result of $1$ or $0$. So if I can express each group with this function:
$$x_n = occupation\ binary$$ $$m = blocks\ needed$$ $$\delta_\shared\in \{0,1\}$$ $$x_1 + x_2 + .. + x_n - m\delta >= 0$$
I can express each grouping as a 1 or 0 effectively, indicating a contiguous grouping of needed size exists or not. For the case as a whole to be valid, the sum of all "Result" values must be 1 indicating a consecutive grouping of the needed size exists (as shown in Case 2). Otherwise it will sum to 0 (as in Case 1). $$\delta_1 + \delta_2 + ... + \delta_n = 1$$
However, putting this equation into ojAlgo ends up churning forever. I'm wondering if maybe this isn't the right way to model this. Can someone help me reason if I'm doing something wrong with my thought process?