def _create_constraints( self, solver: Solver, players_dict: Dict[Player, Any], ): players_in_stack = defaultdict(set) # type: Dict[Player, Set[Any]] for stack in self.stacks: combinations_variables = {} for group in stack.groups: group_name = self._build_group_name(group) sub_groups = group.get_all_players_groups() if self._is_reached_exposure(group) or ( group.parent and self._is_reached_exposure(group.parent)): for group_players, _, max_from_group in sub_groups: if max_from_group is None: continue solver.add_constraint( [players_dict[p] for p in group_players], None, SolverSign.EQ, 0) max_group = sorted(sub_groups, key=lambda t: t[1])[0] if max_group[1]: solver.add_constraint( [players_dict[p] for p in max_group[0]], None, SolverSign.LTE, max_group[1] - 1) continue solver_variable = None if any(sub_group[1] is not None for sub_group in sub_groups): solver_variable = solver.add_variable(group_name) combinations_variables[group_name] = solver_variable for group_players, group_min, group_max in sub_groups: variables = [players_dict[p] for p in group_players] if group_min is not None: if not stack.can_intersect: for player in group_players: players_in_stack[player].add(solver_variable) solver.add_constraint(variables, None, SolverSign.GTE, group_min * solver_variable) if group_max is not None: solver.add_constraint(variables, None, SolverSign.LTE, group_max) elif group_max is not None: solver_variable = solver.add_variable( group_name, min_value=0, max_value=group_max) solver.add_constraint(variables, None, SolverSign.EQ, solver_variable) if combinations_variables: solver.add_constraint(combinations_variables.values(), None, SolverSign.GTE, 1) for player, stacks_vars in players_in_stack.items(): if len(stacks_vars) > 1: solver.add_constraint(stacks_vars, None, SolverSign.LTE, 1)
def _create_constraints( self, solver: Solver, players_dict: Dict[Player, Any], ): players_in_stack = defaultdict(set) # type: Dict[Player, Set[Any]] for stack in self.stacks: combinations_variables = {} for group in stack.groups: group_name = ('stack_%s_%s' % (stack.uuid, group.uuid)).replace('-', '_') sub_groups = group.get_all_players_groups() if group.max_exposure is not None and group.max_exposure <= self.used_groups[group_name] / self.total_lineups: max_group = sorted(sub_groups, key=lambda t: t[1])[0] variables = [players_dict[p] for p in max_group[0]] solver.add_constraint(variables, None, SolverSign.LTE, max_group[1] - 1) continue if any(sub_group[1] is not None for sub_group in sub_groups): solver_variable = solver.add_variable(group_name) combinations_variables[group_name] = solver_variable for group_players, group_min, group_max in sub_groups: variables = [players_dict[p] for p in group_players] if group_min is not None: if not stack.can_intersect: for player in group_players: players_in_stack[player].add(solver_variable) solver.add_constraint(variables, None, SolverSign.GTE, group_min * solver_variable) if group_max is not None: solver.add_constraint(variables, None, SolverSign.LTE, group_max) if combinations_variables: solver.add_constraint(combinations_variables.values(), None, SolverSign.GTE, 1) for player, stacks_vars in players_in_stack.items(): if len(stacks_vars) > 1: solver.add_constraint(stacks_vars, None, SolverSign.LTE, 1)
def _create_constraints( self, solver: Solver, ): players_in_stack = defaultdict(set) # type: Dict[Player, Set[Any]] for stack in self.stacks: combinations_variables = {} for group in stack.groups: group_name = self._build_group_name(group) sub_groups = group.get_all_players_groups() if self.exposure_strategy.is_reached_exposure(group_name) or \ (group.parent and self.exposure_strategy.is_reached_exposure( self._build_group_name(group.parent))): for sub_group in sub_groups: if sub_group.max_from_group is None: continue solver.add_constraint( [self.players_dict[p] for p in sub_group.players], None, SolverSign.EQ, 0) max_group = sorted( sub_groups, key=lambda g: g.min_from_group)[0] # type: ignore if max_group.min_from_group: solver.add_constraint( [self.players_dict[p] for p in max_group.players], None, SolverSign.LTE, max_group.min_from_group - 1) continue solver_variable = None if any(sub_group.min_from_group is not None for sub_group in sub_groups): solver_variable = solver.add_variable(group_name) if group.depends_on is None: combinations_variables[group_name] = solver_variable for sub_group in sub_groups: variables = [ self.players_dict[p] for p in sub_group.players if p in self.players_dict ] if sub_group.min_from_group is not None: if not stack.can_intersect: for player in sub_group.players: players_in_stack[player].add(solver_variable) solver.add_constraint( variables, None, SolverSign.GTE, sub_group.min_from_group * solver_variable) if sub_group.max_from_group is not None: solver.add_constraint(variables, None, SolverSign.LTE, sub_group.max_from_group) elif sub_group.max_from_group is not None: solver_variable = solver.add_variable( group_name, min_value=0, max_value=sub_group.max_from_group) solver.add_constraint(variables, None, SolverSign.EQ, solver_variable) if group.depends_on is not None: total_players_var = solver.add_variable( 'total_players_%s' % group_name, min_value=0, max_value=sub_group.max_from_group or len(variables)) solver.add_constraint(variables, None, SolverSign.EQ, total_players_var) depend_var = self.players_dict.get(group.depends_on, 0) solver.add_constraint( [total_players_var], None, SolverSign.GTE, depend_var * (sub_group.min_from_group or 1)) if group.strict_depend: solver.add_constraint( [total_players_var], None, SolverSign.LTE, depend_var * (sub_group.max_from_group or len(variables))) if combinations_variables: solver.add_constraint(combinations_variables.values(), None, SolverSign.GTE, 1) for player, stacks_vars in players_in_stack.items(): if len(stacks_vars) > 1: solver.add_constraint(stacks_vars, None, SolverSign.LTE, 1)