Exemplo n.º 1
0
    def _partial_constraints_add(problem, row_increment, column_increment,
                                 index_to_row_to_column, first_to_second_to_is,
                                 name):
        t_square = len(index_to_row_to_column)
        t = int(round(math.sqrt(t_square)))
        assert t**2 == t_square

        first_index_to_second_index_to_row_to_column = LpVariable.matrix(
            name, (list(range(t_square)), list(
                range(t_square)), list(range(t - row_increment)),
                   list(range(t - column_increment))),
            lowBound=0,
            upBound=1,
            cat=LpInteger)

        for first_index in range(t_square):
            for second_index in range(t_square):
                for row in range(t - row_increment):
                    for column in range(t - column_increment):
                        problem += \
                            first_index_to_second_index_to_row_to_column[first_index][second_index][row][column] <= \
                            index_to_row_to_column[first_index][row][column]
                        problem += \
                            first_index_to_second_index_to_row_to_column[first_index][second_index][row][column] <= \
                            index_to_row_to_column[second_index][row + row_increment][column + column_increment]

                problem += first_to_second_to_is[first_index][second_index] == \
                           lpSum(SolverLP._flatten(
                               first_index_to_second_index_to_row_to_column[first_index][second_index]))

        return first_index_to_second_index_to_row_to_column
Exemplo n.º 2
0
    def _partial_objective(index_to_row_to_column,
                           first_to_second_to_probability, name):
        t_square = len(index_to_row_to_column)

        first_to_second_to_is = LpVariable.matrix(
            name, (list(range(t_square)), list(range(t_square))),
            lowBound=0,
            upBound=1,
            cat=LpInteger)

        objective = [
            lpDot(first_to_second_to_is[first][second],
                  first_to_second_to_probability[first][second])
            for first in range(t_square) for second in range(t_square)
            if first != second
        ]

        return first_to_second_to_is, objective
Exemplo n.º 3
0
def L1_E3(n, m, l, c, a, b, d, D):
    model = LpProblem('Bodegas', LpMinimize)

    # Variables de decisiones.
    var_name = [
        str(i) + str(j) for i in range(1, n + 1) for j in range(1, m + 1)
    ]
    var_name.sort()
    var_temp = LpVariable.matrix('x', var_name, cat='Integer', lowBound=0)
    x = np.array(var_temp).reshape(2, 5)

    # Funcion objetiva:
    fun_obj = lpSum(lpSum(c[j] * x[i][j] for j in range(m))
                    for i in range(n)) - lpSum(c[j] * d[j] for j in range(m))
    model += fun_obj

    # Restrinciones:
    for i in range(n):
        for k in range(l):
            model += lpSum(x[i][j] * a[j][k]
                           for j in range(m)) == lpSum(x[i][j] * b[i][k]
                                                       for j in range(m))
    for j in range(m):
        model += lpSum(x[i][j] for i in range(n)) >= d[j]
    for i in range(n):
        model += lpSum(x[i][j] for j in range(m)) >= D[i]
    for i in range(n):
        for j in range(m):
            model += x[i][j] >= 0

    model.solve()
    model_status = LpStatus[model.status]

    print('Modelo:', model)
    print(model_status)
    print('Ganancia total: ', model.objective.value())
    print('Variables de desiciones:')
    for var in model.variables():
        try:
            print(var.name, '=', var.value())
        except:
            print('Error: Couldn\'t find value')
Exemplo n.º 4
0
    def run_optimisation(self):
        # Declare problem instance, max/min problem
        self.prob = LpProblem("Squad", LpMaximize)

        # Declare decision variable - 1 if a player is part of the squad else 0
        self.decision = LpVariable.matrix("decision", list(self.data_length),
                                          0, 1, LpInteger)

        # Objective function -> Maximize specified optimisation parameter
        self.prob += lpSum(self.opt_param_list[i] * self.decision[i]
                           for i in self.data_length)

        # Constraint definition
        self.add_constraints()

        # solve problem
        self.prob.solve()

        # extract selected players and return
        return [
            self.opt_id_list[i] for i in self.data_length
            if self.decision[i].varValue
        ]
