Ejemplo n.º 1
0
 def build_stacks(self, players, optimizer):
     players_by_teams = get_players_grouped_by_teams(players)
     all_groups: List[BaseGroup] = []
     for game in optimizer.games:
         groups = [
             PlayersGroup(
                 players=players_by_teams[game.home_team],
                 min_from_group=self.min_from_team,
             ),
             PlayersGroup(
                 players=players_by_teams[game.away_team],
                 min_from_group=self.min_from_team,
             ),
             PlayersGroup(
                 players=[
                     *players_by_teams[game.home_team],
                     *players_by_teams[game.away_team]
                 ],
                 min_from_group=self.size,
             )
         ]
         nested_group = NestedPlayersGroup(
             groups=groups,
             max_exposure=self.max_exposure,
         )
         all_groups.append(nested_group)
     return [OptimizerStack(groups=all_groups)]
Ejemplo n.º 2
0
 def apply(self, solver):
     all_restrict_positions = self.optimizer.same_team_restrict_positions
     if not all_restrict_positions:
         return
     players_by_team = get_players_grouped_by_teams(
         self.players_dict.keys())
     for restrict_positions in all_restrict_positions:
         for team_players in players_by_team.values():
             first_position_players = [
                 player for player in team_players
                 if restrict_positions[0] in player.positions
             ]
             second_position_players = [
                 player for player in team_players
                 if restrict_positions[1] in player.positions
             ]
             for players_combination in product(first_position_players,
                                                second_position_players):
                 if players_combination[0] == players_combination[1]:
                     continue
                 variables = [
                     self.players_dict[player]
                     for player in players_combination
                 ]
                 solver.add_constraint(variables, None, SolverSign.LTE, 1)
Ejemplo n.º 3
0
 def build_stacks(self, players: List[Player],
                  optimizer: 'LineupOptimizer') -> List[OptimizerStack]:
     players_by_teams = get_players_grouped_by_teams(
         players, for_teams=self.for_teams)
     all_positions = tuple(set(chain.from_iterable(self.positions)))
     positions_for_optimizer = Counter(self.positions)
     positions_for_optimizer[all_positions] = len(self.positions)
     all_groups = []  # type: List[BaseGroup]
     for team_name, team_players in players_by_teams.items():
         groups = []
         for positions, total in positions_for_optimizer.items():
             groups.append(
                 PlayersGroup(
                     players=[
                         player for player in team_players
                         if list_intersection(player.positions, positions)
                     ],
                     min_from_group=total,
                 ))
         nested_group = NestedPlayersGroup(
             groups=groups,
             max_exposure=self.max_exposure_per_team.get(
                 team_name, self.max_exposure),
         )
         all_groups.append(nested_group)
     return [OptimizerStack(groups=all_groups)]
Ejemplo n.º 4
0
 def apply(self, solver, players_dict):
     total_teams = self.optimizer.total_teams
     settings = self.optimizer.settings
     min_teams = settings.min_teams
     if not min_teams and not total_teams:
         return
     total_players = self.optimizer.settings.get_total_players()
     players_by_teams = get_players_grouped_by_teams(
         players_dict.keys(),
         for_positions=[
             position for position in self.optimizer.available_positions
             if position not in settings.total_teams_exclude_positions
         ])
     teams_variables = []
     for team, team_players in players_by_teams.items():
         variable = solver.add_variable('total_teams_%s' % team)
         teams_variables.append(variable)
         variables = [players_dict[player] for player in team_players]
         solver.add_constraint(variables, None, SolverSign.LTE,
                               variable * total_players)
         solver.add_constraint(variables, None, SolverSign.GTE, variable)
     if total_teams:
         solver.add_constraint(teams_variables, None, SolverSign.EQ,
                               total_teams)
     else:
         solver.add_constraint(teams_variables, None, SolverSign.GTE,
                               min_teams)
