Exemplo n.º 1
0
def test_check_stability():
    """Test that HospitalResident can recognise whether a matching is stable or
    not."""

    residents = [Resident("A"), Resident("B"), Resident("C")]
    hospitals = [Hospital("X", 2), Hospital("Y", 2)]

    (a, b, c), (x, y) = residents, hospitals

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

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

    game = HospitalResident(residents, hospitals)

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

    (a, b, c), (x, y) = game.residents, game.hospitals
    matching[x] = [c]
    matching[y] = [a, b]

    assert not game.check_stability()
Exemplo n.º 2
0
def test_example_in_issue():
    """ Verify that the matching found is consistent with the example in #67.
    """

    group_prefs = {
        "Group 1": ["Intellectual property", "Privacy"],
        "Group 2": ["Privacy", "Fairness in AI"],
        "Group 3": ["Privacy", "Social media"],
    }

    topic_hospital_prefs = {
        "Fairness in AI": ["Group 2"],
        "Intellectual property": ["Group 1"],
        "Privacy": ["Group 3", "Group 2", "Group 1"],
        "Social media": ["Group 3"],
    }

    capacities = {t: 2 for t in topic_hospital_prefs}

    game = HospitalResident.create_from_dictionaries(
        group_prefs, topic_hospital_prefs, capacities
    )
    (G1, G2, G3), (F, I, P, S) = game.residents, game.hospitals

    matching = game.solve()
    assert matching == {I: [G1], P: [G3, G2], F: [], S: []}
Exemplo n.º 3
0
def test_readme_example():
    """ Verify the example used in the repo README. """

    resident_prefs = {
        "A": ["C"],
        "S": ["C", "M"],
        "D": ["C", "M", "G"],
        "J": ["C", "G", "M"],
        "L": ["M", "C", "G"],
    }

    hospital_prefs = {
        "M": ["D", "L", "S", "J"],
        "C": ["D", "A", "S", "L", "J"],
        "G": ["D", "J", "L"],
    }

    capacities = {hosp: 2 for hosp in hospital_prefs}

    game = HospitalResident.create_from_dictionaries(
        resident_prefs, hospital_prefs, capacities
    )
    (A, S, D, J, L), (M, C, G) = game.residents, game.hospitals

    matching = game.solve()
    assert matching == {M: [L, S], C: [D, A], G: [J]}
Exemplo n.º 4
0
def fuzzy_matching(identifier: Tuple, pdf: pd.DataFrame):
    # Default recusion limit of 1000 causes the deepcopy in
    # HospitalResident.create_from_dictionaries to fail for particularly
    # large inputs.
    (identifier,) = identifier
    identifier = str(identifier)  # instead of np.str
    sys.setrecursionlimit(10000)
    audio_preferences = defaultdict(list)
    text_preferences = defaultdict(list)
    for row in pdf.itertuples():
        audio_preferences[row.audio_document_id].append(
            (row.levenshtein, row.text_document_id)
        )
        text_preferences[row.text_document_id].append(
            (row.levenshtein, row.audio_document_id)
        )
    # tuples are sorted lexicographically, so by levenshtein distance first
    for k, v in audio_preferences.items():
        audio_preferences[k] = [text_id for _score, text_id in sorted(v)]
    for k, v in text_preferences.items():
        text_preferences[k] = [audio_id for _score, audio_id in sorted(v)]
    # problem = StableMarriage.create_from_dictionaries(audio_preferences, text_preferences)

    more_audio_files = len(audio_preferences) > len(text_preferences)
    if more_audio_files:
        resident_preferences = audio_preferences
        hospital_preferences = text_preferences
    else:
        resident_preferences = text_preferences
        hospital_preferences = audio_preferences
    hospital_capacities = {k: 1 for k in hospital_preferences.keys()}

    try:
        problem = HospitalResident.create_from_dictionaries(
            resident_preferences, hospital_preferences, hospital_capacities
        )
    except RecursionError:
        print("GALVEZ:problem=", identifier[0])
        pprint.pprint("GALVEZ:residents:")
        pprint.pprint(resident_preferences)
        pprint.pprint("GALVEZ:hospitals:")
        pprint.pprint(hospital_preferences)
        raise
    pairs = problem.solve(optimal="hospital")

    pdf_dict = {"identifier": [], "audio_document_id": [], "text_document_id": []}
    for hospital_id, (resident_id,) in pairs.items():
        if more_audio_files:
            audio_id = resident_id
            text_id = hospital_id
        else:
            audio_id = hospital_id
            text_id = resident_id
        pdf_dict["identifier"].append(identifier)
        pdf_dict["audio_document_id"].append(audio_id.name)
        pdf_dict["text_document_id"].append(text_id.name)

    return pd.DataFrame(pdf_dict)
