Ограничение пульпы Python - Удвоение веса любой переменной, которая вносит наиболее - PullRequest
0 голосов
/ 14 ноября 2018

Я пытаюсь использовать http://www.philipkalinda.com/ds9.html для настройки ограниченной оптимизации.

prob = pulp.LpProblem('FantasyTeam', pulp.LpMaximize)

        decision_variables = []

        res = self.team_df
        # Set up the LP

        for rownum, row in res.iterrows():
            variable = str('x' + str(rownum))
            variable = pulp.LpVariable(str(variable), lowBound = 0, upBound = 1, cat= 'Integer') #make variables binary
            decision_variables.append(variable)

        print ("Total number of decision_variables: " + str(len(decision_variables)))


        total_points = ""


        for rownum, row in res.iterrows():
            for i, player in enumerate(decision_variables):
                if rownum == i:
                    formula = row['TotalPoint']* player
            total_points += formula

        prob += total_points
        print ("Optimization function: " + str(total_points))

Выше, однако, создается оптимизация, где, если очки, заработанные как x1 = X1, x2 = X2 .... и xn = Xn, это максимизирует x1 * X1 + x2 * X2 + ..... + xn * XN. Здесь xi - очки, заработанные переменной XI. Однако в моем случае мне нужно удвоить баллы для переменной, которая зарабатывает наибольшее количество баллов. Как мне это настроить?

Увеличить OBJ: 38,1 x0 + 52,5 x1 + 31,3 x10 + 7,8 x11 + 42,7 x12 + 42,3 x13 + 4,7 x14 + 49,5х15 + 21,2х16 + 11,8х17 + 1,4х18 + 3,2х2 + 20,8х3 + 1,2х4 + 24 x 5 + 25,9 x 6 + 27,8 x 7 + 6,2 x 8 + 41 x 9

Когда я максимизирую, сумма x1 сбрасывается, но когда я максимизирую, когда ведущий получает двойные очки, она должна быть там

Вот ограничения, которые я использую: -

Subject To
_C1: 10.5 x0 + 21.5 x1 + 17 x10 + 7.5 x11 + 11.5 x12 + 12 x13 + 7 x14 + 19 x15
 + 10.5 x16 + 5.5 x17 + 6.5 x18 + 6.5 x2 + 9.5 x3 + 9 x4 + 12 x5 + 12 x6
 + 9.5 x7 + 7 x8 + 14 x9 <= 100
_C10: x12 + x2 + x6 >= 1
_C11: x10 + x11 + x17 + x3 <= 4
_C12: x10 + x11 + x17 + x3 >= 1
_C13: x0 + x10 + x11 + x12 + x13 + x14 + x15 + x18 + x2 <= 5
_C14: x0 + x10 + x11 + x12 + x13 + x14 + x15 + x18 + x2 >= 3
_C15: x1 + x16 + x17 + x3 + x4 + x5 + x6 + x7 + x8 + x9 <= 5
_C16: x1 + x16 + x17 + x3 + x4 + x5 + x6 + x7 + x8 + x9 >= 3
_C2: x0 + x1 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + x18 + x2 + x3
 + x4 + x5 + x6 + x7 + x8 + x9 = 8
_C3: x0 + x14 + x16 + x5 <= 4
_C4: x0 + x14 + x16 + x5 >= 1
_C5: x15 + x18 + x4 + x7 + x8 <= 4
_C6: x15 + x18 + x4 + x7 + x8 >= 1
_C7: x1 + x13 + x9 <= 4
_C8: x1 + x13 + x9 >= 1
_C9: x12 + x2 + x6 <= 4

Естественно, максимизация A + B + C + D не максимизирует максимум (2A + B + C + D, A + 2B + C + D, A + B + 2C + D, A + B + C + 2D )

1 Ответ

0 голосов
/ 19 ноября 2018

Я собираюсь ответить на вопрос, который, по-моему, вы задаете, и вы можете исправить меня, если я ошибаюсь. Мое понимание вашего вопроса:

  • У меня есть серия двоичных переменных x0...xN, и, если переменная включена, получает несколько очков. Если он не включен, он не получает очков.
  • Существуют некоторые ограничения, которые применяются к выбору
  • Если (и только если) переменная выбрана и если (и только если) это выбранная переменная, которая получает наибольшее количество баллов, то эта конкретная переменная получает двойные баллы
  • Цель состоит в том, чтобы максимизировать общее количество очков, включая удвоение самого высокого балла.

Предполагая, что это ваш вопрос, это фиктивный пример, который делает это. По существу, мы добавляем вспомогательную двоичную переменную для каждой переменной, которая является истинной, если (если и только если) эта переменная набирает наибольшее количество баллов:

from pulp import *

n_vars = 4
idxs = range(n_vars)
points = [2.0, 3.0, 4.0, 5.0]

prob = pulp.LpProblem('FantasyTeam', pulp.LpMaximize)

# Variables
x = LpVariable.dicts('x', idxs, cat='Binary')
x_highest_score = LpVariable.dicts('x_highest_score', idxs, cat='Binary')

# Objective
prob += lpSum([points[i]*(x[i] + x_highest_score[i]) for i in idxs])

# Constraints
# Exactly one item has highest score:
prob += lpSum([x_highest_score[i] for i in idxs]) == 1

# If a score is to be highest, it has to be chosen
for i in idxs:
    prob += x_highest_score[i] <= x[i]

# And some selection constraints:
prob += x[0] + x[1] + x[2] + 1.5*x[3] <= 3
prob += x[0] + x[2] + 3*x[3] <= 3
prob += x[0] + x[1] + x[2] + 2*x[3] <= 3
# etc...

# Solve problem
prob.solve()

# Get soln
x_soln = [x[i].varValue for i in idxs]
x_highest_soln = [x_highest_score[i].varValue for i in idxs]

# And print the outputs
print (("Status: "), LpStatus[prob.status])
print ("Total points: ", value(prob.objective))
print ("x = ", x_soln)
print ("x_highest_soln = ", x_highest_soln)

Это должно вернуть следующее:

Status:  Optimal
Total points:  13.0
x =  [0.0, 1.0, 0.0, 1.0]
x_highest_soln =  [0.0, 0.0, 0.0, 1.0]

Если вы отключите опцию двойных точек, изменив ограничение на следующее:

prob += lpSum([x_highest_score[i] for i in idxs]) == 1

т.е. ни один из них не наберет наибольшее количество баллов, вы найдете другой выбор.

...