# coding: utf-8 from django.conf import settings from django.db.models import Max import random class Algorithm(object): shows = None ranks = None origranks = None double = None def __init__(self, shows, members, choices): """Initialisation : - on aggrège toutes les demandes pour chaque spectacle dans show.requests - on crée des tables de demandes pour chaque personne, afin de pouvoir modifier les rankings""" self.max_group = 2 * choices.aggregate(Max('priority'))['priority__max'] self.shows = [] showdict = {} for show in shows: show.nrequests = 0 showdict[show] = show show.requests = [] self.shows.append(show) self.ranks = {} self.origranks = {} self.choices = {} next_rank = {} member_shows = {} for member in members: self.ranks[member] = {} self.choices[member] = {} next_rank[member] = 1 member_shows[member] = {} for choice in choices: member = choice.participant if choice.spectacle in member_shows[member]: continue else: member_shows[member][choice.spectacle] = True showdict[choice.spectacle].requests.append(member) showdict[choice.spectacle].nrequests += 2 if choice.double else 1 self.ranks[member][choice.spectacle] = next_rank[member] next_rank[member] += 2 if choice.double else 1 self.choices[member][choice.spectacle] = choice for member in members: self.origranks[member] = dict(self.ranks[member]) def IncrementRanks(self, member, currank, increment = 1): for show in self.ranks[member]: if self.ranks[member][show] > currank: self.ranks[member][show] -= increment def appendResult(self, l, member, show): l.append((member, self.ranks[member][show], self.origranks[member][show], self.choices[member][show].double)) """ Pour les 2 Walkyries: c'est Sandefer Pour les 4 places pour l'Oratorio c'est Maxence Arutkin """ def __call__(self, seed): random.seed(seed) results = [] shows = sorted(self.shows, key = lambda x: float(x.nrequests) / x.slots, reverse = True) for show in shows: # On regroupe tous les gens ayant le même rang groups = dict([(i, []) for i in range(1, self.max_group + 1)]) for member in show.requests: if self.ranks[member][show] == 0: raise RuntimeError, (member, show.title) groups[self.ranks[member][show]].append(member) # On passe à l'attribution winners = [] losers = [] for i in range(1, self.max_group + 1): group = list(groups[i]) random.shuffle(group) for member in group: if self.choices[member][show].double: # double if len(winners) + 1 < show.slots: self.appendResult(winners, member, show) self.appendResult(winners, member, show) elif not self.choices[member][show].autoquit and len(winners) < show.slots: self.appendResult(winners, member, show) self.appendResult(losers, member, show) else: self.appendResult(losers, member, show) self.appendResult(losers, member, show) self.IncrementRanks(member, i, 2) else: # simple if len(winners) < show.slots: self.appendResult(winners, member, show) else: self.appendResult(losers, member, show) self.IncrementRanks(member, i) results.append((show,winners,losers)) return results