Exemplo n.º 5
0
def make_game(resident_names, hospital_names, capacities, seed, clean):
    """ Make all of the residents and hospitals, and the match itself. """

    np.random.seed(seed)
    residents, hospitals = make_players(resident_names, hospital_names,
                                        capacities)
    game = HospitalResident(residents, hospitals, clean)

    return residents, hospitals, game
Exemplo n.º 6
0
def test_resident_loses_all_preferences():
    """ An example that forces a resident to be removed from the game as all of
    their preferences have been forgotten. """

    resident_prefs = {"A": ["X"], "B": ["X", "Y"]}
    hospital_prefs = {"X": ["B", "A"], "Y": ["B"]}
    capacities = {"X": 1, "Y": 1}

    game = HospitalResident.create_from_dictionaries(
        resident_prefs, hospital_prefs, capacities
    )
    (A, B), (X, Y) = game.residents, game.hospitals

    matching = game.solve()
    assert matching == {X: [B], Y: []}
Exemplo n.º 7
0
def combinate_users_with_respect_interests_and_history(users, clear_history,
                                                       userdata_this_time):
    user_prefs = {}
    user_for_interests = {}
    for user in users:
        user_prefs[user] = userdata_this_time[user]['interests']
        for interest in userdata_this_time[user]['interests']:
            if interest not in user_for_interests.keys():
                user_for_interests[interest] = []
            user_for_interests[interest].append(user)
    capacities = {hosp: 2 for hosp in user_for_interests}
    game = HospitalResident.create_from_dictionaries(user_prefs,
                                                     user_for_interests,
                                                     capacities)
    pairs_by_interests = [
        tuple(x) for x in game.solve(optimal="hospital").values()
        if len(tuple(x)) == 2
    ]
    combinations_without_history = set(pairs_by_interests) - set(clear_history)
    return combinations_without_history
Exemplo n.º 8
0
def test_init(players, clean):
    """Test that an instance of HospitalResident is created correctly when
    passed a set of players."""

    residents, hospitals = players

    game = HospitalResident(residents, hospitals, clean)

    for resident, game_resident in zip(residents, game.residents):
        assert resident.name == game_resident.name
        assert resident._pref_names == game_resident._pref_names

    for hospital, game_hospital in zip(hospitals, game.hospitals):
        assert hospital.name == game_hospital.name
        assert hospital._pref_names == game_hospital._pref_names
        assert hospital.capacity == game_hospital.capacity

    assert all([resident.matching is None for resident in game.residents])
    assert all([hospital.matching == [] for hospital in game.hospitals])
    assert game.matching is None
Exemplo n.º 9
0
def test_create_from_dictionaries(connections, clean):
    """Test that HospitalResident is created correctly when passed a set of
    dictionaries for each party."""

    resident_prefs, hospital_prefs, capacities = connections

    game = HospitalResident.create_from_dictionaries(resident_prefs,
                                                     hospital_prefs,
                                                     capacities, clean)

    for resident in game.residents:
        assert resident._pref_names == resident_prefs[resident.name]
        assert resident.matching is None

    for hospital in game.hospitals:
        assert hospital._pref_names == hospital_prefs[hospital.name]
        assert hospital.capacity == capacities[hospital.name]
        assert hospital.matching == []

    assert game.matching is None
    assert game.clean is clean
