Exemplo n.º 1
0
    def create_schedule(self):
        if self.debug:
            print "{}: Starting".format(dg.datetime.datetime.today())
        matchups = None
        initialState = dom.Matchups(None, self.data.league,
                                    self.data.game_indices)
        if self.matchups_json:
            matchups = read_output(self.data.league, "Matchups")
        else:
            matchups, matchups_statesExplored = self.DFS(initialState)
            if self.debug:
                print "{}: Matchups, {} states explored, {}".format(
                    dg.datetime.datetime.today(), matchups_statesExplored,
                    matchups is not None)

        if matchups is not None:
            write_output(matchups, "Matchups")
            #now we have our matchups which is a dict of (team, game_num) -> [opponent]
            #we next want to assign home/away so we create a map of the form:
            #(team1, team2, game_num) -> [True/False]
            #where True indicates it's played at team1's venue
            #also team1 < team2 alphabetically
            venues_dates = None
            if self.venues_dates_json:
                venues_dates = {}
                venues = read_output(self.data.league, "Venues")
                dates = read_output(self.data.league, "Dates")
                self.data.game_indices = read_output(self.data.league, "I2D")
                for state in venues:
                    venues_dates[state] = (dates[state], venues[state])
            else:
                venues_domains = {}
                venues_selected = {}
                master_dates = {}
                for state in matchups:
                    t, g_n = state
                    o = matchups[state]
                    sk = (t, o, g_n) if t.name < o.name else (o, t, g_n)
                    dk = (t, o) if t.name < o.name else (o, t)
                    if sk not in venues_selected:
                        venues_selected[sk] = None
                        dates_true = date_ranges(2, dk[0], g_n)
                        dates_false = date_ranges(2, dk[1], g_n)
                        master_dates[(sk, True)] = dates_true
                        master_dates[(sk, False)] = dates_false
                        venues_domains[dk] = [True, False] * (
                            (dom.constraint.total_games(initialState, t, o) +
                             1) / 2)
                venueState = dom.Venues({initialState.domains: venues_domains, initialState.selected: venues_selected,\
                                         initialState.master_dates: master_dates})
                venues_dates, venues_statesExplored = self.DIJKSTRAS(
                    venueState)
                #venues_dates, venues_statesExplored = self.DFS(venueState)
                if self.debug:
                    print "{}: Venues, {} states explored, {}".format(
                        dg.datetime.datetime.today(), venues_statesExplored,
                        venues_dates is not None)

            if venues_dates is not None:
                venues = {}
                dates = {}
                #write_output(venu, "Dates")
                #create a master map of everything of the form:
                #(team, game_num) -> (opponent, home, dateindex)
                #where home is true if played at team's venue
                sched_map = {}
                for state in venues_dates:
                    t1, t2, g_n = state
                    date, home = venues_dates[state]
                    sched_map[(t1, g_n)] = (t2, home, date)
                    sched_map[(t2, g_n)] = (t1, not home, date)
                    venues[state] = home
                    dates[state] = date
                #sanity check that everything is right
                for team in self.data.league.teams():
                    date = -20
                    opponent_venue = {}
                    for i in range(1, 83):
                        opponent, t_f, d = sched_map[(team, i)]
                        if date >= d:
                            print "invalid date. game {} has date {}, game {} has date {}".format(
                                i - 1, date, i, d)
                        date = d
                        key = (opponent, t_f)
                        constraint.add(opponent_venue, key)
                    for opponent in self.data.league.teams():
                        if opponent is not team:
                            if opponent_venue[(
                                    opponent, True)] < (constraint.total_games(
                                        initialState, team, opponent)) / 2:
                                print "not enough home games"
                            if opponent_venue[
                                (opponent, False)] < (constraint.total_games(
                                    initialState, team, opponent)) / 2:
                                print "not enough away games"
                            if opponent_venue[
                                (opponent, True)] + opponent_venue[
                                    (opponent,
                                     False)] != constraint.total_games(
                                         initialState, team, opponent):
                                print "not enough games"
                write_output(venues, "Venues")
                write_output(dates, "Dates")
                write_output(self.data.i2d, "I2D")
                return sched_map

        return None
