Quantum Annealing-based Meeting Scheduler
Find the best meeting time across a weekly timetable using SA / QA (D‑Wave).
🌐 Live Demo: https://eyedicamp.github.io/SuperPosition/frontend/
- 🗓️ Build / upload a weekly timetable (Mon–Sun)
- 🧩 Set meeting length + preference window
- ⚖️ Add attendee weights (important people matter more)
- 🚀 Run optimization:
- 🧊 SA (Simulated Annealing,
dwave-neal) - ⚛️ QA (Quantum Annealing on D‑Wave QPU)
- 🧊 SA (Simulated Annealing,
- 🥇 Get the best start time + Top‑K candidates with a visual timetable overlay
.
├─ index.html # redirects to /frontend
├─ backend/
│ ├─ app.py
│ ├─ Dockerfile
│ └─ requirements.txt
└─ frontend/
├─ index.html
├─ app.js
├─ styles.css
├─ timetable.html
└─ timetable.js
- 🎛️ Main UI:
frontend/index.html - 🧾 Timetable viewer:
frontend/timetable.html - ↪️ Redirect: root
index.html
backend/requirements.txt includes (high-level):
- ⚡
fastapi,uvicorn[standard],pydantic - 🧊
dwave-neal(SA) - ⚛️
dwave-system(QA / D‑Wave)
Header:
slot_minutes,person_id,weight,day,time,available,pref
day:Mon,Tue,Wed,Thu,Fri,Sat,Suntime:HH:MMavailable: 1 / 0pref: 1 / 0 (preference start-slot hint)
This project can solve the “best meeting start time” problem via QUBO (Quadratic Unconstrained Binary Optimization), which is the standard form used by quantum annealers (and also by many classical annealing solvers).
Let the week be discretized into fixed-size slots (e.g., 30 minutes). Define:
- Total number of slots:
$T$ - Meeting length in slots:
$L$ (e.g., 180 minutes with 30-min slots$\Rightarrow L=6$ ) - Candidate meeting start slots:
$s \in {0,1,\dots,T-L}$
We use a one-hot binary vector over start times:
where:
-
$x_s = 1$ means “the meeting starts at slot$s$ ” - exactly one start time must be chosen
For each person
- Weight (importance):
$w_i \ge 0$ - Slot-level availability:
$a_{i,t}\in{0,1}$ for each slot$t$ - Start preference indicator:
$p_{i,s}\in{0,1}$ for each start$s$ (UI:pref_start_ok)
A person can attend a meeting starting at
So
Late-time overlap penalty:
- Late threshold slot index:
$t_{\text{late}}$ (derived fromlate_hour) - Number of late slots overlapped by a meeting starting at
$s$ :
For each candidate start
where:
-
$\beta$ ispref_bonus -
$\rho$ islate_penalty_per_slot
Interpretation:
- Weighted attendance rewards selecting a slot where high-weight people can attend the full meeting.
- Preference bonus adds extra value when the selected start aligns with attendee start-time preferences.
- Late penalty discourages solutions that overlap “late hours”.
The “exactly one” requirement is encoded as a squared penalty:
This equals 0 only when exactly one
Quantum annealers minimize energy. We therefore maximize
-
$\lambda>0$ is a penalty coefficient large enough to enforce feasibility.
Expanding the squared term yields a standard QUBO with linear and quadratic coefficients:
So the QUBO matrix
- Diagonal (linear) terms:
$Q_{s,s} = -W_s - \lambda$ - Off-diagonal (quadratic) terms for
$s<t$ :$Q_{s,t} = 2\lambda$
To guarantee feasibility (exactly one start),
In practice,
- 🧁 Frontend: GitHub Pages (root redirects →
/frontend) - 🛠️ Backend: Render / Fly.io / any FastAPI hosting
- 🔗 In the UI, set “Backend API Base URL” to your deployed backend URL
