Вот краткий ответ в виде наброска рабочего примера:
Создайте проблему и добавьте жесткие ограничения и цель.
prob = LpProblem("My Problem", LpMinimize)
....
После того, как вы это сделаете, определите мягкое (эластичное) ограничение и добавьте его к задаче с помощью pulp.prob.extend()
, например:
c_e_LHS = LpAffineExpression([(var1,coeff1), (var2,coeff2)]) # example left-hand-side expression
c_e_RHS = 30 # example right-hand-side value
c_e_pre = LpConstraint(e=el_constr_LHS, sense=-1, name='pre-elastic', rhs=c_e_RHS) # The constraint LHS = RHS
c_e = c_e_pre.makeElasticSubProblem(penalty=100, proportionFreeBoundList=[.02,.02]) # The definition of the elasticized constraint
prob.extend(c_e) # Adding the constraint to the problem
На этом этапе проблема была изменена и теперь включает мягкое (эластичное) ограничение, и вы можете ее решить. $ \ qed $.
Вот более развернутый ответ: на этот вопрос ответят в группе Google Pulp-or-Disc в разделе добавление эластичного ограничения. Я создал следующий пример для своих целей, основываясь на этом обсуждении и на чем дольше формулировка задачи смешивания на сайте документации PuLP.
Сначала вы создаете проблему:
from pulp import *
prob = LpProblem("The Whiskas Problem", LpMinimize)
Составьте список ингредиентов:
Ingredients = ['CHICKEN', 'BEEF', 'MUTTON', 'RICE', 'WHEAT', 'GEL']
Составлен словарь стоимости каждого ингредиента:
costs = {'CHICKEN': 0.013,
'BEEF': 0.008,
'MUTTON': 0.010,
'RICE': 0.002,
'WHEAT': 0.005,
'GEL': 0.001}
Создается словарь процентного содержания белка в каждом из ингредиентов:
proteinPercent = {'CHICKEN': 0.100,
'BEEF': 0.200,
'MUTTON': 0.150,
'RICE': 0.000,
'WHEAT': 0.040,
'GEL': 0.000}
Создается словарь процентного содержания жира в каждом из ингредиентов:
fatPercent = {'CHICKEN': 0.080,
'BEEF': 0.100,
'MUTTON': 0.110,
'RICE': 0.010,
'WHEAT': 0.010,
'GEL': 0.000}
Создается словарь процентного содержания клетчатки в каждом из ингредиентов:
fibrePercent = {'CHICKEN': 0.001,
'BEEF': 0.005,
'MUTTON': 0.003,
'RICE': 0.100,
'WHEAT': 0.150,
'GEL': 0.000}
Создается словарь процента соли в каждом из ингредиентов:
saltPercent = {'CHICKEN': 0.002,
'BEEF': 0.005,
'MUTTON': 0.007,
'RICE': 0.002,
'WHEAT': 0.008,
'GEL': 0.000}
Создайте переменную 'prob' для хранения данных о проблеме:
prob = LpProblem("The Whiskas Problem", LpMinimize)
Словарь под названием «ингредиент_варс» создается для хранения переменных, на которые имеются ссылки:
ingredient_vars = LpVariable.dicts("Ingr",Ingredients,0)
Добавьте цель:
prob += lpSum([costs[i]*ingredient_vars[i] for i in Ingredients]), "Total Cost of Ingredients per can"
Создайте жесткие ограничения (здесь мой пример начинает отличаться от примера в документации):
c1 = lpSum([ingredient_vars[i] for i in Ingredients]) == 100, "PercentagesSum"
c2 = lpSum([proteinPercent[i] * ingredient_vars[i] for i in Ingredients]) >= 8.0, "ProteinRequirement"
c3 = lpSum([fatPercent[i] * ingredient_vars[i] for i in Ingredients]) >= 6.0, "FatRequirement"
c4 = lpSum([fibrePercent[i] * ingredient_vars[i] for i in Ingredients]) <= 2.0, "FibreRequirement"
c5 = lpSum([saltPercent[i] * ingredient_vars[i] for i in Ingredients]) <= 0.4, "SaltRequirement"
Добавьте жесткие ограничения:
for con in [c1,c2,c3,c4,c5]:
prob += con
Определите левое выражение ограничения, которое нужно эластизировать:
c6_LHS = LpAffineExpression([(ingredient_vars['GEL'],1), (ingredient_vars['BEEF'],1)])
Определите ограничение, которое необходимо эластизировать: общее количество геля и говядины менее 30%:
c6= LpConstraint(e=c6_LHS, sense=-1, name='GelBeefTotal', rhs=30)
Определите эластичное ограничение:
c6_elastic = c6.makeElasticSubProblem(penalty = 100, proportionFreeBoundList = [.02,.02])
И это способ добавить к проблеме эластичное (то есть мягкое) ограничение:
prob.extend(c6_elastic)
Решать проблему:
prob.writeLP("WhiskasModel.lp")
prob.solve()
Выведите оптимальное решение:
for v in prob.variables():
print v.name, "=", v.varValue
Если вы поиграете со штрафом и ограничениями, вы можете убедиться, что он работает так, как рекламируется.
PS, насколько я понимаю, название вопроса может вводить в заблуждение. Добавление эластичной подзадачи равносильно добавлению к цели некоторых стоимостных терминов, соответствующих «мягкому ограничению». Мягкое ограничение - это не ограничение - это сокращение для набора стоимостных терминов в цели.
person
GrayOnGray
schedule
17.02.2017