Commit aa5295a3 by Pierre-antoine Comby

### le dépot est propre

parents
.gitignore 0 → 100644
 __pycache__/ *.csv
algorithms.py 0 → 100644
 """ This script contains both the standard and extended Gale-Shapley algorithms for solving matching games. A matching game is defined by two sets called suitors and reviewers. Each suitor (and reviewer) has associated with it an ordered preference of the elements of the corresponding set. A solution to a matching game is any mapping between the set of suitors and reviewers. """ from collections import Counter from copy import deepcopy import numpy as np def galeshapley(suitor_pref_dict, reviewer_pref_dict): """ The Gale-Shapley algorithm. This is known to provide a unique, stable suitor-optimal matching. The algorithm is as follows: (1) Assign all suitors and reviewers to be unmatched. (2) Take any unmatched suitor, s, and their most preferred reviewer, r. - If r is unmatched, match s to r. - Else, if r is matched, consider their current partner, r_partner. - If r prefers s to r_partner, unmatch r_partner from r and match s to r. - Else, leave s unmatched and remove r from their preference list. (3) Go to (2) until all suitors are matched, then end. Parameters ---------- suitor_pref_dict : dict A dictionary with suitors as keys and their respective preference lists as values review_pref_dict : dict A dictionary with reviewers as keys and their respective preference lists as values Returns ------- matching : dict The suitor-optimal (stable) matching with suitors as keys and the reviewer they are matched with as values """ suitors = [s for s in suitor_pref_dict] matching = {s: None for s in suitors} while suitors != []: s = suitors.pop(0) r = suitor_pref_dict[s][0] if r not in matching.values(): matching[s] = r else: for suitr, revwr in matching.items(): if revwr == r: r_partner = suitr if reviewer_pref_dict[r].index(s) < reviewer_pref_dict[r].index( r_partner ): matching[r_partner] = None matching[s] = r suitors.append(r_partner) else: suitor_pref_dict[s].remove(r) suitors.append(s) return matching def get_free_residents(resident_prefs, matching): """ Return a list of all residents who are currently unmatched but have a non-empty preference list. """ return [ resident for resident in resident_prefs if resident_prefs[resident] and not any([resident in match for match in matching.values()]) ] def get_worst_idx(hospital, hospital_prefs, matching): """ Find the index of the worst resident currently assigned to `hospital` according to their preferences. """ return max( [ hospital_prefs[hospital].index(resident) for resident in hospital_prefs[hospital] if resident in matching[hospital] ] ) def resident_hospital(resident_prefs, hospital_prefs, capacities): """ Provide a stable, resident-optimal matching for the given instance of HR using the algorithm set out in [Gale, Shapley 1962]. """ matching = {hospital: [] for hospital in hospital_prefs} free_residents = get_free_residents(resident_prefs, matching) while free_residents: resident = free_residents[0] hospital = resident_prefs[resident][0] i = 0 while capacities[hospital] <= 0: i += 1 hospital = resident_prefs[resident][i] <<<<<<< HEAD ======= >>>>>>> 7158617afbb760d3a35b62a2705688d11b9d0b1b matching[hospital].append(resident) if len(matching[hospital]) > capacities[hospital]: worst = get_worst_idx(hospital, hospital_prefs, matching) resident = hospital_prefs[hospital][worst] matching[hospital].remove(resident) if len(matching[hospital]) == capacities[hospital]: worst = get_worst_idx(hospital, hospital_prefs, matching) successors = hospital_prefs[hospital][worst + 1 :] if successors: for resident in successors: hospital_prefs[hospital].remove(resident) if hospital in resident_prefs[resident]: resident_prefs[resident].remove(hospital) free_residents = get_free_residents(resident_prefs, matching) for hospital, matches in matching.items(): sorted_matches = sorted(matches, key=hospital_prefs[hospital].index) matching[hospital] = sorted_matches return matching def hrt_super_res(resident_prefs, hospital_prefs, capacities): """ Determine whether a super-stable, resident-optimal matching exists for the given instance of HR. If so, return the matching. """ # ================================== # Needs adjusting for ties in prefs. # ================================== matching = {h: [] for h in hospital_prefs.keys()} fulls = {h: False for h in hospital_prefs.keys()} free_residents = [r for r in resident_prefs.keys()] while [r for r in free_residents if resident_prefs[r]]: r = free_residents.pop(0) r_prefs = resident_prefs[r] h_best = r_prefs[0] matching[h_best] += [r] if len(matching[h_best]) > capacities[h_best]: r_worst = hospital_prefs[h_best][-1] if r_worst in matching[h_best]: matching[h_best].remove(r_worst) resident_prefs[r_worst].remove(h_best) hospital_prefs[h_best].remove(r_worst) if len(matching[h_best]) == capacities[h_best]: fulls[h_best] = True worst_idx = np.max( [ hospital_prefs[h_best].index(resident) for resident in hospital_prefs[h_best] if resident in matching[h_best] ] ) successors = hospital_prefs[h_best][worst_idx + 1 :] if successors: for resident in successors: hospital_prefs[h_best].remove(resident) resident_prefs[resident].remove(h_best) resident_match_counts = Counter([tuple(res) for res in matching.values()]) if np.any( [count > 1 for count in resident_match_counts.values()] ) or np.any(fulls.values()): raise ValueError("No super-stable matching exists.") return matching
