如何在未建模为变量的时间范围内添加PuLP约束

问题描述

我目前正在处理一个复杂的调度问题,其中涉及大量参数和决策变量。简而言之,我正在尝试根据容量,复杂性,可用时间和潜在的完成时间来安排任务的资源。

我有一个矩阵Av,j,t,它确定在时间t向项目v上的作业j分配了多少资源,以及变量Sv,j和Ev,j,它们确定每个项目的开始和结束时间按项目工作。从数学上讲,约束都是有道理的,但是我在建模时遇到了很多麻烦。

为了确保仅在工作的开始和结束时间之间分配工作,我强制执行了约束:

pulp.lpSum([A[t][v][j] for t in [t0 for t0 in T if t0 >= S[v][j]]]) == P[v][j]
pulp.lpSum([A[t][v][j] for t in [t0 for t0 in T if t0 <= S[v][j] - 1]]) == 0
pulp.lpSum([A[t][v][j] for t in [t0 for t0 in T if t0 >= E[v][j] + 1]]) == 0

其中Pv,j是任务使用单个资源花费的总时间。我遇到的这类约束的主要问题是开始时间和结束时间是模型变量,而T(时间集)不是。试图在模型中强制执行此约束被证明是有问题的,因为在设置约束时Sv,j并未真正“初始化”,因此该约束实际上没有像集合那样做任何事情

[t0 for t0 in T if t0 >= S[v][j]]

不随模型改变。我还设置了一个指标来跟踪作业完成情况Xv,j,t,对于t> Ev,j,它为1,否则为0。我已经尝试了多种方法来强制执行此操作,但是所有方法都依赖于T中t的集合的总和,而模型调整时并不会调整。

有人对我如何强制这些集合随模型本身进行调整有任何想法吗?

解决方法

所有约束都必须是线性的。您尝试指定的是非线性的,因此是不允许的。

相反,您需要建模:

                       t   1 2 3 4 5 6 7 8 9 10 11
   job is executing  x(t)  0 0 0 0 1 1 1 1 0 0 0 
   job is starting   s(t)  0 0 0 0 1 0 0 0 0 0 0 
    

这可以建模为:

   s(t) >= x(t)-x(t-1)
   sum(t,s(t)) <= 1      (one start allowed)
   sum(t,x(t)) = joblen

要获取开始时间和结束时间:

   S = sum(t,t*s(t));
   E = S + joblen - 1

这是一个相当标准的方法。您的教科书中可能会提到它。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...