简体   繁体   English

使用 Python (Pulp) 进行线性规划 - 调度

[英]Linear Programming with Python (Pulp) - Scheduling

I'm trying to optimize a schedule by formulating it as an (integer) linear problem.我试图通过将其制定为(整数)线性问题来优化计划。 I've run into some problems with the coding part (mostly due to Pulp), which is fairly separate from the formulation.我在编码部分遇到了一些问题(主要是由于 Pulp),它与公式完全分开。

The Problem:问题:

Schedule n ships over a period of 5 years (timesteps in months), subject to the following constraints:在 5 年内(以月为单位的时间步长)的附表 n 船舶,受以下限制:

  • one and only one ship must be on "Local Patrol" (state = 'C') each month一艘且只有一艘船必须每月进行“本地巡逻”(状态 = 'C')
  • one and only one ship must go on "Extended Patrol" (state = 'A') each year, which is a four month block from July to October inclusive每年只有一艘船必须进行“扩展巡逻”(状态 = 'A'),从 7 月到 10 月有四个月的时间段
  • each ship must have a 4 month long inspection once during the 5 year period (state = '4')每艘船必须在 5 年内进行一次为期 4 个月的检查(state = '4')
  • each ship must have an 8 month long break once during the 5 year period (state = '8')每艘船在 5 年期间必须有一次 8 个月的长时间休息(状态 = '8')
  • each ship must have regular maintenance approx every 5 months (state = 'M')每艘船必须大约每 5 个月进行一次定期维护(状态 = 'M')
  • a ship can be in only one state during a given month, but it can also have no state (open/vacant, '_')一艘船在给定的月份只能处于一种状态,但也可以没有状态(开放/空置,“_”)

Objective Function formulation:目标函数公式:

Define slack variables that count the number of times (and the amount) the schedule deviates from the 5 month ('M') maintenance plan.定义计算计划偏离 5 个月 ('M') 维护计划的次数(和数量)的松弛变量。

I can explain the setup more if needed, but for now I have some basic questions that might be the source of my problems.如果需要,我可以更多地解释设置,但现在我有一些基本问题,可能是我的问题的根源。

Here is one of my constraints (blockList stores the start of the 4 and 8 month block for each ship):这是我的约束之一(blockList 存储每艘船的 4 个月和 8 个月块的开始):

# Each ship must have one 8block and one m4block in a 5 year schedule, which must be between 2 and 3 years apart
for n in ship_list:
    prob += blockList[n][0] - blockList[n][1] >= 24
    prob += blockList[n][0] - blockList[n][1] <= 36

I want to take the absolute value of the LHS of the above expressions, but I can't because the objects are initialized as pulp.LpVariable.我想取上述表达式的 LHS 的绝对值,但我不能,因为对象被初始化为纸浆.LpVariable。 Any recommendations for a workaround?有关解决方法的任何建议?

Anyways, that may or may not fix my problem.无论如何,这可能会也可能不会解决我的问题。 If it doesn't, my next question is for anyone familiar with pulp.如果没有,我的下一个问题是针对任何熟悉纸浆的人。 How can I know if the solution true, or if there was some sort of elasticity added by the solver in the background?我怎么知道解是否正确,或者求解器是否在后台添加了某种弹性? (Running the code as is with that constraint gives incorrect results, and using a different solver like GLPK gives an error). (使用该约束按原样运行代码会产生不正确的结果,而使用不同的求解器(如 GLPK)会产生错误)。

Here are a few suggestions:以下是一些建议:

  1. Taking Absolute Values取绝对值

    In PuLP, you can do that by relying on the underlying Python commands to do that.在 PuLP 中,您可以通过依赖底层 Python 命令来做到这一点。

    Something along the lines of:类似的东西:

     if blockList[n][0] > blockList[n][1]: prob += blockList[n][0] - blockList[n][1] >= 24 else: prob += blockList[n][1] - blockList[n][0] >= 24
  2. To see if the Solver that to "add elasticity" you'd examine the value of pulp.constants.LpStatusOptimal.要查看求解器是否“增加弹性”,您需要检查pulp.constants.LpStatusOptimal.的值pulp.constants.LpStatusOptimal. If this value is 1, then the problem was solved to optimality.如果此值为 1,则问题已求解为最优。 Note that the typical practice is to add a dummy slack or a surplus variable, give it a small penalty in the objective function.请注意,典型的做法是添加一个虚拟松弛或剩余变量,在目标函数中给它一个小的惩罚。 If in the solution that dummy variable is non-zero, that means that the problem needed the extra 'elasticity.'如果在解决方案中虚拟变量不为零,则意味着该问题需要额外的“弹性”。

  3. Finally, my main suggestion is that you start small, with a minimal example that works in PuLP.最后,我的主要建议是从小处着手,从一个适用于 PuLP 的最小示例开始。 You can even start with one of the case studies here .您甚至可以从此处案例研究之一开始。 At each step, write down your LP to a file and examine it.在每一步,将你的 LP 写到一个文件中并检查它。 This will right away tell you which constraints or variables are off, and you can alter that.这将立即告诉您哪些约束或变量已关闭,您可以更改它。

     class pulp.LpProblem(name='outfile.lp', sense=1)

Hope this gets you moving forward.希望这能让你继续前进。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM