将PULP中的约束与目标相关联



我正试图解决MIP问题。我正试图通过最小化完成需求所需的总时间来找出每项技术在一周内某一天要完成的考试数量。

我在单独的数据帧中有需求、每个技术所花费的时间、技术列表等。

我能够找到考试的数量来最大限度地减少目标,但我希望添加一个限制,即使用的最大技术数量为8。

我添加了一些二进制变量来添加条件,但我无法将其与目标函数联系起来。

以下是我到目前为止的代码:

model = pulp.LpProblem("Time minimizing problem", pulp.LpMinimize)
capacity = pulp.LpVariable.dicts("capacity",
((examdate , techname, region) for examdate, techname, region in tech_data_new.index),
lowBound=0,
cat='Integer')
for examdate, techname,region in tech_data_new.index:
var = capacity[(examdate,techname,region)]
var.upBound = tech_data_new.loc[(examdate,techname,region), 'Max Capacity']

model += pulp.lpSum(capacity[examdate,techname, region] * tech_data_new.loc[(examdate,techname, region), 'Time taken'] for examdate,techname, region in tech_data_new.index)
for date in demand_data.index.get_level_values('Exam Date').unique():
for i in demand_data.loc[date].index.tolist():
model += pulp.lpSum([capacity[examdate,techname,region] for examdate, techname, region in tech_data_new.index 
if (date == examdate and i == region)]) == demand_data.loc[(demand_data.index.get_level_values('Exam Date') == date) & (demand_data.index.get_level_values('Body Region') == i), shiftname].item()

这些是二进制变量,我试着加,但不能和目标联系起来,因为乘法会使它非线性。

techs = pulp.LpVariable.dicts("techs",
(techname for techname in tech_data_new.index.get_level_values('Technologist Name').unique()),
cat='Binary')
days = pulp.LpVariable.dicts("day",
(examdate for examdate in tech_data_new.index.get_level_values('Exam Date').unique()),
cat='Binary')

任何线索都将不胜感激。提前谢谢。如果需要任何其他支持,请告诉我。

如果你想为每个examdate设置一个约束,并且具有索引(examdate, techname, region)的整数变量capacity表示每个技术在每个地区的每个日期进行的检查次数,那么我会创建一组二进制变量tech_used,其索引(examdate, techname)表示每天是否使用reach技术。

在定义这些变量之后,您需要设置约束,以便它们按要求运行。。。假设列表examdates, technames, regions已经被适当地声明:

for examdate in examdates:
for techname in technames:
model += Lp.sum([capacity[examdate, techname, region] for region in regions]) < max_capacity*tech_used(examdate, techname)

请注意,在上面的max_capacity应该是每个技术的容量,这些限制可以取代您在其他地方设置的最大容量限制。

然后你只需要将你的技术数量限制为最多8:

for examdate in examdates:
model += Lp.sum([tech_used[examdate, techname] for techname in technames])  <= 8

最新更新