AI / Optimization / Full-Stack

AI and Optimization-Based Timetable Scheduler

Automated timetable generation for six engineering batches

Hook & Introduction

As team lead, I took on the challenge of automating a process that was previously done manually — building a system to generate conflict-free, optimized timetables for the Faculty of Engineering, University of Ruhuna. Working under the guidance of Dr. Kushan as our academic client, our team set out to construct a robust, scalable system to replace days of manual planning with minutes of mathematical execution.


Background & Theory

The scheduling problem was modeled as a Constraint Satisfaction Problem (CSP) / Integer Linear Program (ILP). We defined a binary decision variable:

$$x_{c, t, r, i} \in {0, 1}$$

representing whether a given course session c is assigned to a particular time slot t, room r, and instructor i.

We specified 9 hard constraints that must never be violated, including:

  1. No instructor double-bookings (an instructor cannot teach two sessions at the same time).
  2. No room double-bookings (a room cannot host two classes simultaneously).
  3. Student batch availability (a student cohort cannot attend two sessions concurrently).
  4. Room capacity constraints (the room must fit the enrolled student size).
  5. Fixed lab durations and consecutive slots.

We also defined 5 soft constraints combined into a weighted objective function to optimize:

  1. Minimizing gaps in student daily schedules (avoiding long idle hours).
  2. Balancing daily course load (no single day is overloaded).
  3. Preferred teaching slots for instructors.
  4. Consecutive lectures for the same course.
  5. Minimizing room changes for consecutive classes of the same student cohort.

Database Design

Before writing solver logic, we designed a complete relational schema to model every entity the constraints depend on. This went beyond a simple courses-and-rooms table: lecturers and students can each register individual time-slot preferences and unavailability (including one-off dates, not just recurring weekly patterns), halls carry their own equipment and capacity metadata, and every constraint itself is stored as configurable data in a CONSTRAINT_RULE table rather than hardcoded into the algorithm.

The schema centers on a few key relationships:

  • Faculty → Department → Batch → Module, modeling the academic hierarchy each timetable is generated for
  • Hall and Lecturer, each with their own unavailability tables (HALL_UNAVAILABILITY, LECTURER_UNAVAILABILITY) supporting both recurring and specific-date exceptions
  • Lecturer Preference and Student Preference, letting individual scheduling preferences feed into the soft-constraint objective rather than being hardcoded assumptions
  • Timetable → Timetable Entry, the actual generated schedule, linked back to batch, module, hall, and time slot
  • Generation Log, recording each solver run’s algorithm used, iteration count, fitness score, conflicts resolved, and duration — giving us a way to track and compare solver performance over time as we tune the model

Designing this schema before writing solver code forced us to be explicit about every constraint source up front, rather than discovering missing data mid-implementation.


Design & Implementation

Before jumping into code, I walked through the constraint formulations manually with my team using a backtracking exercise on a miniature grid. This visual grounding was crucial before translating the mathematical model into code using Google OR-Tools’ CP-SAT solver in Python.

The system architecture separates the optimization engine from the rest of the application:

  • Frontend: An Angular dashboard for administrators to configure batches, modules, lecturers, and halls, and trigger schedule generation directly from the browser.
  • Backend: Spring Boot API that orchestrates the data flow, manages metadata, and triggers the solver.
  • Optimization Engine: A Python microservice that consumes the database snapshot, invokes Google OR-Tools, and returns the optimized schedule.
  • Database: MySQL, modeling the full schema described above.

The Angular dashboard lets an administrator select a student intake batch, manage its module list (code, name, weekly hours, lecture count), assign lecturers to modules, and define hall capacity and availability windows, all before generating a timetable with a single click.

Timetable Optimizer dashboard interface Figure 1 — The Timetable Optimizer dashboard: batch selection, module schedule, lecturer assignment, and hall configuration

The repository was organized into clear modules:

  • /backend (Spring Boot API)
  • /frontend (Angular application)
  • /database (Migration scripts and schemas)
  • /algorithm (Python OR-Tools optimization logic)
  • /docs (Technical documentation and API schemas)

Entity-relationship diagram of the timetable scheduling database Figure 2 — Entity-relationship diagram covering the academic hierarchy, constraint configuration, preferences, and generation logging

Early in the project, we encountered a direct-to-main commit conflict that disrupted the build. I resolved this by establishing branch protection rules and a clean PR review workflow, setting up a Git branching strategy that allowed our 4-person team to commit concurrently without code overlap.


Challenges & Debugging

Coordinating a 4-person team across backend, frontend, and algorithm work while ensuring the constraint model accurately captured real faculty scheduling rules (drawn from real batch timetable data) required multiple rounds of constraint refinement. Grounding our data schemas on historical scheduling files revealed edge cases where multiple batches merged for elective courses, prompting updates to the decision variables.

Designing the preference and unavailability tables also surfaced a subtlety we hadn’t initially planned for: unavailability needed to support both recurring weekly patterns (a lecturer who never teaches Friday afternoons) and one-off date exceptions (a hall closed for a single day), which meant extending the schema rather than treating availability as a simple boolean.


Results & Impact

We’re currently in active testing of the solver engine. The Spring Boot backend, Angular frontend, and database schema are integrated and functional, and the optimization engine is being tuned against real constraint data. We’re holding off on publishing solve-time and conflict-resolution figures until we have results from a full semester’s dataset, since early test numbers wouldn’t be representative of real-world performance.


What I’d Improve Next

Complete remaining sprints and validate the optimizer against a full semester’s real scheduling data. In the future, we hope to explore genetic algorithms as an alternative solver to compare solve-times and output quality for larger-scale constraints.