Ejemplo n.º 5
0
 def _create_constraints(self, solver, players_dict, exclude_teams=None):
     # type: (Solver, Dict[Player, Any], Optional[Set[str]]) -> None
     all_combinations = defaultdict(set)  # type: DefaultDict[Tuple[Any, ...], Set[Any]]
     players_by_teams = get_players_grouped_by_teams(players_dict.keys())
     for stack, total_stacks in self.stacks_dict.items():
         stack_variables = []
         variable_prefix = 'rules_%s' % '_'.join(str(stack))
         all_positions = tuple(set(chain.from_iterable(stack)))
         positions_for_optimizer = Counter(stack)
         positions_for_optimizer[all_positions] = len(stack)
         for team_name, team_players in players_by_teams.items():
             if exclude_teams and team_name in exclude_teams:
                 variables = [players_dict[player] for player in team_players
                              if list_intersection(player.positions, all_positions)]
                 solver.add_constraint(variables, None, SolverSign.LTE, len(stack) - 1)
                 continue
             variable_name = '%s_players_%s' % (variable_prefix, team_name)
             team_stack_var = solver.add_variable(variable_name)
             stack_variables.append(team_stack_var)
             for positions, total in positions_for_optimizer.items():
                 position_variables = set(
                     players_dict[player] for player in sorted(team_players, key=lambda p: p.full_name)
                     if list_intersection(player.positions, positions))
                 all_combinations[tuple(position_variables)].add(team_stack_var)
                 solver.add_constraint(position_variables, None, SolverSign.GTE, total * team_stack_var)
         solver.add_constraint(stack_variables, None, SolverSign.GTE, total_stacks)
     for combination_variables in all_combinations.values():
         if len(combination_variables) > 1:
             solver.add_constraint(combination_variables, None, SolverSign.LTE, 1)
Ejemplo n.º 6
0
 def _get_players_combinations_by_team(self, players_dict):
     players_combinations_by_team = defaultdict(lambda: defaultdict(
         set))  # type: Dict[Tuple[str, ...], Dict[str, Set]]
     players_by_teams = get_players_grouped_by_teams(players_dict.keys())
     for stack in self.stacks_dict.keys():
         for team_name, team_players in players_by_teams.items():
             all_players_combinations = set()
             players_by_positions = []
             for position in stack:
                 players_by_positions.append([
                     player for player in team_players
                     if position in player.positions
                 ])
             # Create all possible players combinations for stack
             for players_combination in product(*players_by_positions):
                 # Remove combinations with duplicated players
                 if len(set(players_combination)) != len(stack):
                     continue
                 players_combination = tuple([
                     players_dict[player]
                     for player in sorted(players_combination,
                                          key=lambda p: p.id)
                 ])
                 all_players_combinations.add(players_combination)
             players_combinations_by_team[stack][
                 team_name] = all_players_combinations
     return players_combinations_by_team
Ejemplo n.º 7
0
 def apply(self, solver, players_dict):
     all_players = players_dict.keys()
     for_positions = self.optimizer.team_stacks_for_positions
     if for_positions:
         all_players = [player for player in all_players if list_intersection(player.positions, for_positions)]
     players_by_teams = get_players_grouped_by_teams(all_players)
     for team, players in players_by_teams.items():
         variables = [players_dict[player] for player in players]
         self.player_variables_by_teams[team] = variables
     if not self.teams_max_exposures:
         self._create_constraints(solver)
