PuLP - COIN-CBC错误:如何添加具有双重不等式和松弛的约束?

时间:2016-07-07 23:08:09

标签: optimization mathematical-optimization pulp coin-or-cbc

我想添加这组约束:

-M(1-X_(i,j,k,n) )≤S_(i,j,k,n)-ToD_(i,j,k,n)≤M(1-X_(i,j,k,n) ) ∀i,j,k,n

其中M是一个大数,S是一个整数变量,取值介于0和1440之间.ToD是一个4维矩阵,它从Excel表中获取值。 X i是双变量,取值为0-1。

我尝试在代码中实现如下:

for n in range(L):
    for k in range(M):
        for i in range(N):
            for j in range(N):
                if (i != START_POINT_S & i != END_POINT_T & j != START_POINT_S & j != END_POINT_T):
                    prob += (-BIG_NUMBER*(1-X[i][j][k][n])) <= (S[i][j][k][n] - ToD[i][j][k][n]), ""

和另一个约束如下:

for i in range(N):
    for j in range(N):
        for k in range(M):
            for n in range(L):
                if (i != START_POINT_S & i != END_POINT_T & j != START_POINT_S & j != END_POINT_T):
                    prob += S[i][j][k][n] - ToD[i][j][k][n] <= BIG_NUMBER*(1-X[i][j][k][n]), ""

根据我的经验,在代码中,这两个约束完全等同于我们想要的。问题是PuLP和CBC不会接受它们。产生以下错误:

浆:

Traceback (most recent call last):
  File "basic_JP.py", line 163, in <module>
    prob.solve()
  File "C:\Users\dimri\Desktop\Filesystem\Projects\deliverable_B4\lib\site-packa
ges\pulp\pulp.py", line 1643, in solve
    status = solver.actualSolve(self, **kwargs)
  File "C:\Users\dimri\Desktop\Filesystem\Projects\deliverable_B4\lib\site-packa
ges\pulp\solvers.py", line 1303, in actualSolve
    return self.solve_CBC(lp, **kwargs)
  File "C:\Users\dimri\Desktop\Filesystem\Projects\deliverable_B4\lib\site-packa
ges\pulp\solvers.py", line 1366, in solve_CBC
    raise PulpSolverError("Pulp: Error while executing "+self.path)
pulp.solvers.PulpSolverError: Pulp: Error while executing C:\Users\dimri\Desktop
\Filesystem\Projects\deliverable_B4\lib\site-packages\pulp\solverdir\cbc\win\64\
cbc.exe

和CBC:

Welcome to the CBC MILP Solver
Version: 2.9.0
Build Date: Feb 12 2015

command line - C:\Users\dimri\Desktop\Filesystem\Projects\deliverable_B4\lib\sit
e-packages\pulp\solverdir\cbc\win\64\cbc.exe 5284-pulp.mps branch printingOption
s all solution 5284-pulp.sol (default strategy 1)
At line 2 NAME          MODEL
At line 3 ROWS
At line 2055 COLUMNS
Duplicate row C0000019 at line 10707 <     X0001454  C0000019  -1.000000000000e+
00 >
Duplicate row C0002049 at line 10708 <     X0001454  C0002049  -1.000000000000e+
00 >
Duplicate row C0000009 at line 10709 <     X0001454  C0000009   1.000000000000e+
00 >
Duplicate row C0001005 at line 10710 <     X0001454  C0001005   1.000000000000e+
00 >
At line 14153 RHS
At line 16204 BOUNDS
Bad image at line 17659 <  UP BND       X0001454   1.440000000000e+03 >
At line 18231 ENDATA
Problem MODEL has 2050 rows, 2025 columns and 5968 elements
Coin0008I MODEL read with 5 errors
There were 5 errors on input
** Current model not valid
Option for printingOptions changed from normal to all
** Current model not valid
No match for 5284-pulp.sol - ? for list of commands
Total time (CPU seconds):       0.02   (Wallclock seconds):       0.02

我不知道有什么问题,有什么帮助吗?我是新手,如果信息不够,请告诉我应该添加的内容。

1 个答案:

答案 0 :(得分:1)

好吧,我已经搜索了几个小时,但在我发布这个问题后,我找到了答案。这些问题主要是因为变量的名称或约束。这就是导致重复的原因。我真的不习惯那种软件,这就是我花了这么长时间才找到并回答的原因。无论如何,对我来说问题是我在定义变量时:

# define X[i,j,k,n]
lower_bound_X = 0 # lower bound for variable X
upper_bound_X = 1 # upper bound for variable X
X = LpVariable.dicts(name="X",
                     indexs=(range(N), range(N), range(M), range(L)),     
                     lowBound=lower_bound_X,
                     upBound=upper_bound_X,
                     cat=LpInteger)

# define S[i,j,k,n]
lower_bound_S = 0       # lower bound for variable S
upper_bound_S = 1440    # upper bound for variable S
S = LpVariable.dicts(name="X", 
                     indexs=(range(N), 
                     range(N), range(M), range(L)), 
                     lowBound=lower_bound_S, 
                     upBound=upper_bound_S, 
                     cat=LpInteger)

正如您在S的定义中所看到的,我显然忘记将变量的名称更改为S,因为我将其复制粘贴。无论如何,定义S的正确方法是这样的:

# define S[i,j,k,n]
lower_bound_S = 0       # lower bound for variable S
upper_bound_S = 1440    # upper bound for variable S
S = LpVariable.dicts(name="S", 
                     indexs=(range(N), range(N), range(M), range(L)), 
                     lowBound=lower_bound_S, 
                     upBound=upper_bound_S, 
                     cat=LpInteger)

这就是我运行代码的方式。