コード例 #1
0
ファイル: rules.py プロジェクト: asardinha/Cloud_Test
 def apply(self, solver, players_dict):
     if not self.optimizer.opposing_teams_position_restriction:
         return
     for game in self.optimizer.games:
         first_team_players = {
             player: variable
             for player, variable in players_dict.items()
             if player.team == game.home_team
         }
         second_team_players = {
             player: variable
             for player, variable in players_dict.items()
             if player.team == game.away_team
         }
         for first_team_positions, second_team_positions in \
                 permutations(self.optimizer.opposing_teams_position_restriction, 2):
             first_team_variables = [
                 variable
                 for player, variable in first_team_players.items() if
                 list_intersection(player.positions, first_team_positions)
             ]
             second_team_variables = [
                 variable
                 for player, variable in second_team_players.items() if
                 list_intersection(player.positions, second_team_positions)
             ]
             for variables in product(first_team_variables,
                                      second_team_variables):
                 solver.add_constraint(variables, None, SolverSign.LTE, 1)
コード例 #2
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)
コード例 #3
0
 def apply(self, solver, players_dict):
     if not self.optimizer.opposing_teams_position_restriction:
         return
     for game in self.optimizer.games:
         first_team_players = {
             player: variable
             for player, variable in players_dict.items()
             if player.team == game.home_team
         }
         second_team_players = {
             player: variable
             for player, variable in players_dict.items()
             if player.team == game.away_team
         }
         for first_team_positions, second_team_positions in \
                 permutations(self.optimizer.opposing_teams_position_restriction, 2):
             first_team_variables = [
                 variable
                 for player, variable in first_team_players.items() if
                 list_intersection(player.positions, first_team_positions)
             ]
             second_team_variables = [
                 variable
                 for player, variable in second_team_players.items() if
                 list_intersection(player.positions, second_team_positions)
             ]
             coefficients = [1] * len(second_team_variables)
             for var in first_team_variables:
                 solver.add_constraint(
                     [var, *second_team_variables],
                     [self.MULTIPLIER, *coefficients], SolverSign.LTE,
                     self.MULTIPLIER +
                     self.optimizer.opposing_teams_max_allowed)
コード例 #4
0
 def test_restrict_positions_for_opposing_team_correctness(self):
     first_team_positions = ['SP', 'RP']
     second_team_positions = ['1B', '2B', '3B']
     self.optimizer.restrict_positions_for_opposing_team(first_team_positions, second_team_positions)
     lineup = next(self.optimizer.optimize(1))
     pitcher_games = {player.game_info for player in lineup
                      if list_intersection(player.positions, first_team_positions)}
     hitters_games = {player.game_info for player in lineup
                      if list_intersection(player.positions, second_team_positions)}
     self.assertFalse(pitcher_games.intersection(hitters_games))
コード例 #5
0
ファイル: rules.py プロジェクト: lupka/pydfs-lineup-optimizer
 def apply(self, solver):
     players_dict = {player: variable for player, variable in self.players_dict.items() if
                     list_intersection(player.positions, self.HITTERS)}
     for team in self.optimizer.available_teams:
         players_from_team = [variable for player, variable in players_dict.items() if player.team == team]
         solver.add_constraint(players_from_team, None, SolverSign.LTE, self.MAXIMUM_HITTERS_FROM_ONE_TEAM,
                               name='dk_max_hitters_%s' % team)
コード例 #6
0
ファイル: rules.py プロジェクト: asardinha/Cloud_Test
 def apply(self, solver, players_dict):
     optimizer = self.optimizer
     positions, spacing = optimizer.spacing_positions, optimizer.spacing
     if not spacing or not positions:
         return
     available_players = sorted(
         [(player, variable) for player, variable in players_dict.items()
          if player.roster_order is not None
          and list_intersection(player.positions, positions)],
         key=self.sort_players,
     )
     players_by_roster_positions = {
         players_spacing: list(players)
         for players_spacing, players in groupby(available_players,
                                                 key=self.sort_players)
     }
     for roster_position, players in players_by_roster_positions.items():
         next_restricted_roster_position = roster_position + 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, first_variable in restricted_players:
             for second_player, second_variable in players:
                 if first_player.team != second_player.team:
                     continue
                 solver.add_constraint([first_variable, second_variable],
                                       None, SolverSign.LTE, 1)