bus.py 0 → 100755
 #! /usr/bin/env python3 BUS = ['Nausi[car] de la vallee du [van]', 'Au [bus]cher', 'La grosse [caisse]', 'Ha[van]a Club', 'l houm[bus]', '[Van]ted', 'Pernod-Ri[Car]d'] NB_BUS=8 class Bus(object): """Un bus contient des équipes , remplis par des 1A en fonction de leur réponse à un questionnaire """ def __init__(self, nom, places, places_2a,reponse_criteres,size_equipe): self.nom = nom # nom du bus self.criteres = reponse_criteres # critère et pondération self.note = dict() # note de tous les 1A par rapport à ce bus. self.rank_unA = [] self.passengers = [] self.old_passengers = [] self.size_team = [int(s) for s in size_equipe] self.teams = [] self.places = places self.places_2a = places_2a self.places_1a = places-places_2a def __repr__(self): ret = self.nom return"Bus_"+ret def __str__(self): return "Bus {}".format(self.nom) def __str__(self): return "Bus {}".format(self.nom) def gen_note(self, list_unA): for unA in list_unA: score_unA = unA.scores_bus[self] rank_unA = unA.rank_bus.index(self) if rank_unA == NB_BUS-1: note_bus = score_unA/rank_unA else: #note_bus = (score_unA-unA.scores_bus[unA.rank_bus[rank_unA+1]] + 2)/(rank_unA+1) p = NB_BUS - rank_unA nextu = unA.scores_bus[unA.rank_bus[rank_unA+1]] tmp = ((NB_BUS - rank_unA) * score_unA - (NB_BUS - rank_unA - 1) * nextu) / (rank_unA + 1) note_bus = tmp #note_bus = (score_unA**p - next**(p - 1)) # note_bus = (score_unA-unA.scores_bus[unA.rank_bus[rank_unA+1]]) self.note[unA] = note_bus def gen_rank(self): self.rank_unA = list(self.note.items()) self.rank_unA = sorted(self.rank_unA,key=lambda x:x[1],reverse = True) self.rank_unA = [r[0] for r in self.rank_unA] def partial_rank(self, students): return [student for student in self.rank_unA if student in students] def make_teams(self): print(self.nom) n_chef_tot = sum(self.size_team) n_equipe = len(self.size_team) N = len(self.passengers) size_goal = [0]*len(self.size_team) for i in range(len(self.size_team)): size_goal[i] = int(self.size_team[i]*N/n_chef_tot)+1 i = 0 places_equipe=sum(size_goal) girls = [p for p in self.passengers if p.infos["genre"] == 'F' or p.infos["genre"] == 'N'] not_girls = [p for p in self.passengers if p.infos["genre"] == 'M'] # # for e in size_goal: # equipe = [] # for k in range(int(len(girls)*e/places_equipe)): # if girls: # equipe.append(girls.pop()) # for k in range(int(len(not_girls)*e/places_equipe)): # if not_girls: # equipe.append(not_girls.pop()) # print(len(equipe)) # self.teams.append(equipe) i=0 self.teams=[[None]*s for s in size_goal] while girls : if None in self.teams[i]: self.teams[i].append(girls.pop()) self.teams[i].remove(None) i +=1; i %= n_equipe; for i in range(len(self.size_team)): if len(self.teams[i])-self.teams[i].count(None) == 1: #Si une fille est seule on l'enlève. g_alone=self.teams[i].pop() self.teams[i].append(None) next_ind = (i+1)%n_equipe self.teams[next_ind].remove(None) self.teams[next_ind].append(g_alone) remain =True while not_girls and remain: if None in self.teams[i]: self.teams[i].append(not_girls.pop()) self.teams[i].remove(None) i +=1; i %= n_equipe; #cleaned unused places for l in self.teams: while None in l: l.remove(None) #affichage for k in range(len(self.size_team)): print(self.size_team[k],size_goal[k],len(self.teams[k]),self.teams[k]) print(len(self.passengers),sum(size_goal)) def partial_rank(self, students): return [student for student in self.rank_unA if student in students]
