from copy import copy import pandas as pd from sqlalchemy import false class Constants: players_per_group = 7 w = 0 # 文字列 Num を作成 for i in range(1,Constants.players_per_group+1): if i==1: Num="1" else : Num= Num+","+str(i) # 全腎臓の提出後処理(リスト化) def get_direction(group: Group): tmp=group.paths.split("|") tmp=[i for i in tmp if i!="" ] direction=[i.split(",") for i in tmp ] return direction # Chain B アルゴリズム def Algo(group): group.start_algo_frag==False tmp=group.paths.split("|") tmp=[i for i in tmp if i!="" ] patient_list=[i[0] for i in tmp] # 候補の患者リスト kideny_list=[i[2] for i in tmp] # 候補の腎臓リスト direction=[i.split(",") for i in tmp ] patient_dict=dict(zip(patient_list,direction)) # substep_a substep_b_frag = True for patient_int in patient_list: Conti_frag=True Chain = [patient_int] Pointed = patient_dict[patient_int][1] #腎臓 while Conti_frag: if Pointed in Chain: # substep_a に分岐 substep_b_frag = False if Pointed==patient_int: # サークルの処理 for patient_id in Chain: # Chainを作成 #patient = group.get_player_by_id(patient_id) patient = player.loc[int(patient_id)] kideny_id = patient_dict[patient_id][1] # 確定腎臓ID # player クラスに保存 if patient.out_frag==False: patient.result=kideny_id patient.out_frag=True # group クラスを更新 # 分配が確定した腎臓(Chain)を kindeny_Remaining から取り除く tmp = [ i for i in kindeny_Remaining if i not in Chain ] group.kideny=",".join(tmp) # 確定者(Chain)をpatient_list から取り除く、以外を残す tmp = [ i for i in patient_Remaining if i not in Chain ] group.patient = ",".join(tmp) group.paths="" break elif Pointed== Constants.w: # 優先権 Chains.append(Chain) break elif Pointed not in patient_list: # 退出者 Chains.append(Chain) break Chain.append(Pointed) Pointed = patient_dict[Pointed][1] # 腎臓の更新 ############################## # マッチング終了 判定 if group.patient =="": group.end_frag==TRUE # substep_b 分岐 if substep_b_frag: # 最後尾が未割り当てか判定 first_patient_chains=[ i for i in Chains if i[0] in patient_Remaining] length_list=list(map(len,first_patient_chains)) if len(length_list)!=1: max_length=max(length_list) candidate_chains=[ i for i in first_patient_chains if len(i)== max_length] arrive_set=[] for candidate_chain in candidate_chains: other_chains=[i for i in candidate_chains if i!=candidate_chain] unique_set=set(candidate_chain) for other_chain in other_chains: unique_set=unique_set.difference(set(other_chain)) if unique_set==set(): tmp=Constants.players_per_group+1 else: tmp= list(map(int,unique_set) ) arrive_set.append(tmp) min_patients=list(map(min,arrive_set)) min_patient=min(min_patients) win_chain = [ i ==min_patient for i in min_patients] for i,j in zip(win_chain,candidate_chains): if i: chain=j for patient_id in chain: if patient_id==Constants.w: break patient = group.get_player_by_id(patient_id) kideny_id = patient_dict[patient_int][1] # 確定腎臓ID # player クラスに保存 if patient.out_frag==False: patient.result=kideny_id patient.out_frag=True # group クラスを更新 # 分配が確定した腎臓(Chain)を kindeny_Remaining から取り除く tmp = [ i for i in kindeny_Remaining if i not in chain[1:] ] # 最後尾の患者を除く group.kideny=",".join(tmp) # 確定者(Chain)をpatient_list から取り除く、以外を残す tmp = [ i for i in patient_Remaining if i not in chain ] group.patient = ",".join(tmp) break # 最後尾の患者に対する処理 group.paths = chain[0]+"," +str(Constants.w)+ "|" # 優先権を指す。 # マッチング終了 判定 if group.patient =="": group.end_frag==TRUE #アルゴリズム終了 #group = player.group import random P=[1,2,3,4,5,6,7] Bid=["1","2","3","4","5","6","7"] random.shuffle(P) random.shuffle(Bid) # P=[1,2,3,4,5,6,7] # Bid=["3","6","4","3","1","7","6"] player = Player_db.copy() group = Group_db.copy() for p,bid in zip(P,Bid): # seaquence の更新 player.current_value[p] = bid tmp = player.seaquence[p]+","+bid # 初めの一回目に空白が含まれる tmp = tmp.split(",") tmp = [ i for i in tmp if i!="" ] player.seaquence[p] = ",".join(tmp) # 提出済み(applyed)情報を更新 tmp = group.applyed+","+bid tmp = tmp.split(",") tmp = [ i for i in tmp if i!="" ] patient_applyed=tmp group.applyed = ",".join(tmp) # paths を文字列で保存 tmp = group.paths + str(p) + "," +bid+ "|" # 「|」で区切り tmp = tmp.split(",") tmp= [ i for i in tmp if i!=""] group.paths = ",".join(tmp) patient_Remaining = group.patient.split(",") kindeny_Remaining = group.kideny.split(",") # 終了フラグ判定 if len(patient_applyed)==len(patient_Remaining): group.start_algo_frag=True group.applyed="" else: group.start_algo_frag=False #全腎臓の提出後処理 アルゴリズムスタート if group.start_algo_frag==True: Algo(group) group.applyed="" Group_db = pd.Series() Group_db["kideny"]=Num Group_db["patient"]=Num Group_db["applyed"]="" Group_db["paths"]="" Group_db["start_algo_frag"]=False Group_db["end_frag"]=False Player_db = pd.DataFrame(index=[i for i in range(1,8,1)], columns=[]) Player_db["seaquence"]="" Player_db["current_value"]="" Player_db["out_frag"]=False Player_db["result"]=""