Open frizensami opened 3 years ago
On the matters of bundle size and performance, I don't think it is a concern. NUS students tend to use modern browsers and relatively fast mobile phones (compared to the avg pop). What does matter, is the UX and how we teach people how to use the constraint solver. As I understand, we have someone working on UX, so I'll defer to them on this.
Sounds good! I added a WIP PR so that we can prototype quickly.
Probably the two important things out of the lot above are:
Updated the PR with the current method i have of initializing the solver in z3w.wasm
. A subset of changes:
Note: filenames are outdated, this has been simplified a bit
z3w.wasm
(Z3 Solver binary) and z3w.js
(emscripten wrapper for the wasm file)src/workers/z3Worker.ts
is a WebWorker that uses importScripts
to include z3w.js
(this is how it's used in the z3.wasm GitHub project). It is responsible for starting and running Z3, which are CPU intensive operations. It hooks onto the solver's stdout/stderr and reports those values to src/utils/z3Manager.ts
through callbackssrc/utils/z3Manager.ts
is the main utility for components to initialize and call the Z3 solver. While mostly commented out for now (just has the init workflow), it receives the timetable + constraints and handles the two-stage call procedure to the Z3 solver. worker-loader
library to import WebWorkers TLDR: usage of Z3 is controlled by
z3Manager
--> [[ Webworker boundary ]] --> z3Worker
(importing the wrapper z3w.js
) --> z3w.wasm
Just an update on this: slowly working on maximizing test coverage on all non-UI code. I just have converter.ts
to go for utils
. That will hopefully make it easier to iterate on the UI side without worrying about breakages.
This is a fairly long issue - my apologies! I hope it will provide a good base for discussion.
Is your feature request related to a problem? Please describe.
Students have many possibilities each semester when choosing lessons and modules for their timetable. This is especially difficult and time-consuming in earlier academic years.
Therefore, a feature that automatically optimizes a student's NUSMods timetable subject to their preferences might be very useful.
MVP Solution Implementation (NUS Timetable Optimizer)
Description
NUS Timetable Optimizer (GitHub link) is a standalone MVP implementation of this proposed feature. It takes as input a list of modules and a set of user-supplied constraints (e.g., free day / lunch hours / lesson start-end requirements), and outputs a timetable that meets the constraints. If optimization constraints are specified (e.g., compact the timetable as much as possible), the output timetable attempts to maximize/minimize the stated constraints. The list of possible new features are at the project's Issues page, with more to be added.
This issue aims to discuss the possibility of merging its functionality into NUSMods, and if so, to discuss the design considerations around its implementation.
Some results from MVP implementation
Prior work
390 describes a previous attempt to solve this issue, which inspired the current approach. Notable similarities are:
However, we also build upon #390. This is a short description of some of the improvements:
Integration into NUSMods
This section aims to discuss the following design points that I can think of. I can check these off and insert the conclusions as this discussion progresses:
Should / can this be integrated into NUSMods?
Ethical considerations
I and others were concerned that computing optimal timetables would upset the demand-and-supply characteristics of the module registration system. There might be excessive demand for "ideal" lesson configurations, resulting in more students ending up without classes. My thoughts:
Current infrastructure requirements
These are the two things the optimizer requires that might present deployment challenges.
This + Initializing the solver takes around 10 seconds on average.
However, I think this is the best implementation I can think of. Most serverless platforms (Cloudflare, Vercel, Netlify, AWS) have restrictions on solver runtime, so the 1 - 5 second runtime (which can be more for complex optimizations) is too much. Modern mobile and desktop devices are more than capable of running this computation, so I doubt the UX benefit of running the solver on a dedicated server platform is worth it. That option might also be prohibitively expensive.
Currently, this is deployed on a free Netlify instance, taking advantage of of the 100 GB free egress bandwidth. The app is just a statically served React bundle there.
Where should the optimizer go?
I think the most natural place is on the main timetable page, but hidden behind the beta flag. For instance:
Showing the optimizer could mean showing constraints below the existing module list (Not a front-end person, please ignore the terrible styling!):
Every time the user runs the optimizer (say it's a button above the Constraints header), the timetable is arranged. Could add a button to restore the original timetable.
Other options?:
UX Flow
What i'm envisioning:
Conclusion
I hope this issue acts as a base for discussing whether this feature is wanted, and how to implement it if so :)