hardcode.json 0 → 100644
 { "aspique":[978,1004,1112,1042,1092,1083,1145,963,975,1059,934,931,1082,1046,1084,961,1097,1195,944,1106,952,942,1071,1134], "chytem":[1002], "fanfare":[947,997,929,930, 1066], "hooligens":[1050,1006,962,1013], "med":[951,956], "saphire":[1118,1111], "satelist":[1016,1114], "vieux":[974, 1066,943] }
main.py 0 → 100755
This diff is collapsed.
parsewiki.py 0 → 100755
 #!/usr/bin/env python3 # -*- coding:utf-8 -* """Pour récupérer des infos à partir du wiki.""" import time import re #import urllib.request import pprint #: URL de la page wiki des bus URL = "https://wiki.crans.org/OrganisationWei{}/Bus?action=raw".format( time.localtime()[0]) FILE = "rawpage" def get_raw(): """Récupère le contenu de la page.""" return open(FILE).read() # page = urllib.request.urlopen(URL) # text = page.read().decode("utf-8") return text def parse_names(raw): """Récupère les tableaux de Bus (= un tableau après un titre commençant par '== Bus').""" names = [] l = re.findall("== (?:Bi)?Bus.*==[^|]*\n((?:\|\|.*\|\|\n)+)", raw) for table in l: obj = re.search("Nom de l'équipe[^|]*\|\|", table) after = table[obj.end():] end = after.index("\n") after = after[:end] teams = re.findall("([^|]+)\|\|", after) teams = [t.strip() for t in teams] names.append(teams) return names def get_team_names(): raw = get_raw() teams = parse_names(raw) return teams if __name__ == "__main__": for t in get_team_names(): print(t)
rawpage 0 → 100644
This diff is collapsed.
unA.py 0 → 100755
 #!/usr/bin/env python3 INFOS = [ "idwei", "nom", "prenom", "genre", "dept", "tel", "urgence_nom", "urgence_tel", "mail", "infos" ] INFOS_2A =INFOS + [ "idbde", "bus", "role" ] CRITERES = { "q_soirees", "q_alcools", "q_encadrement", "q_groupe", "q_sociable", "q_chants", "q_boire", "q_assos", "q_activites", "q_personnes", "q_suiveur", "q_conquetes" } class People(object): def __init__(self, infos): self.infos = infos def __repr__(self): return repr("P_"+self.infos["nom"]) def __str__(self): return "{} {}".format(self.infos["nom"].upper(), self.infos["prenom"]) class UnA(People): """un 1A est une gentille personne qui veux faire plein de rencontre dans le bon bus.""" def __init__(self, infos, reponse_criteres): People.__init__(self,infos) self.criteres = reponse_criteres self.scores_bus = dict() self.rank_bus = [] def __repr__(self): return repr("unA_"+self.infos["nom"]) def __str__(self): return "{} {}".format(self.infos["nom"].upper(), self.infos["prenom"]) def score_question(self,ans1a, ansbus): """ Calcule le score pour une question, Connaissance la réponse du 1A, celle du bus, et l'importance. """ MAX = 3 MIN = -MAX delta = abs(ans1a*2 - ansbus) # unA /5 , bus /10 s = (MAX - MIN) * (- delta / 4.) + MAX return s def score_questions(self, crit_bus): """ Calcule le score total pour 1 bus. """ s = 0 for crit in self.criteres: s += self.score_question(self.criteres[crit],crit_bus[crit]) return s def gen_score(self, list_bus): for bus in list_bus: self.scores_bus[bus] = self.score_questions(bus.criteres) def gen_rank(self): #self.rank_bus = list(self.scores_bus.keys()) #self.rank_bus = sorted(self.scores_bus,key=self.scores_bus.get) self.rank_bus = list(self.scores_bus.items()) self.rank_bus = sorted(self.rank_bus,key=lambda x:x[1],reverse = True) self.rank_bus = [r[0] for r in self.rank_bus]
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!