Exemplo n.º 5
0
    def _predict(self,
                 left_index_to_right_index_to_probability,
                 top_index_to_bottom_index_to_probability,
                 return_log_objective=False):
        print('Solving lp')

        t_square = left_index_to_right_index_to_probability.shape[0]
        t = int(round(math.sqrt(t_square)))
        assert t**2 == t_square

        problem = LpProblem(name="permutation", sense=LpMaximize)
        index_to_row_to_column = LpVariable.matrix(
            'index_to_row_to_column',
            (list(range(t_square)), list(range(t)), list(range(t))),
            lowBound=0,
            upBound=1,
            cat=LpInteger,
        )
        left_index_to_right_index_to_is_left, horizontal_objective = \
            SolverLP._partial_objective(
                index_to_row_to_column,
                left_index_to_right_index_to_probability,
                'left_index_to_right_index_to_is_left'
            )
        top_index_to_bottom_index_to_is_top, vertical_objective = \
            SolverLP._partial_objective(
                index_to_row_to_column,
                top_index_to_bottom_index_to_probability,
                'top_index_to_bottom_index_to_is_top'
            )

        problem += lpSum(horizontal_objective + vertical_objective)

        left_index_to_right_index_to_row_to_column_to_is = SolverLP._partial_constraints_add(
            problem, 0, 1, index_to_row_to_column,
            left_index_to_right_index_to_is_left,
            'left_index_to_right_index_to_row_to_column_to_is')

        top_index_to_bottom_index_to_row_to_column_to_is = SolverLP._partial_constraints_add(
            problem, 1, 0, index_to_row_to_column,
            top_index_to_bottom_index_to_is_top,
            'top_index_to_bottom_index_to_row_to_column_to_is')

        # Each element has single position
        for index in range(t_square):
            problem += 1 == lpSum(index_to_row_to_column[index][row][column]
                                  for row in range(t) for column in range(t))

        # Each position has single stander
        for row in range(t):
            for column in range(t):
                problem += 1 == lpSum(
                    index_to_row_to_column[index][row][column]
                    for index in range(t_square))

        # Here comes the voodoo, you do not really need, for sanity or debug probably
        problem += t * (t - 1) == lpSum(
            SolverLP._flatten(left_index_to_right_index_to_is_left))
        problem += t * (t - 1) == lpSum(
            SolverLP._flatten(top_index_to_bottom_index_to_is_top))

        problem.writeLP('current-problem.lp')
        problem.solve()

        if LpStatusOptimal != problem.status:
            print('Warning: status is ', LpStatus[problem.status])

        prediction = [
            np.argmax([
                index_to_row_to_column[index][row][column].value()
                for row in range(t) for column in range(t)
            ]) for index in range(t_square)
        ]

        return (prediction, None) if return_log_objective else prediction
Exemplo n.º 6
0
def optimise_selection(
    schedule_input: pd.DataFrame,
    selection_limit: int,
    black_points_limit: int,
    rounds: List[str],
    loser: Optional[str] = None,
) -> Dict[str, Any]:
    """
    Optimise player selection.
    :param schedule_input: Players and their schedule.
    :param selection_limit: Number of players to choose.
    :param black_points_limit: Maximum number of black points.
    :param rounds: Rounds to play
    :param loser: Selected loser
    :return: Optimal selection
    """
    LOGGER.info("Optimising selection")

    schedule = schedule_input.copy()
    black_extra = 0
    selection_limit_extra = 0
    extra_loss = 0

    if loser:
        loser_record = schedule[schedule["player"].str.lower() ==
                                loser.lower()].iloc[0]

        if loser_record.empty:
            LOGGER.warning("Unable to find player %s in draw", loser)
            loser = None
        else:
            loser = loser_record.player

            # extra_loss = TennisPoolEmulator.rounds_to_score(
            #     rounds=loser_record.rounds,
            #     black=loser_record.black,
            #     loser=True
            # )

            extra_loss = TennisPoolEmulator.probabilities_to_score(
                round_probs=loser_record[rounds],
                black=loser_record.black,
                loser=True)

            schedule.loc[schedule.player == loser, "potency"] = extra_loss

            black_extra = loser_record.black
            selection_limit_extra = 1
            LOGGER.info(
                "Allowing %d extra black points, because of your selected loser",
                black_extra,
            )
            LOGGER.info(
                "Adding the loser to your selection, and simultaneously increasing the limit of your"
                "selection, such that your loser is taken into account.")

    black_points_limit += black_extra

    players = schedule["player"].tolist()
    potency = schedule["potency"].tolist()
    black_points = schedule["black"].tolist()

    param_player = range(len(schedule))

    # Declare problem instance, maximization problem
    probability = LpProblem("PlayerSelection", LpMaximize)

    # Declare decision variable x, which is 1 if a
    # player is part of the selection and 0 else
    param_x = LpVariable.matrix("x", list(param_player), 0, 1, LpInteger)

    # Objective function -> Maximise potency
    probability += sum(potency[p] * param_x[p] for p in param_player)

    # Constraint definition
    probability += sum(param_x[p]
                       for p in param_player) == (selection_limit +
                                                  selection_limit_extra)
    probability += (sum(black_points[p] * param_x[p]
                        for p in param_player) <= black_points_limit)

    if loser:
        probability += param_x[players.index(loser)] == 1

    # Start solving the problem instance
    probability.solve()

    # Extract solution
    player_selection = [
        players[p] for p in param_player if param_x[p].varValue
    ]

    LOGGER.info("Optimiser finished")

    if loser:
        LOGGER.warning(
            "Do note you're going to lose %d points because of your loser.",
            -extra_loss)

    return {
        "schedule":
        schedule[schedule["player"].isin(
            player_selection)].copy().reset_index(),
        "loser":
        extra_loss,
    }
from pulp import *
players = bbal_data['Player']
salary = bbal_data['Salary']
std_score = bbal_data['STD_Score']
points = bbal_data['PTS']
fix = bbal_data['Fix']
owner = bbal_data['Status']

P = range(len(players))
S = 200

prob = LpProblem("Optimal_Lineup", LpMaximize)

# Declare decision variable x, which is 1 if a
# player is part of the portfolio and 0 else
x = LpVariable.matrix("x", list(P), 0, 1, LpInteger)

# Objective function -> Maximize z-score
prob += sum(std_score[p] * x[p] for p in P)

# Constraint definition
prob += sum(x[p] for p in P) == 13
prob += sum(salary[p] * x[p] for p in P) <= 200

# Can add more constraints

# Start solving the problem instance
prob.solve()

# Extract solution
lineup = [players[p] for p in P if x[p].varValue]