Exemplo n.º 2
0
    def create_schedule(self):
        if self.debug: print "{}: Starting".format(dg.datetime.datetime.today())
        matchups = None
        initialState = dom.Matchups(None, self.data.league, self.data.game_indices)
        if self.matchups_json:
            matchups = read_output(self.data.league, "Matchups")
        else:
            matchups, matchups_statesExplored = self.DFS(initialState)
            if self.debug: print "{}: Matchups, {} states explored, {}".format(dg.datetime.datetime.today(), matchups_statesExplored, matchups is not None)

        if matchups is not None:
            write_output(matchups, "Matchups")
            #now we have our matchups which is a dict of (team, game_num) -> [opponent]
            #we next want to assign home/away so we create a map of the form:
            #(team1, team2, game_num) -> [True/False]
            #where True indicates it's played at team1's venue
            #also team1 < team2 alphabetically
            venues_dates = None
            if self.venues_dates_json:
                venues_dates = {}
                venues = read_output(self.data.league, "Venues")
                dates = read_output(self.data.league, "Dates")
                self.data.game_indices = read_output(self.data.league, "I2D")
                for state in venues:
                    venues_dates[state] = (dates[state], venues[state])
            else:
                venues_domains = {}
                venues_selected = {}
                master_dates = {}
                for state in matchups:
                    t, g_n = state
                    o = matchups[state]
                    sk = (t, o, g_n) if t.name < o.name else (o, t, g_n)
                    dk = (t, o) if t.name < o.name else (o, t)
                    if sk not in venues_selected:
                        venues_selected[sk] = None
                        dates_true = date_ranges(2, dk[0], g_n)
                        dates_false = date_ranges(2, dk[1], g_n)
                        master_dates[(sk,True)] = dates_true
                        master_dates[(sk,False)] = dates_false
                        venues_domains[dk] = [True, False] * ((dom.constraint.total_games(initialState, t, o) + 1)/2)
                venueState = dom.Venues({initialState.domains: venues_domains, initialState.selected: venues_selected,\
                                         initialState.master_dates: master_dates})
                venues_dates, venues_statesExplored = self.DIJKSTRAS(venueState)
                #venues_dates, venues_statesExplored = self.DFS(venueState)
                if self.debug: print "{}: Venues, {} states explored, {}".format(dg.datetime.datetime.today(), venues_statesExplored, venues_dates is not None)

            if venues_dates is not None:
                venues = {}
                dates = {}
                #write_output(venu, "Dates")
                #create a master map of everything of the form:
                #(team, game_num) -> (opponent, home, dateindex)
                #where home is true if played at team's venue
                sched_map = {}
                for state in venues_dates:
                    t1, t2, g_n = state
                    date, home = venues_dates[state]
                    sched_map[(t1, g_n)] = (t2, home, date)
                    sched_map[(t2, g_n)] = (t1, not home, date)
                    venues[state] = home
                    dates[state] = date
                #sanity check that everything is right
                for team in self.data.league.teams():
                    date = -20
                    opponent_venue = {}
                    for i in range(1, 83):
                        opponent, t_f, d = sched_map[(team, i)]
                        if date >= d:
                            print "invalid date. game {} has date {}, game {} has date {}".format(i-1, date, i, d)
                        date = d
                        key = (opponent, t_f)
                        constraint.add(opponent_venue, key)
                    for opponent in self.data.league.teams():
                        if opponent is not team:
                            if opponent_venue[(opponent, True)] < (constraint.total_games(initialState, team, opponent))/2:
                                print "not enough home games"
                            if opponent_venue[(opponent, False)] < (constraint.total_games(initialState, team, opponent))/2:
                                print "not enough away games"
                            if opponent_venue[(opponent, True)] + opponent_venue[(opponent, False)] != constraint.total_games(initialState, team, opponent):
                                print "not enough games"
                write_output(venues, "Venues")
                write_output(dates, "Dates")
                write_output(self.data.i2d, "I2D")
                return sched_map

        return None
Exemplo n.º 3
0
    def min_key(self):
        '''
            Goal is to first assign the games for teams with opponents they have an
            even number of games with. Then once they are all assigned we try to fit
            the remaining games, there's a little more flexibility there as it's not strict
            split
        '''
        teams_selected_even = {}
        teams_selected_odd = {}
        #calculate number of games against even-gamed opponents
        total_even_games = 4*self.DIVISIONAL_GAMES + 6*self.CONF_OPPONENTS_GAMES + 15*self.INTERCONF_GAMES
        total_odd_games = self.TOTAL_GAMES - total_even_games
        begin_search = True
        for state in self.states[self.selected]:
            if self.states[self.selected][state] is not None:
                begin_search = False
                t1, t2, g_n = state
                total_games = total_even_games if constraint.total_games(self, t1, t2)%2==0 else total_odd_games
                teams_selected = teams_selected_even if constraint.total_games(self, t1, t2)%2==0 else teams_selected_odd
                constraint.add(teams_selected, t1)
                constraint.add(teams_selected, t2)
                if teams_selected[t1] == total_games:
                    teams_selected.pop(t1, None)
                if teams_selected[t2] == total_games:
                    teams_selected.pop(t2, None)

        #teams_selected_* stores how many teams have selected their home/away for games
        #removing those that have had all their games scheduled with home/away
        #if it's empty then no team has had a selected home/away yet
        if begin_search:
            for k in self.states[self.domains]:
                if len(self.states[self.domains][k]) > 0 and constraint.total_games(self, k[0], k[1])%2==0:
                    return (k, self.min_key_helper(k))
        elif len(teams_selected_even) == 0 and len(teams_selected_odd) == 0:
            for k in self.states[self.domains]:
                if len(self.states[self.domains][k]) > 0 and constraint.total_games(self, k[0], k[1])%2!=0:
                    return (k, self.min_key_helper(k))

        #choose the team with the most selected home/away venues, i.e. least domain size remaining
        min_k = None
        if len(teams_selected_even) > 0:
            min_k = sorted(teams_selected_even.keys(), key=lambda x: -teams_selected_even[x])[0]
        elif len(teams_selected_odd) > 0:
            min_k = sorted(teams_selected_odd.keys(), key=lambda x: -teams_selected_odd[x])[0]
        else:
            return (None, None)
        best_k_even = None
        best_len_even = float("-inf")
        best_k_odd = None
        best_len_odd = float("-inf")
        #we have the team we want to next choose a venue for, but domains are pairs of teams,
        #so choose the pair with the largest remaining games to choose from
        for k in self.states[self.domains]:
            t1, t2 = k
            #store best_k for opponents u play even/odd # of games w/
            l = len(self.states[self.domains][k])
            if t1 is min_k or t2 is min_k:
                if constraint.total_games(self, t1, t2)%2 == 0:
                    if l > 0 and l > best_len_even:
                        best_len_even = l
                        best_k_even = k
                else:
                    if l > 0 and l > best_len_odd:
                        best_len_odd = l
                        best_k_odd = k
        #want to first assign games with teams you play even # of games with
        if best_k_even is not None:
            return (best_k_even, self.min_key_helper(best_k_even))
        elif best_k_odd is not None:
            return (best_k_odd, self.min_key_helper(best_k_odd))
        else:
            return (None, None)
