Преобразование логического c ограничения в python код целлюлозы - PullRequest
0 голосов
/ 19 января 2020

Я начал работать над проблемой в последние несколько дней ...

Компания планирует свой бизнес в течение трех месяцев. Он может производить 110 единиц по цене 600 каждый. Минимальная сумма, которую он должен производить в месяц, составляет 15 единиц, если активна (но, конечно, он может выбрать закрытие в течение месяца и произвести 0 единиц). Каждый месяц он может производить 60 единиц продукции по цене 660 штук. Хранение единицы в течение одного месяца стоит 20 $ за единицу в месяц. Отдел маркетинга прогнозировал продажи на 100, 130 и 150 штук на следующие три месяца соответственно. Цель состоит в том, чтобы удовлетворять спрос каждый месяц при минимизации общей стоимости.

Я пришел к выводу, что нам нужна целевая функция в форме min [Sum (i = 0..3) 600 * x1 + 660 * х2 + х3 * 20]. Нам нужно добавить некоторые ограничения на x1> = 15 и на x2 0 <= x2 <= 60 Также нам понадобится еще одно ограничение для каждого месяца ... Для первого i = 1 => x1 + x2 = 100 - x3last (x3last - дополнительная переменная, которая должна содержать сумму, существующую в депозите за предыдущий месяц), и для i = 2 и i = 3 те же ограничения. Я понятия не имею, как написать это в целлюлозе, и я был бы признателен за помощь. Thx ^ _ ^

1 Ответ

1 голос
/ 26 января 2020

Я склонен согласиться с @Erwin, что вам следует сосредоточиться на формулировании проблемы как линейной программы. Затем легко перевести это в код в PULP или в одну из многих других библиотек / инструментов / языков PULP.

В качестве примера - давайте проработаем этот процесс для примера проблемы, которую вы написали в своем Вопрос.

Переменные решения

Первое, что нужно решить, это то, что вы можете / должны решить. Этот набор информации называется переменными решения. Выбор лучших / самых простых переменных решения для вашей проблемы приходит с практикой - важно то, что как только вы узнаете значения переменных, у вас будет уникальное решение проблемы.

Здесь я бы предложил следующее. Они предполагают, что прогнозы спроса идеальны. За каждый месяц i:

  • Должна ли быть открыта производственная линия - o[i]
  • Сколько нужно произвести в этом месяце - p[i]
  • Сколько нужно хранить в хранилище на следующий месяц - s[i]
  • Сколько можно получить извне - e[i]

Функция цели

Цель в вашем Случай очевиден - минимизировать общую стоимость. Таким образом, мы можем просто записать это: sum(i=0...2)[p[i]*600 + s[i]*20 + e[i]*660]

Ограничения

Давайте сразу же поднимем наше описание вашей проблемы:

"Это может произвести 110 единиц по цене 600 каждый. Минимальная сумма, которую он должен производить в месяц, составляет 15 единиц, если активен (но, конечно, он может выбрать закрытие в течение месяца и произвести 0 единиц). "

p[i] >= o[i]*15 
p[i] <= o[i]*110

Первое ограничение устанавливает минимальное производство, равное 15, если производство открыто в этом месяце (o[i] == 1), если производство не открыто, это ограничение не действует. Второе ограничение устанавливает максимальное значение на p[i], равное 110, если производство открыто, и максимальное производство, равное 0, если производство закрывается в этом месяце (o[i] == 0).

"Каждый месяц он может вычитать производство 60 единиц, по 660 штук каждый "

e[i] <= 60

". Маркетинговый отдел прогнозировал продажи 100, 130 и 150 единиц на следующие три месяца соответственно. Цель - удовлетворить спрос каждый месяц при минимизации общей стоимости. " Если мы объявляем продажи в каждом месяце продажами [i], мы можем определить наше «ограничение потока» следующим образом:

p[i] + e[i] + s[i-1] == s[i] + sales[i]

Способ думать об этом ограничении - ввод слева и вывод право. Входами единиц являются производство, внешнее производство и материалы, снятые со склада с прошлого месяца. Выходные данные - это единицы, оставленные / помещенные в хранилище на следующий месяц и продажи.

Наконец, в коде:

from pulp import *
all_i = [1,2,3]
all_i_with_0 = [0,1,2,3]
sales = {1:100, 2:130, 3:150}

o = LpVariable.dicts('open', all_i, cat='Binary')
p =LpVariable.dicts('production', all_i, cat='Linear')
s =LpVariable.dicts('stored', all_i_with_0, lowBound=0, cat='Linear')
e =LpVariable.dicts('external', all_i, lowBound=0, cat='Linear')

prob = LpProblem("MinCost", LpMinimize)
prob += lpSum([p[i]*600 + s[i]*20 + e[i]*660 for i in all_i]) # Objective
for i in all_i:
    prob += p[i] >= o[i]*15
    prob += p[i] <= o[i]*110
    prob += e[i] <= 60
    prob += p[i] + e[i] + s[i-1] == sales[i] + s[i]

prob += s[0] == 0 # No stock inherited from previous monts
prob.solve()

# The status of the solution
print ("Status:", LpStatus [prob.status])

# Dislay the optimums of each var
for v in prob.variables ():
    print (v.name, "=", v.varValue)

# Objective fcn
print ("Obj. Fcn: ", value(prob.objective))

Что возвращает:

Status: Optimal
external_1 = 0.0
external_2 = 10.0
external_3 = 40.0
open_1 = 1.0
open_2 = 1.0
open_3 = 1.0
production_1 = 110.0
production_2 = 110.0
production_3 = 110.0
stored_0 = 0.0
stored_1 = 10.0
stored_2 = 0.0
stored_3 = 0.0
Obj. Fcn:  231200.0
...