Reputation: 543
I am trying to solve MILP in puLP (Python), and I keep getting the following error:
Traceback (most recent call last):
File "main_lp.py", line 63, in <module>
ans = solve_lp(C)
File "/home/ashwin/Documents/Williams/f2014/math317_or/project/solve_lp.py", line 36, in solve_lp
prob.solve()
File "/usr/local/lib/python2.7/dist-packages/PuLP-1.5.6-py2.7.egg/pulp/pulp.py", line 1619, in solve
status = solver.actualSolve(self, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/PuLP-1.5.6-py2.7.egg/pulp/solvers.py", line 1283, in actualSolve
return self.solve_CBC(lp, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/PuLP-1.5.6-py2.7.egg/pulp/solvers.py", line 1346, in solve_CBC
raise PulpSolverError("Pulp: Error while executing "+self.path)
pulp.solvers.PulpSolverError: Pulp: Error while executing /usr/local/lib/python2.7/dist-packages/PuLP-1.5.6-py2.7.egg/pulp/solverdir/cbc-32
For my linear programming problem, I am attempting to take sums of different vectors as the constraint, and I think I must have done that wrong somehow, because a much simpler problem works with no hitches. I have attached the code (C
is an N by N numpy
array).
def solve_lp(C):
N = len(C)
prob=LpProblem('Scheduling',LpMinimize)
X = [[LpVariable('X' + str(i+1) + str(j+1), 0, C[i,j],LpBinary)
for j in range(N)] for i in range(N)]
X = np.array(X)
X_o = [LpVariable('X0' + str(i), 0, None, LpBinary) for i in range(N)]
X_t = [LpVariable('X' + str(i) + 't', 0, None, LpBinary) for i in range(N)]
# Objective Function
ones_vec = list(np.ones(len(X_o)))
prob += lpDot(ones_vec,X_o), 'Minimize Buses'
# Constraints
for i in range(N):
row = list(X[i,:]) + [X_t[i]]
ones_vec = list(np.ones(len(row)))
prob += lpDot(ones_vec, row) == 1, 'Only one destination for ' + str(i)
for j in range(N):
col = list(X[:,j]) + [X_o[j]]
ones_vec = list(np.ones(len(col)))
prob += lpDot(ones_vec,col) == 1, 'Only one source for ' + str(j)
prob.solve()
return X, value(prob.objective)
Upvotes: 8
Views: 29184
Reputation: 1
I had a similar problem, and after spending hours (running in both google colab and locally on jupyter notebook) and printing the variables I realized that duplicate LpVariables in my problem cause the error after changing the names, it worked without any error.
Upvotes: 0
Reputation: 1
On your LP problem remove NAN or nan from your equation that you want to solve
Upvotes: 0
Reputation: 116
I recently had the same error raised aswell. The reason this error code was raised in my case was that my data frame was not correctly populated. i incorrectly had NaN
on the RHS on some of my constraints
What is had was something like:
Matrix = df.pivot(1st_dimension, 2nd_dimension, value)
This operation automatically puts NaN
for the instances that are not in the original dataframe.
in my case the NaN's
are replaced with 0
which is what i was expecting it to be:
Matrix = Matrix.fillna(0)
Upvotes: 2
Reputation: 21
I had a similar problem, and indeed with duplicate LpVariable names just like levis501's answer and aleon answered.
my code was:
var = [[pulp.LpVariable(f'x{i}{j}', lowBound=0, cat=pulp.LpInteger) for j in range(col)] for i in range(row)]
when i=1 j=11, x would be x111, and when i=11 j=1, x also would be x111
I changed to:
var = [[pulp.LpVariable(f'x{i}_{j}', lowBound=0, cat=pulp.LpInteger) for j in range(col)] for i in range(row)]
After changing, it runs successfully.
Upvotes: 2
Reputation: 61
I think that you have duplicate LpVariable names. I just had the same problem and saw it thanks to levis501's answer. Here:
X = [[LpVariable('X' + str(i+1) + str(j+1), 0, C[i,j],LpBinary)
for j in range(N)] for i in range(N)]
X contains some variables with the same name. For example for i = 0 and j = 10 you get 'X111', and for i = 10 and j = 0 you also get 'X111'.
Upvotes: 5
Reputation: 335
I had this problem today, and it was because the temporary files for CBC were trying to be written in a location whose path had spaces in it, and the command that pulp passes to subprocess.Popen() to run CBC does not use quotes, and thus the command was misinterpreted and CBC couldn't find the location to create temp files.
For this I found two solutions:
(1) Explicitly set a temporary file directory that doesn't have spaces in it,
pulp.LpSolverDefault.tmpDir = self.tmp_file_dir # tmp_file_dir can't have spaces!
prob.solve()
or (2) don't use CBC (my problem is small)
prob.solve(pulp.GLPK_CMD())
I have a work-related constraint that a lot of my work is stuck in directories that have spaces.
Upvotes: 0
Reputation: 61
I recently had a similar problem due to Nan inputs in the model. I had the data in a DataFrame where some the cells should not bee converted to variables to improve performance. However, upon creating the objective function and the constraints, I noticed the presence of Nan and when I changed them it worked perfectly.
Upvotes: 6
Reputation: 11
I experienced the same issue when launching multiple instances of the LPSolver class. As fmars stated, the problem is that the path 'tmpSol' does not exist, which is defined in the following lines of code within the solvers.py file of pulp:
pid = os.getpid()
tmpLp = os.path.join(self.tmpDir, "%d-pulp.lp" % pid)
tmpMps = os.path.join(self.tmpDir, "%d-pulp.mps" % pid)
tmpSol = os.path.join(self.tmpDir, "%d-pulp.sol" % pid)
This bit of code appears in every solver. The problem is that these paths are deleted later on, but may coincide for different instances of the LPSolver class (as the variable pid is not unique).
The solution is to get a unique path for each instance of LPSolver, using, for example, the current time. Replacing the above lines by the following four will do the trick.
currentTime = time()
tmpLp = os.path.join(self.tmpDir, "%f3-pulp.lp" % currentTime)
tmpMps = os.path.join(self.tmpDir, "%f3-pulp.mps" % currentTime)
tmpSol = os.path.join(self.tmpDir, "%f3-pulp.sol" % currentTime)
Don't forget to
from time import time
Cheers, Tim
Upvotes: 1
Reputation: 147
I have met some similar problem which because of some PuLP's bug. When some problem is infeasible and the solver failed to solve the problem, PuLP raise an exception rather than return status equals to infeasible. Below is the reason.
(You may first want to check out latest codebase of PuLP because the line number you paste doesn't match the latest one. I'll explain based on latest one but you can look at yours very simply.)
https://github.com/coin-or/pulp/blob/master/src/pulp/solvers.py#L1405-L1406 This is where exception prompt.
if not os.path.exists(tmpSol):
raise PulpSolverError("Pulp: Error while executing "+self.path)
tmpSol is the temporary file where stores the solution. If PuLP cannot find such solution file, it will throw the exception you saw. And the bug I mentioned above is, if the problem itself is infeasible, then PuLP won't be able to generate such temporary file. So it will always throw such exception.
One thing you can do is, send a pull request to PuLP repo and fix it. And a simple workaround is, rather than directly invoke
prob.solve()
in your code, you should always do
try:
prob.solve()
except Exception:
logger.debug('Problem infeasible')
Upvotes: 0
Reputation: 4207
Make sure you don't have duplicate LpVariable names, and watch out for LpVariable names with the unsupported characters -+[] ->/
since all of those characters are silently converted to underscores _
Setting LpSolverDefault.msg = 1
before calling prob.solve()
may help by printing the solvers output to the console.
Upvotes: 11