How should five undergrads split their week, when each of them wants something different out of college, and each of them is influenced by their friends?
This is a course project for ME308 at IIT Bombay (Group 40, "Team Optimistic"). Full write-up in docs/Presentation.pdf; the original experiment notebook is docs/notebook.ipynb.
Each student allocates hours per week across ten activities:
acads, sports, research, pors, tech_team, tech_club, nc_club, cult, leisure, sleep
Five students means 50 decision variables. Each student is optimising their own goals, and the goals conflict, so there is no single best schedule: the output is a Pareto front.
| Student | Optimising for |
|---|---|
| 0 | job |
| 1 | gradstudy |
| 2 | health |
| 3 | social |
| 4 | explore, social |
Six objectives in total. Every objective is scaled by a Gaussian on sleep
centred at 49 hours per week, so both too little and too much sleep hurt every
goal. health uses a tighter variance, so it is punished hardest for bad sleep.
Seven constraints per student:
total weekly hours <= 168 sleep >= 35
total weekly hours >= 120 leisure >= 10
18 <= acads <= 54 pors + tech_team + tech_club + nc_club <= 50
The part that makes this multi-agent rather than five separate problems: each student's effective allocation is blended with their neighbours' in a weighted influence graph, so what your friends do changes what your own schedule is worth.
0 <-> 4 sigma = 0.10 1 <-> 4 sigma = 0.01
1 <-> 2 sigma = 0.05 2 <-> 3 sigma = 0.07
1 <-> 3 sigma = 0.08 3 <-> 4 sigma = 0.01
Three blending rules were studied, where sigma is the edge weight and lambda a decision variable:
| Method | Rule | Behaviour |
|---|---|---|
| 1 | l_i <- l_i + sigma * l_j |
Unbounded. Effective hours grow without limit as neighbours are added, so objectives improve just by having more friends. Rejected. |
| 2 | l_i <- l_i + sigma * (l_j - l_i) |
Moves a fraction of the way toward the neighbour. Stays within the convex hull. |
| 3 | l_i <- (l_i + sigma * l_j) / (1 + sigma) |
Weighted average. Also bounded. |
Methods 2 and 3 are the two compared seriously. tests/test_moma.py asserts
the boundedness property, and that method 1 diverges under repeated application.
- NSGA-II (via
pymoo) over the 50-variable space, with non-dominated sorting, crowding-distance diversity preservation and elitism. - Selection from the front. A Pareto front is not an answer, so two
methods reduce it to one schedule:
- TOPSIS, ranking by closeness to the ideal point. Returns a real member of the front.
- MaxHist, the alternative proposed in this project: for each decision variable independently, take its most frequent value across the front. This assembles a vector coordinate by coordinate, so unlike TOPSIS the result need not itself lie on the front. That is the tradeoff.
Influence method 2 vs. 3, 120 generations, population 300, seed 1, TOPSIS pick. Values are the objectives being maximised (higher is better):
| Influence | s0 job | s1 gradstudy | s2 health | s3 social | s4 explore | s4 social |
|---|---|---|---|---|---|---|
| Method 2 | 27889.7 | 9482.1 | 193.4 | 2753.9 | 10871.7 | 484.4 |
| Method 3 | 26151.4 | 9820.4 | 269.2 | 910.1 | 6166.8 | 3438.2 |
The two rules do not merely rescale each other. Method 2 pushes student 3's
social and student 4's explore far higher; method 3 redistributes toward
health and student 4's social. Which is "better" depends on whose objective
you privilege, which is exactly why the front is kept rather than collapsed
early.
Reproduce with:
python examples/run_experiment.py --generations 120 --pop-size 300 --influence-method 3The report's headline runs used population 1000 and 350 generations.
The presentation also covers the effect of generation count (150 vs. 1000),
TOPSIS vs. MaxHist head to head, scaling to 15 objectives by giving every
student three or four goals, the isolated effect of influence on students 1
and 3, and a sensitivity analysis on the influence weights (sigma_25 = 0.020
vs. 0.022). Those live in docs/ rather than as scripts here.
pip install -r requirements.txt
pip install -e .
python examples/run_experiment.py # optimise, then TOPSIS and MaxHist picks
python tests/test_moma.py # model wiring checksfrom moma import Student, default_graph, run_optimization, topsis
from moma.objectives import job, gradstudy, health, social, explore
students = [Student(0, [job]), Student(1, [gradstudy]), Student(2, [health]),
Student(3, [social]), Student(4, [explore, social])]
res = run_optimization(students, default_graph(), generations=350, pop_size=1000)
best = res.X[topsis(res.F)] # 50 hours-per-week valuesmoma/
agents.py Student: an id, its objectives, and its ten activity values
objectives.py job, gradstudy, health, social, explore
influence.py weighted influence graph and the three blending rules
problem.py CollegeLife: the pymoo Problem (objectives + constraints)
optimization.py NSGA-II driver
selection.py TOPSIS and MaxHist
examples/ runnable five-student experiment
tests/ model wiring and blending-rule checks
docs/ presentation and original notebook
The original notebook aliased the student object while applying influence, so
the constraints were evaluated on the post-influence values rather than on
each student's own declared allocation. CollegeLife reproduces that by
default (constraints_on="influenced") so the notebook's results stay
reproducible, and constraints_on="raw" applies them to the raw allocation,
which is what the formulation in the report describes.
The difference is not cosmetic. Over a 120-generation, population-300 run:
constraints_on |
raw weekly totals | min acads | min sleep | min leisure |
|---|---|---|---|---|
"influenced" (notebook default) |
114.1 to 173.4 | 15.5 | 35.1 | 9.9 |
"raw" (report formulation) |
120.4 to 168.0 | 18.0 | 35.0 | 10.0 |
| required | 120 to 168 | >= 18 | >= 35 | >= 10 |
So under the notebook's default a returned schedule can breach the stated
limits on a student's own time, because the constraint was satisfied by the
blended vector instead. Use constraints_on="raw" if you want the printed
schedule itself to be feasible.
- Objectives are cooperative only. Genuinely competitive goals, where one student gaining means another losing, are not modelled.
- Results depend on generation count in two directions: too few and a good gene may never appear by mutation; too many and the population saturates and diversity collapses.
- The objective functions are hand-designed quadratics, not fitted to data. The framework is the contribution, not the specific coefficients.
MIT. See LICENSE.