LP в целлюлозе — проблема с изменяемым решением

#python #linear-programming #pulp

Вопрос:

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

 my_problem  = lineup_wk1[i] == starting_lineup[i]   trans_in[i] - trans_out[i] for i in players  

где написано

 File "lt;ipython-input-21-42d75f1d2bc3gt;", line 4  my_problem  = lineup_wk1[i] == starting_lineup[i]   trans_in[i] - trans_out[i] for i in players  ^ SyntaxError: invalid syntax  

Полный код таков:

 players = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'] points = [4.2, 5.3, 6.0, 5.5, 4.5, 5.7, 4.8, 6.9] cost = [4.5, 5.0, 5.1, 4.9, 5.2, 5.7, 5.2, 6.0] starting_team = [1,0,1,0,1,0,1,0]  player_points = dict(zip(players, points)) player_cost = dict(zip(players, cost)) starting_lineup = dict(zip(players, starting_team))  my_problem = pulp.LpProblem('LP_model', pulp.LpMaximize) lineup_wk1 = pulp.LpVariable.dict('lineup_wk1_ % s', players, lowBound=0, upBound=1, cat=pulp.LpBinary) trans_in = pulp.LpVariable.dict('trans_in_ % s', players, lowBound=0, upBound=1, cat=pulp.LpBinary) trans_out = pulp.LpVariable.dict('trans_out_ % s', players, lowBound=0, upBound=1, cat=pulp.LpBinary)  my_problem  = sum([player_points[i] * (lineup_wk1[i]) for i in players])  my_problem  = sum([lineup_wk1[i] for i in players]) lt;= 4 my_problem  = sum(trans_in[i] for i in players) lt;=2 my_problem  = sum(trans_in[i] for i in players) == sum(trans_out[i] for i in players) my_problem  = lineup_wk1[i] == starting_lineup[i]   trans_in[i] - trans_out[i] for i in players  my_problem.solve()  

Комментарии:

1. Что вы имели for i in players в виду?

2. Или, скорее, какой вы хотели видеть ценность с правой стороны my_problem = ? Номер? Список номеров? Словарь?

3. В любом случае, у вас есть проблема, когда вы пытаетесь использовать синтаксис, который не имеет смысла, и решение этой проблемы состоит в том, чтобы сначала изучить основы языка программирования, который вы используете.

4. Мое намерение состоит в том, чтобы левая часть константы равнялась правой части ограничения, поэтому lineup_wk1 = starting_lineup trans_in — trans_out, поскольку это словари со списками чисел, я подумал, что [i] представляет i строку списка, и поэтому, говоря «я в игроках», я имею в виду, сделайте это для каждой строки в списке.

5. @mkrieger1 синтаксис в значительной степени верен pulp . pulp переопределяет добавление, поэтому my_problem = ... это правильный способ добавления юридического выражения в модель. Независимо от того, находимся ли мы здесь по уши… мы еще посмотрим! 🙂

Ответ №1:

Таким образом, основная вещь, которая вас подвешивает, — это формулировка правильного pulp выражения для вашего ограничения. Вы путаете выражения типа суммирования / генератора, когда хотите создать ограничение для каждого игрока. Таким образом, вы не суммируете и не можете сделать for i in players это в одной строке. Вместо этого в любое время, когда вашей модели pulp требуется ограничение «для каждого», вам нужно будет создать цикл (самый простой способ) и использовать цикл для создания полного набора ограничений. В моем примере ниже цикл создаст 8 отдельных ограничений, по одному для каждого игрока.

Примечание: Я не проверяю логику вашей модели, поэтому, если есть математическая ошибка, вам нужно будет покопаться. У вас здесь хорошая структура, но я настоятельно рекомендую вам переработать модель, чтобы сделать эту простую проблему с рюкзаком (у вас уже есть детали), чтобы создать наилучшую возможную команду ограниченного размера и ограниченной стоимости. Эти ограничения очень просты. Если вы сможете заставить это работать, вы можете затем приступить к этому более творческому ограничению входа и выхода. 🙂

 # pulp player amp; team  import pulp  players = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'] points = [4.2, 5.3, 6.0, 5.5, 4.5, 5.7, 4.8, 6.9] cost = [4.5, 5.0, 5.1, 4.9, 5.2, 5.7, 5.2, 6.0] starting_team = [1,0,1,0,1,0,1,0]  player_points = dict(zip(players, points)) player_cost = dict(zip(players, cost)) starting_lineup = dict(zip(players, starting_team))  my_problem = pulp.LpProblem('LP_model', pulp.LpMaximize) lineup_wk1 = pulp.LpVariable.dict('lineup_wk1_ % s', players, lowBound=0, upBound=1, cat=pulp.LpBinary) trans_in = pulp.LpVariable.dict('trans_in_ % s', players, lowBound=0, upBound=1, cat=pulp.LpBinary) trans_out = pulp.LpVariable.dict('trans_out_ % s', players, lowBound=0, upBound=1, cat=pulp.LpBinary)  my_problem  = sum([player_points[i] * (lineup_wk1[i]) for i in players])  my_problem  = sum([lineup_wk1[i] for i in players]) lt;= 4 my_problem  = sum(trans_in[i] for i in players) lt;=2 my_problem  = sum(trans_in[i] for i in players) == sum(trans_out[i] for i in players) # this will make a "for each player" constraint. There is no summation...  # note the change from i -gt; "player" which makes this more readable. for player in players:   my_problem  = lineup_wk1[player] == starting_lineup[player]   trans_in[player] - trans_out[player]   my_problem.solve()  

Комментарии:

1. Большое спасибо за ваш вклад, и использование цикла For решает проблему. У меня действительно есть больший фрагмент кода, который имеет гораздо больше ограничений, но они работают нормально, и этот шаг меня смутил, поэтому я создал простую проблему для демонстрации (и ее легко решить в качестве проверки). Я никогда раньше не думал о рюкзаке, но быстрый поиск в Google, кажется, это то, что я буду исследовать намного дальше. Большое спасибо за ваш вклад