试图在条件不佳的情况下使用Python为医生和医院创建匹配算法

时间:2019-01-24 12:54:15

标签: python dictionary conditional-statements list-comprehension matching

首先,我想指出的是,我是python的新秀,所以如果我的措辞或问题听起来很愚蠢,请忍受我,只是尝试学习。

我创建了两个词典,其中之一是向医院评估排名的医生,另一个是向医生评估排名的医院。 医院医生:

{'Doctor_5': {1.0: 'Hospital_7', 2.0: 'Hospital_6', 3.0: 'Hospital_8', 4.0: 'Hospital_5', 5.0: 'Hospital_9', 6.0: 'Hospital_4', 7.0: 'Hospital_10', 8.0: 'Hospital_3', 9.0: 'Hospital_2', 10.0: 'Hospital_1'}, 'Doctor_9': {1.0: 'Hospital_9', 2.0: 'Hospital_8', 3.0: 'Hospital_10', 4.0: 'Hospital_7', 5.0: 'Hospital_6', 6.0: 'Hospital_5', 7.0: 'Hospital_4', 8.0: 'Hospital_3', 9.0: 'Hospital_2', 10.0: 'Hospital_1'}, 'Doctor_8': {1.0: 'Hospital_8', 2.0: 'Hospital_9', 3.0: 'Hospital_10', 4.0: 'Hospital_7', 5.0: 'Hospital_6', 6.0: 'Hospital_5', 7.0: 'Hospital_4', 8.0: 'Hospital_3', 9.0: 'Hospital_2', 10.0: 'Hospital_1'}, 'Doctor_1': {1.0: 'Hospital_1', 2.0: 'Hospital_2', 3.0: 'Hospital_3', 4.0: 'Hospital_4', 5.0: 'Hospital_5', 6.0: 'Hospital_6', 7.0: 'Hospital_7', 8.0: 'Hospital_8', 9.0: 'Hospital_9', 10.0: 'Hospital_10'}, 'Doctor_4': {1.0: 'Hospital_5', 2.0: 'Hospital_6', 3.0: 'Hospital_4', 4.0: 'Hospital_7', 5.0: 'Hospital_3', 6.0: 'Hospital_2', 7.0: 'Hospital_1', 8.0: 'Hospital_8', 9.0: 'Hospital_9', 10.0: 'Hospital_10'}, 'Doctor_3': {1.0: 'Hospital_4', 2.0: 'Hospital_3', 3.0: 'Hospital_2', 4.0: 'Hospital_1', 5.0: 'Hospital_5', 6.0: 'Hospital_6', 7.0: 'Hospital_7', 8.0: 'Hospital_8', 9.0: 'Hospital_9', 10.0: 'Hospital_10'}, 'Doctor_6': {1.0: 'Hospital_7', 2.0: 'Hospital_8', 3.0: 'Hospital_6', 4.0: 'Hospital_9', 5.0: 'Hospital_5', 6.0: 'Hospital_10', 7.0: 'Hospital_4', 8.0: 'Hospital_3', 9.0: 'Hospital_2', 10.0: 'Hospital_1'}, 'Doctor_7': {1.0: 'Hospital_8', 2.0: 'Hospital_7', 3.0: 'Hospital_9', 4.0: 'Hospital_6', 5.0: 'Hospital_5', 6.0: 'Hospital_4', 7.0: 'Hospital_3', 8.0: 'Hospital_2', 9.0: 'Hospital_1'}, 'Doctor_10': {1.0: 'Hospital_10', 2.0: 'Hospital_9', 3.0: 'Hospital_8', 4.0: 'Hospital_7', 5.0: 'Hospital_6', 6.0: 'Hospital_5', 7.0: 'Hospital_4', 8.0: 'Hospital_3', 9.0: 'Hospital_2', 10.0: 'Hospital_1'}, 'Doctor_2': {1.0: 'Hospital_3', 2.0: 'Hospital_2', 3.0: 'Hospital_4', 4.0: 'Hospital_1', 5.0: 'Hospital_5', 6.0: 'Hospital_6', 7.0: 'Hospital_7', 8.0: 'Hospital_8', 9.0: 'Hospital_9', 10.0: 'Hospital_10'}}