コード例 #7
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)]
コード例 #8
0
 def apply(self, solver, players_dict):
     optimizer = self.optimizer
     positions, spacing = optimizer.spacing_positions, optimizer.spacing
     if not spacing or not positions:
         return
     players_by_roster_positions = defaultdict(
         list)  # type: Dict[int, List[Tuple[Player, Any]]]
     for player, variable in players_dict.items():
         if player.roster_order is None or not list_intersection(
                 player.positions, positions):
             continue
         players_by_roster_positions[player.roster_order].append(
             (player, variable))
     for roster_position, players in players_by_roster_positions.items():
         next_restricted_roster_position = roster_position + 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, first_variable in restricted_players:
             for second_player, second_variable in players:
                 if first_player.team != second_player.team:
                     continue
                 solver.add_constraint([first_variable, second_variable],
                                       None, SolverSign.LTE, 1)
コード例 #9
0
 def apply_for_iteration(self, solver, players_dict, result):
     current_lineup = self.lineups[self.current_iteration]
     unswappable_players = current_lineup.get_unswappable_players()
     remaining_positions = get_remaining_positions(
         self.optimizer.settings.positions, unswappable_players)
     # lock selected players
     for player in unswappable_players:
         solver.add_constraint([players_dict[player]], None, SolverSign.EQ,
                               1)
     # set remaining positions
     positions_combinations = set([
         tuple(sorted(player.positions)) for player in players_dict.keys()
         if len(player.positions) > 1
     ])
     positions = get_positions_for_optimizer(remaining_positions,
                                             positions_combinations)
     players_for_optimization = set()
     for position, places in positions.items():
         players_with_position = [
             variable for player, variable in players_dict.items()
             if list_intersection(position, player.positions)
             and player not in unswappable_players
         ]
         players_for_optimization.update(players_with_position)
         solver.add_constraint(players_with_position, None, SolverSign.GTE,
                               places)
     # Set total players for optimization
     solver.add_constraint(players_for_optimization, None, SolverSign.EQ,
                           len(remaining_positions))
     # Exclude players with active games
     for player, variable in players_dict.items():
         if player not in unswappable_players and player.is_game_started:
             solver.add_constraint([players_dict[player]], None,
                                   SolverSign.EQ, 0)
     self.current_iteration += 1
コード例 #10
0
 def apply_for_iteration(self, solver, players_dict, result):
     current_lineup = self.lineups[self.current_iteration]
     unswappable_players = current_lineup.get_unswappable_players()
     positions = self.optimizer.settings.positions[:]
     # lock selected players
     for player in unswappable_players:
         for position in positions:
             if position.name == player.lineup_position:
                 positions.remove(position)
                 break
         solver.add_constraint([players_dict[player]], [1], SolverSign.EQ,
                               1)
     # set remaining positions
     positions = get_positions_for_optimizer(positions)
     for position, places in positions.items():
         players_with_position = [
             variable for player, variable in players_dict.items()
             if list_intersection(position, player.positions)
             and player not in unswappable_players
         ]
         coefficients = [1] * len(players_with_position)
         solver.add_constraint(players_with_position, coefficients,
                               SolverSign.GTE, places)
     # Exclude players with active games
     for player, variable in players_dict.items():
         if player not in unswappable_players and player.is_game_started:
             solver.add_constraint([players_dict[player]], [1],
                                   SolverSign.EQ, 0)
     self.current_iteration += 1
コード例 #11
0
 def test_positions_from_same_team_with_combo_position(self):
     self.optimizer.add_stack(PositionsStack(['PG', ('SF', 'C')]))
     lineups = list(self.optimizer.optimize(2))
     stack = ('PG', 'SF', 'C')
     players_in_stack = max([
         len([p for p in lineup if p.team == self.first_team and list_intersection(p.positions, stack)])
         for lineup in lineups
     ])
     self.assertEqual(players_in_stack, 2)
コード例 #12
0
ファイル: rules.py プロジェクト: lupka/pydfs-lineup-optimizer
 def apply(self, solver):
     if not self.optimizer.opposing_teams_position_restriction:
         return
     for game in self.optimizer.games:
         home_team_players = {player: variable for player, variable in self.players_dict.items()
                               if player.team == game.home_team}
         away_team_players = {player: variable for player, variable in self.players_dict.items()
                                if player.team == game.away_team}
         first_team_positions, second_team_positions = self.optimizer.opposing_teams_position_restriction
         for first_team_players, second_team_players in permutations([home_team_players, away_team_players], 2):
             first_team_variables = [variable for player, variable in first_team_players.items()
                                     if list_intersection(player.positions, first_team_positions)]
             second_team_variables = [variable for player, variable in second_team_players.items()
                                      if list_intersection(player.positions, second_team_positions)]
             aggregated_var = solver.add_variable(str(uuid4()), min_value=0, max_value=len(second_team_variables))
             solver.add_constraint(second_team_variables, None, SolverSign.EQ, aggregated_var)
             for var in first_team_variables:
                 solver.add_constraint([var, aggregated_var], [self.MULTIPLIER, 1],
                                       SolverSign.LTE, self.MULTIPLIER + self.optimizer.opposing_teams_max_allowed)