Ejemplo n.º 8
0
 def build_stacks(self, players: List[Player],
                  optimizer: 'LineupOptimizer') -> List[OptimizerStack]:
     players_by_teams = get_players_grouped_by_teams(
         players,
         for_teams=self.for_teams,
         for_positions=self.for_positions)
     groups = []  # type: List[BaseGroup]
     spacing_groups = []  # type: List[BaseGroup]
     for team, players in players_by_teams.items():
         parent_group = PlayersGroup(
             players=players,
             min_from_group=self.size,
             max_exposure=self.max_exposure_per_team.get(
                 team, self.max_exposure))
         groups.append(parent_group)
         if not self.spacing:
             continue
         players_by_roster_positions = defaultdict(
             list)  # type: Dict[int, List[Player]]
         for player in players:
             if player.roster_order is None:
                 continue
             players_by_roster_positions[player.roster_order].append(player)
         if not players_by_roster_positions:
             continue
         all_allowed_roster_orders = set()
         max_spacing = max(players_by_roster_positions.keys())
         for roster_position in players_by_roster_positions.keys():
             allowed_roster_orders = []
             for i in range(self.spacing):
                 if roster_position + i <= max_spacing:
                     allowed_roster_orders.append(roster_position + i)
                 else:
                     allowed_roster_orders.append(((roster_position + i) %
                                                   (max_spacing + 1)) + 1)
             all_allowed_roster_orders.add(
                 tuple(sorted(allowed_roster_orders)))
         for roster_orders in all_allowed_roster_orders:
             spacing_groups.append(
                 PlayersGroup(
                     players=list(
                         chain.from_iterable(
                             players for players_spacing, players in
                             players_by_roster_positions.items()
                             if players_spacing in roster_orders)),
                     min_from_group=self.size,
                     parent=parent_group,
                 ))
     stacks = [OptimizerStack(groups=groups)]
     if spacing_groups:
         stacks.append(
             OptimizerStack(groups=spacing_groups, can_intersect=True))
     return stacks
Ejemplo n.º 9
0
 def apply(self, solver):
     settings = self.optimizer.settings
     min_teams = self.optimizer.min_teams or settings.min_teams
     max_teams = self.optimizer.max_teams
     if not min_teams and not max_teams:
         return
     total_players = self.optimizer.settings.get_total_players()
     players_by_teams = get_players_grouped_by_teams(
         self.players_dict.keys(),
         for_positions=[
             position
             for position in self.optimizer.player_pool.available_positions
             if position not in settings.total_teams_exclude_positions
         ])
     teams_variables = []
     for team, team_players in players_by_teams.items():
         variable = solver.add_variable('total_teams_%s' % team)
         teams_variables.append(variable)
         variables = [self.players_dict[player] for player in team_players]
         solver.add_constraint(variables, None, SolverSign.LTE,
                               variable * total_players)
         solver.add_constraint(variables, None, SolverSign.GTE, variable)
     if min_teams == max_teams:
         solver.add_constraint(teams_variables,
                               None,
                               SolverSign.EQ,
                               min_teams,
                               name='exact_teams')
     if min_teams:
         solver.add_constraint(teams_variables,
                               None,
                               SolverSign.GTE,
                               min_teams,
                               name='min_teams')
     if max_teams:
         solver.add_constraint(teams_variables,
                               None,
                               SolverSign.LTE,
                               max_teams,
                               name='max_teams')
Ejemplo n.º 10
0
 def build_stacks(self, players: List[Player],
                  optimizer: 'LineupOptimizer') -> List[OptimizerStack]:
     players_by_teams = get_players_grouped_by_teams(
         players,
         for_teams=self.for_teams,
         for_positions=self.for_positions)
     groups = []  # type: List[BaseGroup]
     for team, players in players_by_teams.items():
         groups.append(
             PlayersGroup(players=players,
                          min_from_group=self.size,
                          max_exposure=self.max_exposure_per_team.get(
                              team, self.max_exposure)))
         if self.spacing:
             sub_groups = []
             players_by_roster_positions = defaultdict(
                 list)  # type: Dict[int, List[Player]]
             for player in players:
                 if player.roster_order is None:
                     continue
                 players_by_roster_positions[player.roster_order].append(
                     player)
             for roster_position, players in players_by_roster_positions.items(
             ):
                 next_restricted_roster_position = roster_position + self.spacing
                 restricted_players = chain.from_iterable(
                     players for players_spacing, players in
                     players_by_roster_positions.items()
                     if players_spacing >= next_restricted_roster_position)
                 for first_player in restricted_players:
                     for second_player in players:
                         sub_groups.append(
                             PlayersGroup(
                                 players=[first_player, second_player],
                                 max_from_group=1,
                             ))
             groups.append(NestedPlayersGroup(groups=sub_groups, ))
     return [OptimizerStack(groups=groups)]