Exemplo n.º 4
0
    def min_key(self):
        '''
            Goal is to first assign the games for teams with opponents they have an
            even number of games with. Then once they are all assigned we try to fit
            the remaining games, there's a little more flexibility there as it's not strict
            split
        '''
        teams_selected_even = {}
        teams_selected_odd = {}
        #calculate number of games against even-gamed opponents
        total_even_games = 4 * self.DIVISIONAL_GAMES + 6 * self.CONF_OPPONENTS_GAMES + 15 * self.INTERCONF_GAMES
        total_odd_games = self.TOTAL_GAMES - total_even_games
        begin_search = True
        for state in self.states[self.selected]:
            if self.states[self.selected][state] is not None:
                begin_search = False
                t1, t2, g_n = state
                total_games = total_even_games if constraint.total_games(
                    self, t1, t2) % 2 == 0 else total_odd_games
                teams_selected = teams_selected_even if constraint.total_games(
                    self, t1, t2) % 2 == 0 else teams_selected_odd
                constraint.add(teams_selected, t1)
                constraint.add(teams_selected, t2)
                if teams_selected[t1] == total_games:
                    teams_selected.pop(t1, None)
                if teams_selected[t2] == total_games:
                    teams_selected.pop(t2, None)

        #teams_selected_* stores how many teams have selected their home/away for games
        #removing those that have had all their games scheduled with home/away
        #if it's empty then no team has had a selected home/away yet
        if begin_search:
            for k in self.states[self.domains]:
                if len(
                        self.states[self.domains][k]
                ) > 0 and constraint.total_games(self, k[0], k[1]) % 2 == 0:
                    return (k, self.min_key_helper(k))
        elif len(teams_selected_even) == 0 and len(teams_selected_odd) == 0:
            for k in self.states[self.domains]:
                if len(
                        self.states[self.domains][k]
                ) > 0 and constraint.total_games(self, k[0], k[1]) % 2 != 0:
                    return (k, self.min_key_helper(k))

        #choose the team with the most selected home/away venues, i.e. least domain size remaining
        min_k = None
        if len(teams_selected_even) > 0:
            min_k = sorted(teams_selected_even.keys(),
                           key=lambda x: -teams_selected_even[x])[0]
        elif len(teams_selected_odd) > 0:
            min_k = sorted(teams_selected_odd.keys(),
                           key=lambda x: -teams_selected_odd[x])[0]
        else:
            return (None, None)
        best_k_even = None
        best_len_even = float("-inf")
        best_k_odd = None
        best_len_odd = float("-inf")
        #we have the team we want to next choose a venue for, but domains are pairs of teams,
        #so choose the pair with the largest remaining games to choose from
        for k in self.states[self.domains]:
            t1, t2 = k
            #store best_k for opponents u play even/odd # of games w/
            l = len(self.states[self.domains][k])
            if t1 is min_k or t2 is min_k:
                if constraint.total_games(self, t1, t2) % 2 == 0:
                    if l > 0 and l > best_len_even:
                        best_len_even = l
                        best_k_even = k
                else:
                    if l > 0 and l > best_len_odd:
                        best_len_odd = l
                        best_k_odd = k
        #want to first assign games with teams you play even # of games with
        if best_k_even is not None:
            return (best_k_even, self.min_key_helper(best_k_even))
        elif best_k_odd is not None:
            return (best_k_odd, self.min_key_helper(best_k_odd))
        else:
            return (None, None)