医生医院:

{'Hospital_2': {1.0: 'Doctor_1', 2.0: 'Doctor_2', 3.0: 'Doctor_3', 4.0: 'Doctor_4', 5.0: 'Doctor_5', 6.0: 'Doctor_6', 7.0: 'Doctor_7', 8.0: 'Doctor_8', 9.0: 'Doctor_9', 10.0: 'Doctor_10'}, 'Hospital_1': {1.0: 'Doctor_1', 2.0: 'Doctor_2', 3.0: 'Doctor_3', 4.0: 'Doctor_4', 5.0: 'Doctor_5', 6.0: 'Doctor_6', 7.0: 'Doctor_7', 8.0: 'Doctor_8', 9.0: 'Doctor_9', 10.0: 'Doctor_10'}, 'Hospital_8': {1.0: 'Doctor_8', 2.0: 'Doctor_9', 3.0: 'Doctor_7', 4.0: 'Doctor_6', 5.0: 'Doctor_10', 6.0: 'Doctor_4', 7.0: 'Doctor_3', 8.0: 'Doctor_2', 9.0: 'Doctor_1'}, 'Hospital_7': {1.0: 'Doctor_5', 2.0: 'Doctor_6', 3.0: 'Doctor_7', 4.0: 'Doctor_8', 5.0: 'Doctor_3', 6.0: 'Doctor_2', 7.0: 'Doctor_9', 8.0: 'Doctor_1', 9.0: 'Doctor_10'}, 'Hospital_10': {1.0: 'Doctor_10', 2.0: 'Doctor_9', 3.0: 'Doctor_8', 4.0: 'Doctor_7', 5.0: 'Doctor_6', 6.0: 'Doctor_5', 7.0: 'Doctor_4', 8.0: 'Doctor_3', 9.0: 'Doctor_2', 10.0: 'Doctor_1'}, 'Hospital_3': {1.0: 'Doctor_1', 2.0: 'Doctor_2', 3.0: 'Doctor_3', 4.0: 'Doctor_4', 5.0: 'Doctor_5', 6.0: 'Doctor_6', 7.0: 'Doctor_7', 8.0: 'Doctor_8', 9.0: 'Doctor_9', 10.0: 'Doctor_10'}, 'Hospital_9': {1.0: 'Doctor_9', 2.0: 'Doctor_10', 3.0: 'Doctor_8', 4.0: 'Doctor_7', 5.0: 'Doctor_6', 6.0: 'Doctor_5', 7.0: 'Doctor_4', 8.0: 'Doctor_3', 9.0: 'Doctor_2', 10.0: 'Doctor_1'}, 'Hospital_5': {1.0: 'Doctor_4', 2.0: 'Doctor_3', 3.0: 'Doctor_2', 4.0: 'Doctor_1', 5.0: 'Doctor_5', 6.0: 'Doctor_6', 7.0: 'Doctor_7', 8.0: 'Doctor_8', 9.0: 'Doctor_9', 10.0: 'Doctor_10'}, 'Hospital_4': {1.0: 'Doctor_3', 2.0: 'Doctor_2', 3.0: 'Doctor_4', 4.0: 'Doctor_1', 5.0: 'Doctor_5', 6.0: 'Doctor_6', 7.0: 'Doctor_7', 8.0: 'Doctor_8', 9.0: 'Doctor_9', 10.0: 'Doctor_10'}, 'Hospital_6': {1.0: 'Doctor_4', 2.0: 'Doctor_5', 3.0: 'Doctor_6', 4.0: 'Doctor_3', 5.0: 'Doctor_2', 6.0: 'Doctor_1', 7.0: 'Doctor_8', 8.0: 'Doctor_9', 9.0: 'Doctor_10'}}

