Я склонен согласиться с @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