mirror of https://gitlab.crans.org/bde/nk20
[WEI] Extreme test with full buses and quality constraints
Signed-off-by: Yohann D'ANELLO <ynerant@crans.org>
This commit is contained in:
parent
451851c955
commit
74ab4df9fe
|
@ -53,7 +53,8 @@ class WEIBusInformation:
|
|||
def free_seats(self, surveys: List["WEISurvey"] = None):
|
||||
size = self.bus.size
|
||||
already_occupied = WEIMembership.objects.filter(bus=self.bus).count()
|
||||
valid_surveys = sum(1 for survey in surveys if survey.information.valid) if surveys else 0
|
||||
valid_surveys = sum(1 for survey in surveys if survey.information.valid
|
||||
and survey.information.get_selected_bus() == self.bus) if surveys else 0
|
||||
return size - already_occupied - valid_surveys
|
||||
|
||||
def has_free_seats(self, surveys=None):
|
||||
|
|
|
@ -190,6 +190,9 @@ class WEISurveyAlgorithm2021(WEISurveyAlgorithm):
|
|||
# If it does not exist, choose the next bus.
|
||||
least_preferred_survey.free()
|
||||
least_preferred_survey.save()
|
||||
free_surveys.append(least_preferred_survey)
|
||||
survey.select_bus(bus)
|
||||
survey.save()
|
||||
break
|
||||
else:
|
||||
raise ValueError(f"User {survey.registration.user} has no free seat")
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import math
|
||||
import random
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
|
@ -26,7 +27,7 @@ class TestWEIAlgorithm(TestCase):
|
|||
|
||||
self.buses = []
|
||||
for i in range(10):
|
||||
bus = Bus.objects.create(wei=self.wei, name=f"Bus {i}", size=50)
|
||||
bus = Bus.objects.create(wei=self.wei, name=f"Bus {i}", size=10)
|
||||
self.buses.append(bus)
|
||||
information = WEIBusInformation2021(bus)
|
||||
for word in WORDS:
|
||||
|
@ -39,7 +40,7 @@ class TestWEIAlgorithm(TestCase):
|
|||
There are only a few people in each bus, ensure that each person has its best bus
|
||||
"""
|
||||
# Add a few users
|
||||
for i in range(50):
|
||||
for i in range(10):
|
||||
user = User.objects.create(username=f"user{i}")
|
||||
registration = WEIRegistration.objects.create(
|
||||
user=user,
|
||||
|
@ -63,3 +64,44 @@ class TestWEIAlgorithm(TestCase):
|
|||
preferred_bus = survey.ordered_buses()[0][0]
|
||||
chosen_bus = survey.information.get_selected_bus()
|
||||
self.assertEqual(preferred_bus, chosen_bus)
|
||||
|
||||
def test_survey_algorithm_full(self):
|
||||
"""
|
||||
Buses are full of first year people, ensure that they are happy
|
||||
"""
|
||||
# Add a lot of users
|
||||
for i in range(95):
|
||||
user = User.objects.create(username=f"user{i}")
|
||||
registration = WEIRegistration.objects.create(
|
||||
user=user,
|
||||
wei=self.wei,
|
||||
first_year=True,
|
||||
birth_date='2000-01-01',
|
||||
)
|
||||
information = WEISurveyInformation2021(registration)
|
||||
for j in range(1, 21):
|
||||
setattr(information, f'word{j}', random.choice(WORDS))
|
||||
information.step = 20
|
||||
information.save(registration)
|
||||
registration.save()
|
||||
|
||||
# Run algorithm
|
||||
WEISurvey2021.get_algorithm_class()().run_algorithm()
|
||||
|
||||
penalty = 0
|
||||
# Ensure that everyone seems to be happy
|
||||
# We attribute a penalty for each user that didn't have its first choice
|
||||
# The penalty is the square of the distance between the score of the preferred bus
|
||||
# and the score of the attributed bus
|
||||
# We consider it acceptable if the mean of this distance is lower than 5 %
|
||||
for r in WEIRegistration.objects.filter(wei=self.wei).all():
|
||||
survey = WEISurvey2021(r)
|
||||
chosen_bus = survey.information.get_selected_bus()
|
||||
buses = survey.ordered_buses()
|
||||
score = min(v for bus, v in buses if bus == chosen_bus)
|
||||
max_score = buses[0][1]
|
||||
penalty += (max_score - score) ** 2
|
||||
|
||||
self.assertLessEqual(max_score - score, 20) # Always less than 20 % of tolerance
|
||||
|
||||
self.assertLessEqual(penalty / 100, 25) # Tolerance of 5 %
|
||||
|
|
Loading…
Reference in New Issue