def random_experience(num_residents, num_hospitals):
    np.random.seed()

    uniform_capacity = int(num_residents / num_hospitals) + 1

    resident_prefs = {
        r: np.argsort(np.random.random(size=num_hospitals))
        for r in range(num_residents)
    }

    hospital_prefs = {
        h: np.argsort(np.random.random(size=num_residents))
        for h in range(num_hospitals)
    }

    capacities = {h: num_hospitals for h in hospital_prefs}
    capacities = {h: uniform_capacity for h in hospital_prefs}
    game = HospitalResident.create_from_dictionaries(resident_prefs,
                                                     hospital_prefs,
                                                     capacities)
    _ = game.solve()
    return game, resident_prefs
Exemplo n.º 11
0
def test_create_from_dictionaries(resident_names, hospital_names, capacities,
                                  seed):
    """ Test that HospitalResident is created correctly when passed a set of
    dictionaries for each party. """

    resident_prefs, hospital_prefs = make_prefs(resident_names, hospital_names,
                                                seed)

    capacities_ = dict(zip(hospital_names, capacities))
    game = HospitalResident.create_from_dictionaries(resident_prefs,
                                                     hospital_prefs,
                                                     capacities_)

    for resident in game.residents:
        assert resident.pref_names == resident_prefs[resident.name]
        assert resident.matching is None

    for hospital in game.hospitals:
        assert hospital.pref_names == hospital_prefs[hospital.name]
        assert hospital.capacity == capacities_[hospital.name]
        assert hospital.matching == []

    assert game.matching is None
    df_sorted = df_wiki_2.sort_values(by=['entity_wiki2_id', 'dist'],
                                      ascending=True)
    df_sorted = df_sorted.reset_index(drop=True)
    df_sorted = df_sorted[['entity_wiki2_id', 'entity_wiki1_id']]
    #results = df_sorted.groupby(['entity_wiki2_id'])['entity_wiki1_id'].apply(list)
    #df_results = pd.DataFrame(results)
    #dict_of_women = df_results.to_dict()['entity_wiki1_id']
    dict_of_women = df_sorted.groupby(
        ['entity_wiki2_id'])['entity_wiki1_id'].apply(list).to_dict()

    print('*********Preparing Dictionary for Women Done**********')
    print('Data Preparation Done,  running algo . . . . ')
    capacities = {women: 1 for women in dict_of_women}
    #capacities = {women: 1 for women in dict_of_women}

    game = HospitalResident.create_from_dictionaries(dict_of_men,
                                                     dict_of_women, capacities)

    result = game.solve()

    def get_name(x):
        return entities[x.name]  #entities[x.name]


    #print(entities[437])
    #print(entities[292])

    with open(COR_FOLDER + '/' + MODEL + '/' + file + '.csv',
              'w+',
              encoding='utf-8') as stable_marriage_op:
        stable_marriage_op.write("entity_id_wiki_2,entity_id_wiki_1\n")
        for key in result:
