Пример #1
0
def test_check_stability():
    """ Test that StudentAllocation can recognise whether a matching is stable
    or not. """

    students = [Student("A"), Student("B"), Student("C")]
    projects = [Project("P", 2), Project("Q", 2)]
    supervisors = [Supervisor("X", 2), Supervisor("Y", 2)]

    a, b, c = students
    p, q = projects
    x, y = supervisors

    p.set_supervisor(x)
    q.set_supervisor(y)

    a.set_prefs([p, q])
    b.set_prefs([q])
    c.set_prefs([q, p])

    x.set_prefs([c, a])
    y.set_prefs([a, b, c])

    game = StudentAllocation(students, projects, supervisors)

    matching = game.solve()
    assert game.check_stability()

    matching[p] = [c]
    matching[q] = [a, b]

    assert not game.check_stability()
Пример #2
0
def _make_instances(
    student_prefs,
    project_supervisors,
    project_capacities,
    supervisor_capacities,
):
    """Create ``Player``, ``Project`` and ``Supervisor`` instances for the
    names in each dictionary."""

    student_dict, project_dict, supervisor_dict = {}, {}, {}

    for student_name in student_prefs:
        student = Student(name=student_name)
        student_dict[student_name] = student

    for project_name, supervisor_name in project_supervisors.items():
        capacity = project_capacities[project_name]
        project = Project(name=project_name, capacity=capacity)
        project_dict[project_name] = project

    for supervisor_name, capacity in supervisor_capacities.items():
        supervisor = Supervisor(name=supervisor_name, capacity=capacity)
        supervisor_dict[supervisor_name] = supervisor

    for project_name, supervisor_name in project_supervisors.items():
        project = project_dict[project_name]
        supervisor = supervisor_dict[supervisor_name]
        project.set_supervisor(supervisor)

    return student_dict, project_dict, supervisor_dict
Пример #3
0
def test_unmatch(name, capacity, pref_names):
    """Check that a project can break a matching with a student, and break that
    matching for their supervisor member, too."""

    project = Project(name, capacity)
    supervisor = Supervisor("foo", capacity)
    project.supervisor = supervisor
    students = [Student(student) for student in pref_names]

    project.matching = students
    supervisor.matching = students
    for i, student in enumerate(students[:-1]):
        project._unmatch(student)
        assert project.matching == students[i + 1:]
        assert supervisor.matching == students[i + 1:]

    project._unmatch(students[-1])
    assert project.matching == []
    assert supervisor.matching == []
Пример #4
0
def test_match(name, capacity, pref_names):
    """Check that a project can match to a student, and match its supervisor to
    them, too."""

    project = Project(name, capacity)
    supervisor = Supervisor("foo", capacity)
    project.supervisor = supervisor
    students = [Student(student) for student in pref_names]

    project.prefs = students
    supervisor.prefs = students
    for i, student in enumerate(students[:-1]):
        project._match(student)
        assert project.matching == students[:i + 1]
        assert supervisor.matching == students[:i + 1]

    project._match(students[-1])
    assert project.matching == students
    assert supervisor.matching == students
Пример #5
0
def test_set_supervisor(name, capacity):
    """Check that a project can update its supervisor member and that it is added
    to the supervisor's project list."""

    project = Project(name, capacity)
    supervisor = Supervisor("foo", capacity)

    project.set_supervisor(supervisor)
    assert project.supervisor == supervisor
    assert supervisor.projects == [project]
Пример #6
0
def test_set_prefs(name, capacity, pref_names):
    """ Test that a Supervisor can set its preferences correctly, and the
    preferences of its project(s). """

    supervisor = Supervisor(name, capacity)
    projects = [Project(i, capacity) for i in range(3)]
    students = []
    for sname in pref_names:
        student = Student(sname)
        student.prefs = projects
        students.append(student)

    supervisor.projects = projects
    supervisor.set_prefs(students)
    assert supervisor.prefs == students
    assert supervisor.pref_names == pref_names
    for project in supervisor.projects:
        assert project.prefs == students
        assert project.pref_names == pref_names
Пример #7
0
def test_init(name, capacity):
    """Make an instance of Supervisor and check their attributes are correct."""

    supervisor = Supervisor(name, capacity)

    assert supervisor.name == name
    assert supervisor.capacity == capacity
    assert supervisor.projects == []
    assert supervisor.prefs == []
    assert supervisor.matching == []
    assert supervisor._pref_names == []
    assert supervisor._original_prefs is None
Пример #8
0
def make_players(student_names, project_names, supervisor_names, capacities):
    """ Given some names and capacities, make a set of players for SA. """

    students = [Student(name) for name in student_names]
    projects = [
        Project(name, cap) for name, cap in zip(project_names, capacities)
    ]
    supervisors = [Supervisor(name, capacity=None) for name in supervisor_names]

    if len(students) > len(projects):
        students = students[: len(projects)]

    for project in projects:
        project.set_supervisor(np.random.choice(supervisors))

    supervisors = [
        supervisor for supervisor in supervisors if supervisor.projects
    ]
    for supervisor in supervisors:
        capacities = sorted([proj.capacity for proj in supervisor.projects])
        min_cap, max_cap = max(capacities), sum(capacities)
        supervisor.capacity = np.random.randint(min_cap, max_cap + 1)

    possible_prefs = get_possible_prefs(projects)
    logged_prefs = {supervisor: [] for supervisor in supervisors}
    for student in students:
        prefs = possible_prefs[np.random.choice(range(len(possible_prefs)))]
        student.set_prefs(prefs)
        for project in prefs:
            supervisor = project.supervisor
            if student not in logged_prefs[supervisor]:
                logged_prefs[supervisor].append(student)

    for supervisor, studs in logged_prefs.items():
        supervisor.set_prefs(np.random.permutation(studs).tolist())

    projects = [p for p in projects if p.prefs]
    supervisors = [f for f in supervisors if f.prefs]

    return students, projects, supervisors