コード例 #13
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)
コード例 #14
0
 def _detect_teams_used_in_stacks(self, lineup):
     # type: (Lineup) -> Set[str]
     teams = set([player.team for player in lineup])
     all_teams_used_in_stacks = set()
     for stack in self.stacks_dict.keys():
         teams_used_in_stack = teams.copy()
         for positions in stack:
             teams_used_in_stack = teams_used_in_stack.intersection(
                 set([player.team for player in lineup if list_intersection(positions, player.positions)])
             )
         all_teams_used_in_stacks.update(teams_used_in_stack)
     return all_teams_used_in_stacks
コード例 #15
0
 def lock_player(self, player: DirtyPlayer, position: Optional[str] = None):
     player = self._clean_player(player)
     if player.max_exposure == 0:
         raise LineupOptimizerException(
             'Can\'t add this player to line up! Player has max exposure set to 0.'
         )
     if player in self._locked_players:
         raise LineupOptimizerException(
             'This player already in your line up!')
     if self.remaining_budget and player.salary > self.remaining_budget:
         raise LineupOptimizerException(
             'Can\'t add this player to line up! Your team is over budget!')
     if self.remaining_players < 1:
         raise LineupOptimizerException(
             'Can\'t add this player to line up! You already select all %s players!'
             % len(self.locked_players))
     max_from_one_team = self._settings.max_from_one_team
     if max_from_one_team:
         from_same_team = len(
             [p for p in self.locked_players if p.team == player.team])
         if from_same_team + 1 > max_from_one_team:
             raise LineupOptimizerException(
                 'You can\'t set more than %s players from one team.' %
                 max_from_one_team)
     position_for_player = None
     if position:
         if position not in self.available_positions:
             raise LineupOptimizerException(
                 'Position %s doesn\'t exist. Available positions are %s' %
                 (position, ','.join(self.available_positions)))
         for remaining_position in self._remaining_positions:
             if position:
                 if position == remaining_position.name:
                     position_for_player = remaining_position
                     break
         else:
             raise LineupOptimizerException('Position %s is filled.' %
                                            position)
         if not list_intersection(player.positions,
                                  position_for_player.positions):
             raise LineupOptimizerException(
                 'Player can\'t be set to position %s' % position)
     try:
         link_players_with_positions({player, *self._locked_players},
                                     self._settings.positions)
     except LineupOptimizerException:
         raise LineupOptimizerException('You\'re already select all %s\'s' %
                                        '/'.join(player.positions))
     if position_for_player:
         self._remaining_positions.remove(position_for_player)
     self._locked_players[player] = position_for_player
コード例 #16
0
 def _create_constraints(self, solver: Solver, players_dict: Dict[Player, Any]) -> None:
     for positions, total_for_positions in self.positions.items():
         min_exposure_players = [p for p in self.min_exposure_players if list_intersection(p.positions, positions)]
         if not min_exposure_players:
             continue
         total_force = sum(self.min_exposure_players[p] for p in min_exposure_players) - \
                       total_for_positions * (self.remaining_lineups - 1)
         if total_force > 0:
             variables = [players_dict[p] for p in min_exposure_players]
             total_force = min(total_force, ceil(total_force / self.remaining_lineups))
             solver.add_constraint(variables, None, SolverSign.GTE, total_force)
     for player, total_lineups in self.min_exposure_players.items():
         if total_lineups >= self.remaining_lineups:
             solver.add_constraint([players_dict[player]], None, SolverSign.EQ, 1)
コード例 #17
0
 def apply(self, solver, players_dict):
     extra_positions = self.optimizer.players_with_same_position
     positions = self.optimizer.get_positions_for_optimizer()
     for position, places in positions.items():
         extra = 0
         if len(position) == 1:
             extra = extra_positions.get(position[0], 0)
         players_with_position = [
             variable for player, variable in players_dict.items()
             if list_intersection(position, player.positions)
         ]
         coefficients = [1] * len(players_with_position)
         solver.add_constraint(players_with_position, coefficients,
                               SolverSign.GTE, places + extra)
コード例 #18
0
 def test_list_intersection(self):
     self.assertTrue(list_intersection(['PG'], ['SG', 'PG']))
     self.assertTrue(list_intersection(['SG', 'PG'], ['PG']))
     self.assertFalse(list_intersection(['PG'], ['SF', 'PF']))