Смешанная целочисленная программа python

У меня есть эта проблема оптимизации, когда я пытаюсь максимизировать столбец z на основе уникального значения из столбца X, но также в рамках ограничения, согласно которому каждое из уникальных значений, выбранных из X, добавленного столбца Y, больше всего меньше или равно (в этот пример) 23.

Например, у меня есть этот образец данных:

X  Y  Z
1  9  25    
1  7  20     
1  5  5
2  9  20 
2  7  10 
2  5  5    
3  9  10 
3  7  5
3  5  5

Результат должен выглядеть так:

   X  Y  Z 

  1  9  25  
  2  9  20     
  3  5  5 

Это реплика для настроить оптимизацию линейного программирования в R с помощью LpSolve? с решением, но мне нужно то же самое в python.


person blehblehbleh    schedule 24.01.2018    source источник
comment
В ваших примерных данных нет столбца 3 5 5, как он попадает туда в выходных данных примера? Я также не понимаю ограничения, предложение сломано.   -  person Graipher    schedule 24.01.2018
comment
К сожалению, мой плохой ... так что, похоже, мне нужны двоичные ограничения в форме, в которой результат выбирает одну строку из каждой группы (столбец X; может быть, как рюкзак с несколькими вариантами выбора) вместе с другим ограничением, что сумма (Y) для выбранных строк кратно ‹ =23   -  person blehblehbleh    schedule 24.01.2018
comment
при чем здесь ваш вопрос? Это найти пару x,y, где сумма x+y<23?   -  person Usernamenotfound    schedule 24.01.2018
comment
Не так сложно сделать. Но сначала покажите некоторые предварительные попытки или исследование (выглядит так: напишите этот код для меня прямо сейчас)!   -  person sascha    schedule 24.01.2018
comment
@Usernamenotfound Нет. Он хочет максимизировать z, выбирая строки, в то время как для каждого x может быть выбрана только одна строка, и все соответствующие значения y выбранных строк должны быть суммированы ‹= 23.   -  person sascha    schedule 24.01.2018
comment
Мне жаль, что я не так хорошо разбираюсь в python; Я пытался использовать Pulp, но при указании целевой функции или ограничения, как мне указать выбранную строку, как я думаю, что написания модели +=pulp.lpSum(df['Z']) будет недостаточно   -  person blehblehbleh    schedule 24.01.2018
comment
Вы, очевидно, должны играть по правилам пульпы. Читайте документы. Pulp не знает фреймы данных pandas. В вопросе отсутствуют детали. Есть альтернативы целлюлозе, но некоторые из них не просты в установке. Но это вообще не рассматривается/не указывается в вопросе. Размеры реального мира также отсутствуют. Это может оказать некоторое влияние на инструмент моделирования и решатель.   -  person sascha    schedule 24.01.2018
comment
Контекст. Для каждого элемента мы создаем отдельную модель, предсказывающую стоимость, и модель, предсказывающую стоимость в разных состояниях. Каждый элемент может находиться в одном из 11 возможных состояний. Каждое состояние имеет связанную ценность/вознаграждение наряду со стоимостью и доходом. Мне нужно выбрать одно из состояний для каждого элемента, чтобы сумма (значение) была максимальной и глобальная рентабельность инвестиций, т. Е. Сумма (доход)/сумма (затраты) ›= target_roi. Это очень похоже на фиктивную задачу, о которой я упоминал выше, и также реализовал решение в R с помощью lpSolve. Теперь мне нужно реализовать то же самое на питоне, и я не очень понял синтаксис.   -  person blehblehbleh    schedule 24.01.2018


Ответы (1)


Для тех, кому нужна помощь, чтобы начать работу с пульпой в Python, можно обратиться к http://ojs.pythonpapers.org/index.php/tppm/article/view/111

Репозиторий Github: https://github.com/coin-or/pulp/tree/master/doc/KPyCon2009 тоже может пригодиться.

Ниже приведен код на python для фиктивной задачи.

            import pandas as pd
            import pulp

            X=[1,1,1,2,2,2,3,3,3]
            Y=[9,7,5,9,7,5,9,7,5]
            Z=[25,20,5,20,10,5,10,5,5]

            df = pd.DataFrame({'X':X,'Y':Y,'Z':Z})
            allx = df['X'].unique()
            possible_values = [(w,b) for w in allx for b in range(1,4)]

            x = pulp.LpVariable.dicts('arr', (allx, range(1,4)),
                                        lowBound = 0,
                                        upBound = 1,
                                        cat = pulp.LpInteger)

            model = pulp.LpProblem("Optim", pulp.LpMaximize)
            model += sum([x[w][b]*df[df['X']==w].reset_index()['Z'][b-1] for (w,b) in possible_values])

            model += sum([x[w][b]*df[df['X']==w].reset_index()['Y'][b-1] for (w,b) in possible_values]) <= 23, \
                                        "Maximum_number_of_Y"

            for value in allx:
                model += sum([x[w][b] for (w,b) in possible_values if w==value])>=1

            for value in allx:
                model += sum([x[w][b] for (w,b) in possible_values if w==value])<=1

            ##View definition
            model

            model.solve()

            print("The choosen rows are out of a total of %s:"%len(possible_values))
            for v in model.variables():
                print v.name, "=", v.varValue

Для решения в R

    d=data.frame(x=c(1,1,1,2,2,2,3,3,3),y=c(9,7,5,9,7,5,9,7,5),z=c(25,20,5,20,10,5,10,5,3))
            library(lpSolve)
            all.x <- unique(d$x)
            d[lp(direction = "max",
                 objective.in = d$z,
                 const.mat = rbind(outer(all.x, d$x, "=="), d$y),
                 const.dir = rep(c("==", "<="), c(length(all.x), 1)),
                 const.rhs = rep(c(1, 23), c(length(all.x), 1)),
                 all.bin = TRUE)$solution == 1,]
person blehblehbleh    schedule 02.03.2018