我还创建了医生列表,因为该列表用于创建算法产生的DataFrame索引:

['Doctor_5', 'Doctor_9', 'Doctor_8', 'Doctor_1', 'Doctor_4', 'Doctor_3', 'Doctor_6', 'Doctor_7', 'Doctor_10', 'Doctor_2']

现在,我正在尝试基于Gale-Shapley算法(无需知道具体信息)创建一种将医生分配给医院的算法。

到目前为止,这是我想出的,我最终将其呈现在DataFrame中,因为我发现这更易于理解:

Matches = {}
Matches['Doctors'] = (doctors)
First_round = []
for Doctor_ in ranking_by_doctors:
    First_round.append(ranking_by_doctors[Doctor_].get(1.0))
Matches['First round'] = (First_round)
Matches
Matches_round_1 = pd.DataFrame.from_dict(Matches)
Matches_round_1.set_index('Doctors', inplace=True)
Matches_round_1   

这是我的结果:enter image description here

如您所见,我正在为每位医生分配最喜欢的医院。但是我需要有关我的职能条件的帮助。截至目前,我的结果中存在重复项:doctor_7和doctor_8都与hospital_8匹配,类似地,hospital_7也与两位不同的医生匹配。但是,我想在我的功能中添加一个条件,以便在这种情况下检查医院最喜欢的医生,匹配那个医生,让另一个医生不匹配。之后,我想为无与伦比的医生重新开始整个过程​​,从而在第二轮中获得新的结果。对于第二轮,已经相匹配的医院应该打破他们的比赛,因为医生会比他们更喜欢他们,而不是他们的第一场比赛。

但是,在考虑调整我的功能几个小时并浏览google和列出理解指南以寻求帮助之后,我仍然没有找到解决方法。这就是为什么我转向stackoverflow寻求帮助的原因,也许你们当中的一个以前已经看到过这个问题,可以帮助我解决这个问题。如果您需要除以上提供的信息以外的其他信息,请告诉我!

非常感谢您

1 个答案:

答案 0 :(得分:1)

我将First_round更改为字典,以使其更加直接。我还建议其他结构更改,但此后再进行更多更改。一种解决方案是简单地进行一次if检查,以查看是否已指定了特定医院,然后在医生得分更高的情况下更换医生:

def hospital_ranking_of_doctor(hospital, doctor):
    return next(v for k, v in ranking_by_hospital[hospital].items() if v == doctor)

Matches = {}
Matches['Doctors'] = (doctors)
First_round = {}

# We loop through all the doctors one by one
for Doctor_ in ranking_by_doctors:

    # Then we find which hospital the doctor prefers
    favored_hospital = ranking_by_doctors[Doctor_].get(1.0)

    # We test if that hospital has already had a doctor assigned
    if favored_hospital not in First_round:
        # If it has not, then we just assign the current doctor
        First_round[favored_hospital] = Doctor_
    else:
        # If the hosptial was already assigned a doctor we compare 
        # that doctor with the new one and set the new one only if 
        # the hospital prefers him.
        previously_assigned_doctor = First_round[favored_hospital]
        if hospital_ranking_of_doctor(favored_hospital, previously_assigned_doctor) > hospital_ranking_of_doctor(favored_hospital, Doctor_):
            First_round[favored_hospital] = Doctor_

print(First_round)

现在,对于结构更改,我认为您还应该将排名结构从从数字到医院/医生的字典更改为只是偏好的有序列表或将其翻转,以便关键是医院/医生优先级/分数是值。这样可以更自然地检查医生的分数:

ranking_by_hospital['Hospital_2']['Doctor_2'] > ranking_by_hospital['Hospital_2']['Doctor_3']

因此您可以将排名功能更新为:

def hospital_ranking_of_doctor(hospital, doctor):
    return ranking_by_hospital[hospital][doctor]

或者只是内联这些代码位。