def run_pairing(mentors, learners, requested_pairings_learners,
                requested_pairings_mentors):

    learners_left = list(learners.keys())
    #mentors_left = list(mentors.keys())
    once_more = True

    pairings = []

    while once_more:
        if len(learners) < len(mentors):
            once_more = False

        learner_prefs = {}
        # check for if no matches after contraints satisfied, then soften constraint (allow more mentors?)
        for learner_id, learner in learners.items():
            #if learner.get_id() == "*****@*****.**":
            is_requested = False
            if learner_id in requested_pairings_learners:
                is_requested = True
                #print("jlund requested " + requested_pairings_mentors[requested_pairings_learners.index(learner_id)])
                learner.set_preferences(
                    mentors, requested_pairings_mentors[
                        requested_pairings_learners.index(learner_id)])
            else:
                learner.set_preferences(mentors)
            lprefs = learner.get_preferences()

            if len(lprefs) == 0:
                #rerun with softened contraints
                pairings.append(
                    Pair(learner=learner, is_requested=is_requested))
                learners_left.remove(learner_id)
                print("learner " + learner_id +
                      " has no matching preferences.")
                continue
            # put learner prefs into dictionary for matching
            learner_prefs[learner_id] = learner.get_ranked_mentors()

        mentor_prefs = {}
        for mentor_id, mentor in mentors.items():
            #if learner.get_id() == "*****@*****.**":
            # get all learners in learner_prefs that have mentor in their values list
            subscribed_learner_ids = [
                k for k, v in learner_prefs.items() if mentor_id in v
            ]
            subscribed_learners = {
                id: learners[id]
                for id in subscribed_learner_ids
            }

            is_requested = False
            if mentor_id in requested_pairings_mentors:
                is_requested = True
                mentor.set_preferences_subscribed(
                    subscribed_learners, requested_pairings_learners[
                        requested_pairings_mentors.index(mentor_id)])
            else:
                mentor.set_preferences_subscribed(subscribed_learners)
            mprefs = mentor.get_preferences()
            if len(mprefs) == 0:
                #rerun with softened contraints
                #pairings.append(Pair(mentor=mentor))
                print("mentor " + mentor.get_id() +
                      " has no matching preferences.")
                continue
            # put learner prefs into dictionary for matching
            mentor_prefs[mentor.get_id()] = mentor.get_ranked_learners()

        capacities = {m: 1 for m in mentor_prefs}
        game = HospitalResident.create_from_dictionaries(
            learner_prefs, mentor_prefs, capacities)
        matching = game.solve()

        for k, v in matching.items():
            if len(v) > 0:
                if k.name in requested_pairings_learners or v[
                        0].name in requested_pairings_learners:
                    pairings.append(
                        Pair(mentor=mentors[k.name],
                             learner=learners[v[0].name],
                             is_requested=True))
                else:
                    pairings.append(
                        Pair(mentor=mentors[k.name],
                             learner=learners[
                                 v[0].name]))  # assumes capacity is 1
                learners_left.remove(v[0].name)
            #else:
            #  pairings.append(Pair(mentor=mentors[k.name]))

        # list unpaired learners
        learners = {k: learners[k] for k in learners_left}

    return pairings
Exemplo n.º 14
0
    def generate(self):
        # create the specialties 
        list_of_specialties = []
        for i in range(0, self.n_specialties):
            list_of_specialties.append(Specialty(i))
            
        # create the programs 
        list_of_programs = []    
        for i in range(0, self.n_specialties):
            specialty = list_of_specialties[i]
            for j in range(0, self.n_programs_per_specialty):
                list_of_programs.append(Program(i*self.n_programs_per_specialty + j,
                                                specialty, self.n_interviews_per_spot))

        # create the probability distribution applicant specialty selection 
        list_specialty_spots_distribution = []
        for specialty in list_of_specialties:
            n_spots = 0
            for program in list_of_programs:
                if program._specialty == specialty:
                    n_spots += program._spots
            list_specialty_spots_distribution.append(n_spots)
        total_spots = int(np.sum(list_specialty_spots_distribution))
        list_specialty_spots_distribution = np.array(list_specialty_spots_distribution)
        list_specialty_spots_distribution = [x + np.abs(np.random.normal(0, x*self.specialty_choice_stddev_multiplier)) 
                                             for x in list_specialty_spots_distribution]
        list_specialty_spots_distribution = [np.max(x, 0) for x in list_specialty_spots_distribution]
        list_specialty_spots_distribution = list_specialty_spots_distribution / np.sum(list_specialty_spots_distribution)
        # create the applicants 
        list_of_applicants = []
        n_applicants = total_spots
        for i in range(0, n_applicants):
            list_of_applicants.append(Applicant(i, list_specialty_spots_distribution, 
                                                self.n_specialties, self.n_spec_per_applicant, 
                                                self.n_programs_per_specialty))

        # assign the programs to which the applicants applied
        for i in range(0, n_applicants):
            applicant = list_of_applicants[i]
            list_of_specialties_to_which_applicant_applied = applicant._specialties_id
            programs_applied = []
            for specialty in list_of_specialties_to_which_applicant_applied:
                programs_applied += find_all_programs_for_specialty(list_of_programs, specialty)
            applicant._programs_to_which_applied = programs_applied
            for program_index in programs_applied:
                program = list_of_programs[program_index]
                program._list_of_applicants.append(applicant._id)
        
        # assign the applicants who received interviews
        for i in range(0, self.n_programs):
            program = list_of_programs[i]
            applicants_to_program = program._list_of_applicants
            interview_spots = program._spots * self.n_interviews_per_spot
            if len(applicants_to_program) < interview_spots:
                interviewed_applicants = applicants_to_program
            else:
                interviewed_applicants = np.random.choice(applicants_to_program, 
                                                  size=(interview_spots), 
                                                  replace=False)
            program._list_of_interviewees = interviewed_applicants
            for applicant_index in interviewed_applicants:
                try:
                    applicant = list_of_applicants[applicant_index]
                    applicant._programs_at_which_interviewed.append(program._id)
                except TypeError:
                    pdb.set_trace()
        # create the applicants' rank lists
        for applicant in list_of_applicants:
            rank_list = deepcopy(applicant._programs_at_which_interviewed)
            np.random.shuffle(rank_list)
            applicant._applicant_rank_list = rank_list
        # create the programs' rank lists
        for program in list_of_programs:
            rank_list = deepcopy(program._list_of_interviewees)
            np.random.shuffle(rank_list)
            program._rank_of_applicants_list = rank_list
        applicant_prefs = {applicant._id: applicant._applicant_rank_list for applicant in list_of_applicants}
        applicants_without_interviews = []
        for key in applicant_prefs.keys():       
            applicant_pref = applicant_prefs[key]
            if len(applicant_pref) == 0:
                applicants_without_interviews.append(key)                
        for applicant in applicants_without_interviews:
            del applicant_prefs[applicant]
        applicant_prefs_keys = list(applicant_prefs.keys())
        for key in applicant_prefs_keys:
            applicant_prefs['applicant'+str(key)] = ['program'+str(x) for x in applicant_prefs[key]]
            del applicant_prefs[key]        
        program_prefs = {program._id: program._rank_of_applicants_list for program in list_of_programs}
        program_prefs_keys = list(program_prefs.keys())
        for key in program_prefs_keys:
            program_prefs['program'+str(key)] = ['applicant'+str(x) for x in program_prefs[key]]
            del program_prefs[key]
        capacities = {'program'+str(program._id): program._spots for program in list_of_programs}
        game = HospitalResident.create_from_dictionaries(applicant_prefs, program_prefs, capacities)
        result = game.solve()    
        num_applicants = len(list_of_applicants)
        number_matched = sum_all_matched_applicants(result)
        number_unmatched = len(list_of_applicants) - number_matched
        match_rate = number_matched/len(list_of_applicants)
        unfilled_spots = find_all_unfilled_spots(result, list_of_programs)
        n_applicants_no_interviews = len(applicants_without_interviews)
        return {'num_applicants': num_applicants,
                'fraction_applicants_no_interviews':n_applicants_no_interviews/num_applicants, 
                'match_rate':match_rate}
Exemplo n.º 15
0
from reader import Reader

operation = sys.argv[1]

# insert path of doctors excel below
r = Reader("Projektprioritäten für Challengezuteilung(1-60).xlsx")

DOCTORS = None
HOSPITAL_PREFS = None

if operation == "candidates":
	""" reads doctors excel and writes new excel with candidates per hospital """

	r.read_doctors()


elif operation == "matching":
	DOCTORS = r.read_doctors()
	HOSPITAL_PREFS = r.read_hospital_prefs()

	capacities = r.read_hospital_capacities()

	game = HospitalResident.create_from_dictionaries(
		DOCTORS, HOSPITAL_PREFS, capacities
	)
	result = game.solve()

	turned = r.turn_dict(result)
	df_result = pd.DataFrame(turned, index=[0]).T
	df_result.to_excel("matching_result.xlsx")
Exemplo n.º 16
0
def games(draw, clean=booleans(), **kwargs):
    """ A custom strategy for making a game instance. """

    residents, hospitals = draw(players(**kwargs))
    return HospitalResident(residents, hospitals, clean)