Initial conversion to py 2.6, 2.7, 3.2 version

This commit is contained in:
Stuart Mitchell
2014-01-23 18:05:08 +08:00
parent 0fc78e635d
commit 23f15c644a
37 changed files with 434 additions and 396 deletions

View File

@@ -20,7 +20,11 @@ use the -c option to specify an alternate configuration file.
$Id$ $Id$
""" """
import os, shutil, sys, tempfile, urllib2 import os, shutil, sys, tempfile
try:
from urllib.request import urlopen
except ImportError:
from urllib2 import urlopen
from optparse import OptionParser from optparse import OptionParser
tmpeggs = tempfile.mkdtemp() tmpeggs = tempfile.mkdtemp()
@@ -54,16 +58,23 @@ try:
except ImportError: except ImportError:
ez = {} ez = {}
if USE_DISTRIBUTE: if USE_DISTRIBUTE:
exec urllib2.urlopen('http://python-distribute.org/distribute_setup.py' exec(urlopen('http://python-distribute.org/distribute_setup.py'
).read() in ez ).read(), ez)
ez['use_setuptools'](to_dir=tmpeggs, download_delay=0, no_fake=True) ez['use_setuptools'](to_dir=tmpeggs, download_delay=0, no_fake=True)
else: else:
exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py' try:
).read() in ez exec(urlopen('http://peak.telecommunity.com/dist/ez_setup.py')
.read(), ez)
except SyntaxError:
exec(urlopen('http://python-distribute.org/distribute_setup.py')
.read(), ez)
ez['use_setuptools'](to_dir=tmpeggs, download_delay=0) ez['use_setuptools'](to_dir=tmpeggs, download_delay=0)
if to_reload: if to_reload:
reload(pkg_resources) try:
reload(pkg_resources)
except NameError: # distribute is deprecated by now
pass
else: else:
import pkg_resources import pkg_resources

View File

@@ -42,9 +42,9 @@ for guest in guests:
seating_model.solve() seating_model.solve()
print "The choosen tables are out of a total of %s:"%len(possible_tables) print("The choosen tables are out of a total of %s:"%len(possible_tables))
for table in possible_tables: for table in possible_tables:
if x[table].value() == 1.0: if x[table].value() == 1.0:
print table print(table)

View File

@@ -33,6 +33,6 @@ whiskas_model.solve()
#print the result #print the result
for ingredient in ingredients: for ingredient in ingredients:
print 'The mass of %s is %s grams per can'%(ingredient, print('The mass of %s is %s grams per can'%(ingredient,
x[ingredient].value()) x[ingredient].value()))

View File

@@ -41,8 +41,8 @@ source_suffix = '.rst'
master_doc = 'index' master_doc = 'index'
# General information about the project. # General information about the project.
project = u'PuLP' project = 'PuLP'
copyright = u'2009-, pulp documentation team.' copyright = '2009-, pulp documentation team.'
# The version info for the project you're documenting, acts as replacement for # The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the # |version| and |release|, also used in various other places throughout the
@@ -176,8 +176,8 @@ htmlhelp_basename = 'pulpdoc'
# Grouping the document tree into LaTeX files. List of tuples # Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]). # (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [ latex_documents = [
('index', 'pulp.tex', u'pulp Documentation', ('index', 'pulp.tex', 'pulp Documentation',
u'pulp documentation team', 'manual'), 'pulp documentation team', 'manual'),
] ]
# The name of an image file (relative to this directory) to place at the top of # The name of an image file (relative to this directory) to place at the top of

View File

@@ -90,11 +90,11 @@ prob.writeLP("AmericanSteelProblem.lp")
prob.solve() prob.solve()
# The status of the solution is printed to the screen # The status of the solution is printed to the screen
print "Status:", LpStatus[prob.status] print("Status:", LpStatus[prob.status])
# Each of the variables is printed with it's resolved optimum value # Each of the variables is printed with it's resolved optimum value
for v in prob.variables(): for v in prob.variables():
print v.name, "=", v.varValue print(v.name, "=", v.varValue)
# The optimised objective function value is printed to the screen # The optimised objective function value is printed to the screen
print "Total Cost of Transportation = ", value(prob.objective) print("Total Cost of Transportation = ", value(prob.objective))

View File

@@ -61,11 +61,11 @@ prob.writeLP("BeerDistributionProblem.lp")
prob.solve() prob.solve()
# The status of the solution is printed to the screen # The status of the solution is printed to the screen
print "Status:", LpStatus[prob.status] print("Status:", LpStatus[prob.status])
# Each of the variables is printed with it's resolved optimum value # Each of the variables is printed with it's resolved optimum value
for v in prob.variables(): for v in prob.variables():
print v.name, "=", v.varValue print(v.name, "=", v.varValue)
# The optimised objective function value is printed to the screen # The optimised objective function value is printed to the screen
print "Total Cost of Transportation = ", value(prob.objective) print("Total Cost of Transportation = ", value(prob.objective))

View File

@@ -72,11 +72,11 @@ for demand in range(500, 601, 10):
prob.solve() prob.solve()
# The status of the solution is printed to the screen # The status of the solution is printed to the screen
print "Status:", LpStatus[prob.status] print("Status:", LpStatus[prob.status])
# Each of the variables is printed with it's resolved optimum value # Each of the variables is printed with it's resolved optimum value
for v in prob.variables(): for v in prob.variables():
print v.name, "=", v.varValue print(v.name, "=", v.varValue)
# The optimised objective function value is printed to the screen # The optimised objective function value is printed to the screen
print "Total Cost of Transportation = ", value(prob.objective) print("Total Cost of Transportation = ", value(prob.objective))

View File

@@ -75,7 +75,7 @@ def masterSolve(Patterns, rollData, relax = True):
# The number of rolls of each length in each pattern is printed # The number of rolls of each length in each pattern is printed
for i in Patterns: for i in Patterns:
print i, " = %s"%[i.lengthsdict[j] for j in Pattern.lenOpts] print(i, " = %s"%[i.lengthsdict[j] for j in Pattern.lenOpts])
return value(prob.objective), varsdict return value(prob.objective), varsdict

View File

@@ -81,11 +81,11 @@ prob.writeLP("ComputerPlantProblem.lp")
prob.solve() prob.solve()
# The status of the solution is printed to the screen # The status of the solution is printed to the screen
print "Status:", LpStatus[prob.status] print("Status:", LpStatus[prob.status])
# Each of the variables is printed with it's resolved optimum value # Each of the variables is printed with it's resolved optimum value
for v in prob.variables(): for v in prob.variables():
print v.name, "=", v.varValue print(v.name, "=", v.varValue)
# The optimised objective function value is printed to the screen # The optimised objective function value is printed to the screen
print "Total Costs = ", value(prob.objective) print("Total Costs = ", value(prob.objective))

View File

@@ -51,11 +51,11 @@ prob.writeLP("SpongeRollProblem.lp")
prob.solve() prob.solve()
# The status of the solution is printed to the screen # The status of the solution is printed to the screen
print "Status:", LpStatus[prob.status] print("Status:", LpStatus[prob.status])
# Each of the variables is printed with it's resolved optimum value # Each of the variables is printed with it's resolved optimum value
for v in prob.variables(): for v in prob.variables():
print v.name, "=", v.varValue print(v.name, "=", v.varValue)
# The optimised objective function value is printed to the screen # The optimised objective function value is printed to the screen
print "Production Costs = ", value(prob.objective) print("Production Costs = ", value(prob.objective))

View File

@@ -68,11 +68,11 @@ prob.writeLP("SpongeRollProblem.lp")
prob.solve() prob.solve()
# The status of the solution is printed to the screen # The status of the solution is printed to the screen
print "Status:", LpStatus[prob.status] print("Status:", LpStatus[prob.status])
# Each of the variables is printed with it's resolved optimum value # Each of the variables is printed with it's resolved optimum value
for v in prob.variables(): for v in prob.variables():
print v.name, "=", v.varValue print(v.name, "=", v.varValue)
# The optimised objective function value is printed to the screen # The optimised objective function value is printed to the screen
print "Production Costs = ", value(prob.objective) print("Production Costs = ", value(prob.objective))

View File

@@ -63,9 +63,9 @@ def makePatterns(totalRollLength,lenOpts):
trim[name] = totalRollLength - ssum trim[name] = totalRollLength - ssum
# The different cutting lengths are printed, and the number of each roll of that length in each # The different cutting lengths are printed, and the number of each roll of that length in each
# pattern is printed below. This is so the user can see what each pattern contains. # pattern is printed below. This is so the user can see what each pattern contains.
print "Lens: %s" %lenOpts print("Lens: %s" %lenOpts)
for name,pattern in zip(PatternNames,patterns): for name,pattern in zip(PatternNames,patterns):
print name + " = %s"%pattern print(name + " = %s"%pattern)
return (PatternNames,patterns,trim) return (PatternNames,patterns,trim)
@@ -125,11 +125,11 @@ prob.writeLP("SpongeRollProblem.lp")
prob.solve() prob.solve()
# The status of the solution is printed to the screen # The status of the solution is printed to the screen
print "Status:", LpStatus[prob.status] print("Status:", LpStatus[prob.status])
# Each of the variables is printed with it's resolved optimum value # Each of the variables is printed with it's resolved optimum value
for v in prob.variables(): for v in prob.variables():
print v.name, "=", v.varValue print(v.name, "=", v.varValue)
# The optimised objective function value is printed to the screen # The optimised objective function value is printed to the screen
print "Production Costs = ", value(prob.objective) print("Production Costs = ", value(prob.objective))

View File

@@ -61,9 +61,9 @@ def makePatterns(totalRollLength,lenOpts):
# The different cutting lengths are printed, and the number of each roll of that length in each # The different cutting lengths are printed, and the number of each roll of that length in each
# pattern is printed below. This is so the user can see what each pattern contains. # pattern is printed below. This is so the user can see what each pattern contains.
print "Lens: %s" %lenOpts print("Lens: %s" %lenOpts)
for i in Patterns: for i in Patterns:
print i, " = %s"%[i.lengthsdict[j] for j in lenOpts] print(i, " = %s"%[i.lengthsdict[j] for j in lenOpts])
return Patterns return Patterns
@@ -127,11 +127,11 @@ prob.writeLP("SpongeRollProblem.lp")
prob.solve() prob.solve()
# The status of the solution is printed to the screen # The status of the solution is printed to the screen
print "Status:", LpStatus[prob.status] print("Status:", LpStatus[prob.status])
# Each of the variables is printed with it's resolved optimum value # Each of the variables is printed with it's resolved optimum value
for v in prob.variables(): for v in prob.variables():
print v.name, "=", v.varValue print(v.name, "=", v.varValue)
# The optimised objective function value is printed to the screen # The optimised objective function value is printed to the screen
print "Production Costs = ", value(prob.objective) print("Production Costs = ", value(prob.objective))

View File

@@ -37,7 +37,7 @@ while morePatterns == True:
solution, varsdict = masterSolve(Patterns, rollData, relax = False) solution, varsdict = masterSolve(Patterns, rollData, relax = False)
# Display Solution # Display Solution
for i,j in varsdict.items(): for i,j in list(varsdict.items()):
print i, "=", j print(i, "=", j)
print "objective = ", solution print("objective = ", solution)

View File

@@ -27,7 +27,7 @@ while newPatterns:
solution, varsdict = masterSolve(prob,relax = False) solution, varsdict = masterSolve(prob,relax = False)
# Display Solution # Display Solution
for i,j in varsdict.items(): for i,j in list(varsdict.items()):
print i, "=", j print(i, "=", j)
print "objective = ", solution print("objective = ", solution)

View File

@@ -84,7 +84,7 @@ prob.writeLP("Sudoku.lp")
prob.solve() prob.solve()
# The status of the solution is printed to the screen # The status of the solution is printed to the screen
print "Status:", LpStatus[prob.status] print("Status:", LpStatus[prob.status])
# A file called sudokuout.txt is created/overwritten for writing to # A file called sudokuout.txt is created/overwritten for writing to
sudokuout = open('sudokuout.txt','w') sudokuout = open('sudokuout.txt','w')
@@ -108,4 +108,4 @@ sudokuout.write("+-------+-------+-------+")
sudokuout.close() sudokuout.close()
# The location of the solution is give to the user # The location of the solution is give to the user
print "Solution Written to sudokuout.txt" print("Solution Written to sudokuout.txt")

View File

@@ -85,7 +85,7 @@ sudokuout = open('sudokuout.txt','w')
while True: while True:
prob.solve() prob.solve()
# The status of the solution is printed to the screen # The status of the solution is printed to the screen
print "Status:", LpStatus[prob.status] print("Status:", LpStatus[prob.status])
# The solution is printed if it was deemed "optimal" i.e met the constraints # The solution is printed if it was deemed "optimal" i.e met the constraints
if LpStatus[prob.status] == "Optimal": if LpStatus[prob.status] == "Optimal":
# The solution is written to the sudokuout.txt file # The solution is written to the sudokuout.txt file
@@ -112,4 +112,4 @@ while True:
sudokuout.close() sudokuout.close()
# The location of the solutions is give to the user # The location of the solutions is give to the user
print "Solutions Written to sudokuout.txt" print("Solutions Written to sudokuout.txt")

View File

@@ -31,11 +31,11 @@ prob.writeLP("WhiskasModel.lp")
prob.solve() prob.solve()
# The status of the solution is printed to the screen # The status of the solution is printed to the screen
print "Status:", LpStatus[prob.status] print("Status:", LpStatus[prob.status])
# Each of the variables is printed with it's resolved optimum value # Each of the variables is printed with it's resolved optimum value
for v in prob.variables(): for v in prob.variables():
print v.name, "=", v.varValue print(v.name, "=", v.varValue)
# The optimised objective function value is printed to the screen # The optimised objective function value is printed to the screen
print "Total Cost of Ingredients per can = ", value(prob.objective) print("Total Cost of Ingredients per can = ", value(prob.objective))

View File

@@ -73,11 +73,11 @@ prob.writeLP("WhiskasModel2.lp")
prob.solve() prob.solve()
# The status of the solution is printed to the screen # The status of the solution is printed to the screen
print "Status:", LpStatus[prob.status] print("Status:", LpStatus[prob.status])
# Each of the variables is printed with it's resolved optimum value # Each of the variables is printed with it's resolved optimum value
for v in prob.variables(): for v in prob.variables():
print v.name, "=", v.varValue print(v.name, "=", v.varValue)
# The optimised objective function value is printed to the screen # The optimised objective function value is printed to the screen
print "Total Cost of Ingredients per can = ", value(prob.objective) print("Total Cost of Ingredients per can = ", value(prob.objective))

View File

@@ -26,6 +26,6 @@ prob.writeLP("furniture.lp")
prob.solve() prob.solve()
# Each of the variables is printed with it's value # Each of the variables is printed with it's value
for v in prob.variables(): for v in prob.variables():
print v.name, "=", v.varValue print(v.name, "=", v.varValue)
# The optimised objective function value is printed to the screen # The optimised objective function value is printed to the screen
print "Total Revenue from Production = ", value(prob.objective) print("Total Revenue from Production = ", value(prob.objective))

View File

@@ -42,11 +42,11 @@ prob.solve()
# two paths may be provided (one to clp, one to cbc). # two paths may be provided (one to clp, one to cbc).
# Print the status of the solved LP # Print the status of the solved LP
print "Status:", LpStatus[prob.status] print("Status:", LpStatus[prob.status])
# Print the value of the variables at the optimum # Print the value of the variables at the optimum
for v in prob.variables(): for v in prob.variables():
print v.name, "=", v.varValue print(v.name, "=", v.varValue)
# Print the value of the objective # Print the value of the objective
print "objective=", value(prob.objective) print("objective=", value(prob.objective))

View File

@@ -19,7 +19,7 @@ n = 15
k = floor(log(n)/log(2)); k = floor(log(n)/log(2));
# A vector of n binary variables # A vector of n binary variables
x = LpVariable.matrix("x", range(n), 0, 1, LpInteger) x = LpVariable.matrix("x", list(range(n)), 0, 1, LpInteger)
# A vector of weights # A vector of weights
a = [pow(2,k + n + 1) + pow(2,k + n + 1 - j) + 1 for j in range(1,n+1)] a = [pow(2,k + n + 1) + pow(2,k + n + 1 - j) + 1 for j in range(1,n+1)]
@@ -38,11 +38,11 @@ prob += weight <= b
prob.solve() prob.solve()
# Print the status of the solved LP # Print the status of the solved LP
print "Status:", LpStatus[prob.status] print("Status:", LpStatus[prob.status])
# Print the value of the variables at the optimum # Print the value of the variables at the optimum
for v in prob.variables(): for v in prob.variables():
print v.name, "=", v.varValue print(v.name, "=", v.varValue)
# Print the value of the objective # Print the value of the objective
print "objective=", value(prob.objective) print("objective=", value(prob.objective))

View File

@@ -29,11 +29,11 @@ hpmax = 100.0
sini = 50.0 sini = 50.0
# Time range # Time range
time = range(tmax) time = list(range(tmax))
# Time range (and one more step for the last state of plants) # Time range (and one more step for the last state of plants)
xtime = range(tmax+1) xtime = list(range(tmax+1))
# Units range # Units range
unit = range(units) unit = list(range(units))
# The demand # The demand
demand = [dmin+(dmax-dmin)*0.5 + 0.5*(dmax-dmin)*sin(4*t*2*3.1415/tmax) for t in time] demand = [dmin+(dmax-dmin)*0.5 + 0.5*(dmax-dmin)*sin(4*t*2*3.1415/tmax) for t in time]
# Maximum output for the thermal units # Maximum output for the thermal units
@@ -100,23 +100,23 @@ prob += ctp + cts
# Solve the problem # Solve the problem
prob.solve() prob.solve()
print "Minimum total cost:", prob.objective.value() print("Minimum total cost:", prob.objective.value())
# Print the results # Print the results
print " D S U ", print(" D S U ", end=' ')
for i in unit: print " T%d " %i, for i in unit: print(" T%d " %i, end=' ')
print print()
for t in time: for t in time:
# Demand, hydro storage, hydro production # Demand, hydro storage, hydro production
print "%5.1f" % demand[t], "%5.1f" % value(s[t]), "%5.1f" % value(ph[t]), print("%5.1f" % demand[t], "%5.1f" % value(s[t]), "%5.1f" % value(ph[t]), end=' ')
for i in unit: for i in unit:
# Thermal production # Thermal production
print "%4.1f" % value(p[t][i]), print("%4.1f" % value(p[t][i]), end=' ')
# The state of the unit # The state of the unit
if value(d[t][i]): print "+", if value(d[t][i]): print("+", end=' ')
else: print "-", else: print("-", end=' ')
# Wether the unit will be started # Wether the unit will be started
if value(u[t][i]): print "*", if value(u[t][i]): print("*", end=' ')
else: print " ", else: print(" ", end=' ')
print print()

View File

@@ -16,8 +16,8 @@ B = 500 # Resources available for the two years
s = 20 # Number of scenarios s = 20 # Number of scenarios
n = 10 # Number of projects n = 10 # Number of projects
N = range(n) N = list(range(n))
S = range(s) S = list(range(s))
# First year costs # First year costs
c = [randint(0,C) for i in N] c = [randint(0,C) for i in N]
@@ -56,4 +56,4 @@ lp.solve()
# Solution printing # Solution printing
for i in N: for i in N:
print x[i], "=", x[i].value() print(x[i], "=", x[i].value())

View File

@@ -25,11 +25,11 @@ D = 100
n = 10*(m-1) n = 10*(m-1)
# A vector of n binary variables # A vector of n binary variables
x = LpVariable.matrix("x", range(n), 0, 1, LpInteger) x = LpVariable.matrix("x", list(range(n)), 0, 1, LpInteger)
# Slacks # Slacks
s = LpVariable.matrix("s", range(m), 0) s = LpVariable.matrix("s", list(range(m)), 0)
w = LpVariable.matrix("w", range(m), 0) w = LpVariable.matrix("w", list(range(m)), 0)
# Objective # Objective
prob += lpSum(s) + lpSum(w) prob += lpSum(s) + lpSum(w)
@@ -43,11 +43,11 @@ for j in range(m):
prob.solve() prob.solve()
# Print the status of the solved LP # Print the status of the solved LP
print "Status:", LpStatus[prob.status] print("Status:", LpStatus[prob.status])
# Print the value of the variables at the optimum # Print the value of the variables at the optimum
for v in prob.variables(): for v in prob.variables():
print v.name, "=", v.varValue print(v.name, "=", v.varValue)
# Print the value of the objective # Print the value of the objective
print "objective=", value(prob.objective) print("objective=", value(prob.objective))

View File

@@ -51,11 +51,11 @@ prob.solve()
# two paths may be provided (one to clp, one to cbc). # two paths may be provided (one to clp, one to cbc).
# Print the status of the solved LP # Print the status of the solved LP
print "Status:", LpStatus[prob.status] print("Status:", LpStatus[prob.status])
# Print the value of the variables at the optimum # Print the value of the variables at the optimum
for v in prob.variables(): for v in prob.variables():
print v.name, "=", v.varValue print(v.name, "=", v.varValue)
# Print the value of the objective # Print the value of the objective
print "objective=", value(prob.objective) print("objective=", value(prob.objective))

View File

@@ -23,13 +23,13 @@ prob.writeLP("test7.lp")
prob.solve() prob.solve()
print "Status:", LpStatus[prob.status] print("Status:", LpStatus[prob.status])
for v in prob.variables(): for v in prob.variables():
print v.name, "=", v.varValue, "\tReduced Cost =", v.dj print(v.name, "=", v.varValue, "\tReduced Cost =", v.dj)
print "objective=", value(prob.objective) print("objective=", value(prob.objective))
print "\nSensitivity Analysis\nConstraint\t\tShadow Price\tSlack" print("\nSensitivity Analysis\nConstraint\t\tShadow Price\tSlack")
for name, c in prob.constraints.items(): for name, c in list(prob.constraints.items()):
print name, ":", c, "\t", c.pi, "\t\t", c.slack print(name, ":", c, "\t", c.pi, "\t\t", c.slack)

View File

@@ -42,9 +42,9 @@ for guest in guests:
seating_model.solve() seating_model.solve()
print "The choosen tables are out of a total of %s:"%len(possible_tables) print("The choosen tables are out of a total of %s:"%len(possible_tables))
for table in possible_tables: for table in possible_tables:
if x[table].value() == 1.0: if x[table].value() == 1.0:
print table print(table)

View File

@@ -13,6 +13,7 @@ the appropriate options to ``use_setuptools()``.
This file can also be run as a script to install or upgrade setuptools. This file can also be run as a script to install or upgrade setuptools.
""" """
from os import linesep
import sys import sys
DEFAULT_VERSION = "0.6c11" DEFAULT_VERSION = "0.6c11"
DEFAULT_URL = "http://pypi.python.org/packages/%s/s/setuptools/" % sys.version[:3] DEFAULT_URL = "http://pypi.python.org/packages/%s/s/setuptools/" % sys.version[:3]
@@ -70,10 +71,10 @@ def _validate_md5(egg_name, data):
if egg_name in md5_data: if egg_name in md5_data:
digest = md5(data).hexdigest() digest = md5(data).hexdigest()
if digest != md5_data[egg_name]: if digest != md5_data[egg_name]:
print >>sys.stderr, ( sys.stderr.write(
"md5 validation of %s failed! (Possible download problem?)" "md5 validation of %s failed! (Possible download problem?)"
% egg_name % egg_name + linesep)
) sys.stderr.write()
sys.exit(2) sys.exit(2)
return data return data
@@ -103,14 +104,13 @@ def use_setuptools(
return do_download() return do_download()
try: try:
pkg_resources.require("setuptools>="+version); return pkg_resources.require("setuptools>="+version); return
except pkg_resources.VersionConflict, e: except pkg_resources.VersionConflict as e:
if was_imported: if was_imported:
print >>sys.stderr, ( sys.stderr.write(
"The required version of setuptools (>=%s) is not available, and\n" "The required version of setuptools (>=%s) is not available, and\n"
"can't be installed while this script is running. Please install\n" "can't be installed while this script is running. Please install\n"
" a more recent version first, using 'easy_install -U setuptools'." " a more recent version first, using 'easy_install -U setuptools'."
"\n\n(Currently using %r)" "\n\n(Currently using %r)" % (version, e.args[0]) + linesep)
) % (version, e.args[0])
sys.exit(2) sys.exit(2)
else: else:
del pkg_resources, sys.modules['pkg_resources'] # reload ok del pkg_resources, sys.modules['pkg_resources'] # reload ok
@@ -129,7 +129,7 @@ def download_setuptools(
with a '/'). `to_dir` is the directory where the egg will be downloaded. with a '/'). `to_dir` is the directory where the egg will be downloaded.
`delay` is the number of seconds to pause before an actual download attempt. `delay` is the number of seconds to pause before an actual download attempt.
""" """
import urllib2, shutil import urllib.request, urllib.error, urllib.parse, shutil
egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3]) egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3])
url = download_base + egg_name url = download_base + egg_name
saveto = os.path.join(to_dir, egg_name) saveto = os.path.join(to_dir, egg_name)
@@ -155,7 +155,7 @@ and place it in this directory before rerunning this script.)
version, download_base, delay, url version, download_base, delay, url
); from time import sleep; sleep(delay) ); from time import sleep; sleep(delay)
log.warn("Downloading %s", url) log.warn("Downloading %s", url)
src = urllib2.urlopen(url) src = urllib.request.urlopen(url)
# Read/write all in one block, so we don't create a corrupt file # Read/write all in one block, so we don't create a corrupt file
# if the download is interrupted. # if the download is interrupted.
data = _validate_md5(egg_name, src.read()) data = _validate_md5(egg_name, src.read())
@@ -216,10 +216,10 @@ def main(argv, version=DEFAULT_VERSION):
os.unlink(egg) os.unlink(egg)
else: else:
if setuptools.__version__ == '0.0.1': if setuptools.__version__ == '0.0.1':
print >>sys.stderr, ( sys.stderr.write(
"You have an obsolete version of setuptools installed. Please\n" "You have an obsolete version of setuptools installed. Please\n"
"remove it from your system entirely before rerunning this script." "remove it from your system entirely before rerunning this script."
) + linesep)
sys.exit(2) sys.exit(2)
req = "setuptools>="+version req = "setuptools>="+version
@@ -238,8 +238,8 @@ def main(argv, version=DEFAULT_VERSION):
from setuptools.command.easy_install import main from setuptools.command.easy_install import main
main(argv) main(argv)
else: else:
print "Setuptools version",version,"or greater has been installed." print("Setuptools version",version,"or greater has been installed.")
print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)' print('(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)')
def update_md5(filenames): def update_md5(filenames):
"""Update our built-in md5 registry""" """Update our built-in md5 registry"""
@@ -252,7 +252,7 @@ def update_md5(filenames):
md5_data[base] = md5(f.read()).hexdigest() md5_data[base] = md5(f.read()).hexdigest()
f.close() f.close()
data = [" %r: %r,\n" % it for it in md5_data.items()] data = [" %r: %r,\n" % it for it in list(md5_data.items())]
data.sort() data.sort()
repl = "".join(data) repl = "".join(data)
@@ -262,7 +262,7 @@ def update_md5(filenames):
match = re.search("\nmd5_data = {\n([^}]+)}", src) match = re.search("\nmd5_data = {\n([^}]+)}", src)
if not match: if not match:
print >>sys.stderr, "Internal error!" sys.stderr.write("Internal error!" + linesep)
sys.exit(2) sys.exit(2)
src = src[:match.start(1)] + repl + src[match.end(1):] src = src[:match.start(1)] + repl + src[match.end(1):]

View File

@@ -3,6 +3,7 @@
Setup script for PuLP added by Stuart Mitchell 2007 Setup script for PuLP added by Stuart Mitchell 2007
Copyright 2007 Stuart Mitchell Copyright 2007 Stuart Mitchell
""" """
import sys
from ez_setup import use_setuptools from ez_setup import use_setuptools
use_setuptools() use_setuptools()
from setuptools import setup from setuptools import setup
@@ -13,6 +14,12 @@ License = open('LICENSE').read()
Version = open('VERSION').read().strip() Version = open('VERSION').read().strip()
#hack because pyparsing made version 2 python 3 specific
if sys.version_info[0] <= 2:
pyparsing_ver = 'pyparsing<=1.9.9'
else:
pyparsing_ver = 'pyparsing>=2.0.0'
setup(name="PuLP", setup(name="PuLP",
version=Version, version=Version,
description=""" description="""
@@ -46,7 +53,7 @@ problems.
"README.CoinMP.txt", "README.CoinMP.txt",
], ],
'pulp.solverdir' : ['*','*.*']}, 'pulp.solverdir' : ['*','*.*']},
install_requires = ['pyparsing<=1.9.9'], install_requires = [pyparsing_ver],
entry_points = (""" entry_points = ("""
[console_scripts] [console_scripts]
pulptest = pulp:pulpTestAll pulptest = pulp:pulpTestAll

View File

@@ -30,8 +30,10 @@ Module file that imports all of the pulp functions
Copyright 2007- Stuart Mitchell (s.mitchell@auckland.ac.nz) Copyright 2007- Stuart Mitchell (s.mitchell@auckland.ac.nz)
""" """
from pulp import * VERSION = '1.5.5'
from amply import *
from .pulp import *
from .amply import *
__doc__ = pulp.__doc__ __doc__ = pulp.__doc__
import tests from . import tests

View File

@@ -38,10 +38,10 @@ Usage:
Symbols that are defined can be accessed as attributes or items. Symbols that are defined can be accessed as attributes or items.
>>> print a.T >>> print(a.T)
3 3.0
>>> print a['T'] >>> print(a['T'])
3 3.0
The load_string and load_file methods can be used to parse additional data The load_string and load_file methods can be used to parse additional data
@@ -152,10 +152,10 @@ else:
Transpose a matrix represented as a dict of dicts Transpose a matrix represented as a dict of dicts
""" """
rows = data.keys() rows = list(data.keys())
cols = set() cols = set()
for d in data.values(): for d in list(data.values()):
cols.update(d.keys()) cols.update(list(d.keys()))
d = {} d = {}
@@ -337,7 +337,7 @@ else:
old = self.next old = self.next
try: try:
self.next = self.it.next() self.next = next(self.it)
except StopIteration: except StopIteration:
self.empty = True self.empty = True
return old return old
@@ -445,7 +445,7 @@ else:
elif isinstance(record, TabularRecord): elif isinstance(record, TabularRecord):
record_data = record.data() record_data = record.data()
for row_symbol in record_data: for row_symbol in record_data:
for col_symbol, value in record_data[row_symbol].items(): for col_symbol, value in list(record_data[row_symbol].items()):
self.setValue((row_symbol, col_symbol), _v(value)) self.setValue((row_symbol, col_symbol), _v(value))
def _setSlice(self, slice): def _setSlice(self, slice):

View File

@@ -97,10 +97,15 @@ import types
import string import string
import itertools import itertools
from constants import * from .constants import *
from solvers import * from .solvers import *
from types import GeneratorType from types import GeneratorType
try: # allow Python 2/3 compatibility
maketrans = str.maketrans
except AttributeError:
from string import maketrans
_DICT_TYPE = dict _DICT_TYPE = dict
if sys.platform not in ['cli']: if sys.platform not in ['cli']:
@@ -151,7 +156,7 @@ class LpElement(object):
"""Base class for LpVariable and LpConstraintVar """Base class for LpVariable and LpConstraintVar
""" """
#to remove illegal characters from the names #to remove illegal characters from the names
trans = string.maketrans("-+[] ->/","________") trans = maketrans("-+[] ->/","________")
def setName(self,name): def setName(self,name):
if name: if name:
self.__name = str(name).translate(self.trans) self.__name = str(name).translate(self.trans)
@@ -182,7 +187,7 @@ class LpElement(object):
def __pos__(self): def __pos__(self):
return self return self
def __nonzero__(self): def __bool__(self):
return 1 return 1
def __add__(self, other): def __add__(self, other):
@@ -207,7 +212,7 @@ class LpElement(object):
return LpAffineExpression(self)/other return LpAffineExpression(self)/other
def __rdiv__(self, other): def __rdiv__(self, other):
raise TypeError, "Expressions cannot be divided by a variable" raise TypeError("Expressions cannot be divided by a variable")
def __le__(self, other): def __le__(self, other):
return LpAffineExpression(self) <= other return LpAffineExpression(self) <= other
@@ -421,7 +426,7 @@ class LpVariable(LpElement):
return True return True
def infeasibilityGap(self, mip = 1): def infeasibilityGap(self, mip = 1):
if self.varValue == None: raise ValueError, "variable value is None" if self.varValue == None: raise ValueError("variable value is None")
if self.upBound != None and self.varValue > self.upBound: if self.upBound != None and self.varValue > self.upBound:
return self.varValue - self.upBound return self.varValue - self.upBound
if self.lowBound != None and self.varValue < self.lowBound: if self.lowBound != None and self.varValue < self.lowBound:
@@ -512,7 +517,7 @@ class LpAffineExpression(_DICT_TYPE):
1*x_0 + -3*x_1 + 4*x_2 + 0 1*x_0 + -3*x_1 + 4*x_2 + 0
""" """
#to remove illegal characters from the names #to remove illegal characters from the names
trans = string.maketrans("-+[] ","_____") trans = maketrans("-+[] ","_____")
def setName(self,name): def setName(self,name):
if name: if name:
self.__name = str(name).translate(self.trans) self.__name = str(name).translate(self.trans)
@@ -532,10 +537,10 @@ class LpAffineExpression(_DICT_TYPE):
if isinstance(e, LpAffineExpression): if isinstance(e, LpAffineExpression):
# Will not copy the name # Will not copy the name
self.constant = e.constant self.constant = e.constant
super(LpAffineExpression, self).__init__(e.items()) super(LpAffineExpression, self).__init__(list(e.items()))
elif isinstance(e, dict): elif isinstance(e, dict):
self.constant = constant self.constant = constant
super(LpAffineExpression, self).__init__(e.items()) super(LpAffineExpression, self).__init__(list(e.items()))
elif isinstance(e, list) or isinstance(e, GeneratorType): elif isinstance(e, list) or isinstance(e, GeneratorType):
self.constant = constant self.constant = constant
super(LpAffineExpression, self).__init__(e) super(LpAffineExpression, self).__init__(e)
@@ -549,22 +554,22 @@ class LpAffineExpression(_DICT_TYPE):
# Proxy functions for variables # Proxy functions for variables
def isAtomic(self): def isAtomic(self):
return len(self) == 1 and self.constant == 0 and self.values()[0] == 1 return len(self) == 1 and self.constant == 0 and list(self.values())[0] == 1
def isNumericalConstant(self): def isNumericalConstant(self):
return len(self) == 0 return len(self) == 0
def atom(self): def atom(self):
return self.keys()[0] return list(self.keys())[0]
# Functions on expressions # Functions on expressions
def __nonzero__(self): def __bool__(self):
return float(self.constant) != 0 or len(self) return (float(self.constant) != 0.0) or (len(self) > 0)
def value(self): def value(self):
s = self.constant s = self.constant
for v,x in self.iteritems(): for v,x in self.items():
if v.varValue is None: if v.varValue is None:
return None return None
s += v.varValue * x s += v.varValue * x
@@ -572,7 +577,7 @@ class LpAffineExpression(_DICT_TYPE):
def valueOrDefault(self): def valueOrDefault(self):
s = self.constant s = self.constant
for v,x in self.iteritems(): for v,x in self.items():
s += v.valueOrDefault() * x s += v.valueOrDefault() * x
return s return s
@@ -699,10 +704,10 @@ class LpAffineExpression(_DICT_TYPE):
self.addInPlace(e) self.addInPlace(e)
elif isinstance(other,LpAffineExpression): elif isinstance(other,LpAffineExpression):
self.constant += other.constant self.constant += other.constant
for v,x in other.iteritems(): for v,x in other.items():
self.addterm(v, x) self.addterm(v, x)
elif isinstance(other,dict): elif isinstance(other,dict):
for e in other.itervalues(): for e in other.values():
self.addInPlace(e) self.addInPlace(e)
else: else:
self.constant += other self.constant += other
@@ -719,10 +724,10 @@ class LpAffineExpression(_DICT_TYPE):
self.subInPlace(e) self.subInPlace(e)
elif isinstance(other,LpAffineExpression): elif isinstance(other,LpAffineExpression):
self.constant -= other.constant self.constant -= other.constant
for v,x in other.iteritems(): for v,x in other.items():
self.addterm(v, -x) self.addterm(v, -x)
elif isinstance(other,dict): elif isinstance(other,dict):
for e in other.itervalues(): for e in other.values():
self.subInPlace(e) self.subInPlace(e)
else: else:
self.constant -= other self.constant -= other
@@ -731,7 +736,7 @@ class LpAffineExpression(_DICT_TYPE):
def __neg__(self): def __neg__(self):
e = self.emptyCopy() e = self.emptyCopy()
e.constant = - self.constant e.constant = - self.constant
for v,x in self.iteritems(): for v,x in self.items():
e[v] = - x e[v] = - x
return e return e
@@ -756,23 +761,23 @@ class LpAffineExpression(_DICT_TYPE):
e.constant = self.constant * other.constant e.constant = self.constant * other.constant
if len(other): if len(other):
if len(self): if len(self):
raise TypeError, "Non-constant expressions cannot be multiplied" raise TypeError("Non-constant expressions cannot be multiplied")
else: else:
c = self.constant c = self.constant
if c != 0: if c != 0:
for v,x in other.iteritems(): for v,x in other.items():
e[v] = c * x e[v] = c * x
else: else:
c = other.constant c = other.constant
if c != 0: if c != 0:
for v,x in self.iteritems(): for v,x in self.items():
e[v] = c * x e[v] = c * x
elif isinstance(other,LpVariable): elif isinstance(other,LpVariable):
return self * LpAffineExpression(other) return self * LpAffineExpression(other)
else: else:
if other != 0: if other != 0:
e.constant = self.constant * other e.constant = self.constant * other
for v,x in self.iteritems(): for v,x in self.items():
e[v] = other * x e[v] = other * x
return e return e
@@ -782,22 +787,22 @@ class LpAffineExpression(_DICT_TYPE):
def __div__(self, other): def __div__(self, other):
if isinstance(other,LpAffineExpression) or isinstance(other,LpVariable): if isinstance(other,LpAffineExpression) or isinstance(other,LpVariable):
if len(other): if len(other):
raise TypeError, "Expressions cannot be divided by a non-constant expression" raise TypeError("Expressions cannot be divided by a non-constant expression")
other = other.constant other = other.constant
e = self.emptyCopy() e = self.emptyCopy()
e.constant = self.constant / other e.constant = self.constant / other
for v,x in self.iteritems(): for v,x in self.items():
e[v] = x / other e[v] = x / other
return e return e
def __rdiv__(self, other): def __rdiv__(self, other):
e = self.emptyCopy() e = self.emptyCopy()
if len(self): if len(self):
raise TypeError, "Expressions cannot be divided by a non-constant expression" raise TypeError("Expressions cannot be divided by a non-constant expression")
c = self.constant c = self.constant
if isinstance(other,LpAffineExpression): if isinstance(other,LpAffineExpression):
e.constant = other.constant / c e.constant = other.constant / c
for v,x in other.iteritems(): for v,x in other.items():
e[v] = x / c e[v] = x / c
else: else:
e.constant = other / c e.constant = other / c
@@ -855,7 +860,7 @@ class LpConstraint(LpAffineExpression):
Returns a constraint as a string Returns a constraint as a string
""" """
result, line = self.asCplexVariablesOnly(name) result, line = self.asCplexVariablesOnly(name)
if not self.keys(): if not list(self.keys()):
line += ["0"] line += ["0"]
c = -self.constant c = -self.constant
if c == 0: if c == 0:
@@ -1109,7 +1114,7 @@ class LpProblem(object):
if self.constraints: if self.constraints:
string += "SUBJECT TO\n" string += "SUBJECT TO\n"
for n, c in self.constraints.iteritems(): for n, c in self.constraints.items():
string += c.asCplexLpConstraint(n) +"\n" string += c.asCplexLpConstraint(n) +"\n"
string += "VARIABLES\n" string += "VARIABLES\n"
for v in self.variables(): for v in self.variables():
@@ -1131,7 +1136,7 @@ class LpProblem(object):
if lpcopy.objective is not None: if lpcopy.objective is not None:
lpcopy.objective = self.objective.copy() lpcopy.objective = self.objective.copy()
lpcopy.constraints = {} lpcopy.constraints = {}
for k,v in self.constraints.iteritems(): for k,v in self.constraints.items():
lpcopy.constraints[k] = v.copy() lpcopy.constraints[k] = v.copy()
lpcopy.sos1 = self.sos1.copy() lpcopy.sos1 = self.sos1.copy()
lpcopy.sos2 = self.sos2.copy() lpcopy.sos2 = self.sos2.copy()
@@ -1179,7 +1184,7 @@ class LpProblem(object):
def valid(self, eps = 0): def valid(self, eps = 0):
for v in self.variables(): for v in self.variables():
if not v.valid(eps): return False if not v.valid(eps): return False
for c in self.constraints.itervalues(): for c in self.constraints.values():
if not c.valid(eps): return False if not c.valid(eps): return False
else: else:
return True return True
@@ -1188,7 +1193,7 @@ class LpProblem(object):
gap = 0 gap = 0
for v in self.variables(): for v in self.variables():
gap = max(abs(v.infeasibilityGap(mip)), gap) gap = max(abs(v.infeasibilityGap(mip)), gap)
for c in self.constraints.itervalues(): for c in self.constraints.values():
if not c.valid(0): if not c.valid(0):
gap = max(abs(c.value()), gap) gap = max(abs(c.value()), gap)
return gap return gap
@@ -1223,9 +1228,9 @@ class LpProblem(object):
- A list of the problem variables - A list of the problem variables
""" """
if self.objective: if self.objective:
self.addVariables(self.objective.keys()) self.addVariables(list(self.objective.keys()))
for c in self.constraints.itervalues(): for c in self.constraints.values():
self.addVariables(c.keys()) self.addVariables(list(c.keys()))
variables = self._variables variables = self._variables
#sort the varibles DSU #sort the varibles DSU
variables = [[v.name, v] for v in variables] variables = [[v.name, v] for v in variables]
@@ -1238,7 +1243,7 @@ class LpProblem(object):
if self.objective: if self.objective:
for v in self.objective: for v in self.objective:
variables[v.name] = v variables[v.name] = v
for c in self.constraints.values(): for c in list(self.constraints.values()):
for v in c: for v in c:
variables[v.name] = v variables[v.name] = v
return variables return variables
@@ -1248,7 +1253,7 @@ class LpProblem(object):
def addConstraint(self, constraint, name = None): def addConstraint(self, constraint, name = None):
if not isinstance(constraint, LpConstraint): if not isinstance(constraint, LpConstraint):
raise TypeError, "Can only add LpConstraint objects" raise TypeError("Can only add LpConstraint objects")
if name: if name:
constraint.name = name constraint.name = name
try: try:
@@ -1257,19 +1262,19 @@ class LpProblem(object):
else: else:
name = self.unusedConstraintName() name = self.unusedConstraintName()
except AttributeError: except AttributeError:
raise TypeError, "Can only add LpConstraint objects" raise TypeError("Can only add LpConstraint objects")
#removed as this test fails for empty constraints #removed as this test fails for empty constraints
# if len(constraint) == 0: # if len(constraint) == 0:
# if not constraint.valid(): # if not constraint.valid():
# raise ValueError, "Cannot add false constraints" # raise ValueError, "Cannot add false constraints"
if name in self.constraints: if name in self.constraints:
if self.noOverlap: if self.noOverlap:
raise PulpError, "overlapping constraint names: " + name raise PulpError("overlapping constraint names: " + name)
else: else:
print "Warning: overlapping constraint names:", name print("Warning: overlapping constraint names:", name)
self.constraints[name] = constraint self.constraints[name] = constraint
self.modifiedConstraints.append(constraint) self.modifiedConstraints.append(constraint)
self.addVariables(constraint.keys()) self.addVariables(list(constraint.keys()))
def setObjective(self,obj): def setObjective(self,obj):
""" """
@@ -1310,7 +1315,7 @@ class LpProblem(object):
self.objective = LpAffineExpression(other) self.objective = LpAffineExpression(other)
self.objective.name = name self.objective.name = name
else: else:
raise TypeError, "Can only add LpConstraintVar, LpConstraint, LpAffineExpression or True objects" raise TypeError("Can only add LpConstraintVar, LpConstraint, LpAffineExpression or True objects")
return self return self
def extend(self, other, use_objective = True): def extend(self, other, use_objective = True):
@@ -1332,7 +1337,7 @@ class LpProblem(object):
elif isinstance(other, LpProblem): elif isinstance(other, LpProblem):
for v in set(other.variables()).difference(self.variables()): for v in set(other.variables()).difference(self.variables()):
v.name = other.name + v.name v.name = other.name + v.name
for name,c in other.constraints.iteritems(): for name,c in other.constraints.items():
c.name = other.name + name c.name = other.name + name
self.addConstraint(c) self.addConstraint(c)
if use_objective: if use_objective:
@@ -1363,7 +1368,7 @@ class LpProblem(object):
def writeMPS(self, filename, mpsSense = 0, rename = 0, mip = 1): def writeMPS(self, filename, mpsSense = 0, rename = 0, mip = 1):
wasNone, dummyVar = self.fixObjective() wasNone, dummyVar = self.fixObjective()
f = file(filename, "w") f = open(filename, "w")
if mpsSense == 0: mpsSense = self.sense if mpsSense == 0: mpsSense = self.sense
cobj = self.objective cobj = self.objective
if mpsSense != self.sense: if mpsSense != self.sense:
@@ -1383,7 +1388,7 @@ class LpProblem(object):
if not objName: objName = "OBJ" if not objName: objName = "OBJ"
f.write(" N %s\n" % objName) f.write(" N %s\n" % objName)
mpsConstraintType = {LpConstraintLE:"L", LpConstraintEQ:"E", LpConstraintGE:"G"} mpsConstraintType = {LpConstraintLE:"L", LpConstraintEQ:"E", LpConstraintGE:"G"}
for k,c in self.constraints.iteritems(): for k,c in self.constraints.items():
if rename: k = constraintsNames[k] if rename: k = constraintsNames[k]
f.write(" "+mpsConstraintType[c.sense]+" "+k+"\n") f.write(" "+mpsConstraintType[c.sense]+" "+k+"\n")
# matrix # matrix
@@ -1391,7 +1396,7 @@ class LpProblem(object):
# Creation of a dict of dict: # Creation of a dict of dict:
# coefs[nomVariable][nomContrainte] = coefficient # coefs[nomVariable][nomContrainte] = coefficient
coefs = {} coefs = {}
for k,c in self.constraints.iteritems(): for k,c in self.constraints.items():
if rename: k = constraintsNames[k] if rename: k = constraintsNames[k]
for v in c: for v in c:
n = v.name n = v.name
@@ -1417,7 +1422,7 @@ class LpProblem(object):
f.write(" MARK 'MARKER' 'INTEND'\n") f.write(" MARK 'MARKER' 'INTEND'\n")
# right hand side # right hand side
f.write("RHS\n") f.write("RHS\n")
for k,c in self.constraints.iteritems(): for k,c in self.constraints.items():
c = -c.constant c = -c.constant
if rename: k = constraintsNames[k] if rename: k = constraintsNames[k]
if c == 0: c = 0 if c == 0: c = 0
@@ -1466,7 +1471,7 @@ class LpProblem(object):
Side Effects: Side Effects:
- The file is created. - The file is created.
""" """
f = file(filename, "w") f = open(filename, "w")
f.write("\\* "+self.name+" *\\\n") f.write("\\* "+self.name+" *\\\n")
if self.sense == 1: if self.sense == 1:
f.write("Minimize\n") f.write("Minimize\n")
@@ -1477,11 +1482,11 @@ class LpProblem(object):
if not objName: objName = "OBJ" if not objName: objName = "OBJ"
f.write(self.objective.asCplexLpAffineExpression(objName, constant = 0)) f.write(self.objective.asCplexLpAffineExpression(objName, constant = 0))
f.write("Subject To\n") f.write("Subject To\n")
ks = self.constraints.keys() ks = list(self.constraints.keys())
ks.sort() ks.sort()
for k in ks: for k in ks:
constraint = self.constraints[k] constraint = self.constraints[k]
if not constraint.keys(): if not list(constraint.keys()):
#empty constraint add the dummyVar #empty constraint add the dummyVar
constraint += self.get_dummyVar() constraint += self.get_dummyVar()
f.write(constraint.asCplexLpConstraint(k)) f.write(constraint.asCplexLpConstraint(k))
@@ -1495,7 +1500,7 @@ class LpProblem(object):
repeated_names = {} repeated_names = {}
for v in vs: for v in vs:
repeated_names[v.name] = repeated_names.get(v.name, 0) + 1 repeated_names[v.name] = repeated_names.get(v.name, 0) + 1
repeated_names = [(key, value) for key, value in repeated_names.items() repeated_names = [(key, value) for key, value in list(repeated_names.items())
if value >= 2] if value >= 2]
if repeated_names: if repeated_names:
raise PulpError('Repeated variable names in Lp format\n' raise PulpError('Repeated variable names in Lp format\n'
@@ -1527,14 +1532,14 @@ class LpProblem(object):
if writeSOS and (self.sos1 or self.sos2): if writeSOS and (self.sos1 or self.sos2):
f.write("SOS\n") f.write("SOS\n")
if self.sos1: if self.sos1:
for sos in self.sos1.itervalues(): for sos in self.sos1.values():
f.write("S1:: \n") f.write("S1:: \n")
for v,val in sos.iteritems(): for v,val in sos.items():
f.write(" %s: %.12g\n" % (v.name, val)) f.write(" %s: %.12g\n" % (v.name, val))
if self.sos2: if self.sos2:
for sos in self.sos2.itervalues(): for sos in self.sos2.values():
f.write("S2:: \n") f.write("S2:: \n")
for v,val in sos.iteritems(): for v,val in sos.items():
f.write(" %s: %.12g\n" % (v.name, val)) f.write(" %s: %.12g\n" % (v.name, val))
f.write("End\n") f.write("End\n")
f.close() f.close()
@@ -1830,7 +1835,7 @@ class FractionElasticSubProblem(FixedElasticSubProblem):
self.denominator = denominator self.denominator = denominator
self.complement = denominator - numerator self.complement = denominator - numerator
else: else:
raise PulpError, 'only one of denominator and complement must be specified' raise PulpError('only one of denominator and complement must be specified')
self.RHS = RHS self.RHS = RHS
self.lowTarget = self.upTarget = None self.lowTarget = self.upTarget = None
LpProblem.__init__(self, subProblemName, LpMinimize) LpProblem.__init__(self, subProblemName, LpMinimize)
@@ -1972,7 +1977,7 @@ def combination(orgset, k = None):
>>> c = combination([1,2,3,4],2) >>> c = combination([1,2,3,4],2)
>>> for s in c: >>> for s in c:
... print s ... print(s)
(1, 2) (1, 2)
(1, 3) (1, 3)
(1, 4) (1, 4)
@@ -2014,7 +2019,7 @@ def permutation(orgset, k = None):
>>> c = permutation([1,2,3,4],2) >>> c = permutation([1,2,3,4],2)
>>> for s in c: >>> for s in c:
... print s ... print(s)
(1, 2) (1, 2)
(1, 3) (1, 3)
(1, 4) (1, 4)
@@ -2061,7 +2066,7 @@ def allpermutations(orgset,k):
>>> c = allpermutations([1,2,3,4],2) >>> c = allpermutations([1,2,3,4],2)
>>> for s in c: >>> for s in c:
... print s ... print(s)
(1,) (1,)
(2,) (2,)
(3,) (3,)
@@ -2094,7 +2099,7 @@ def allcombinations(orgset,k):
>>> c = allcombinations([1,2,3,4],2) >>> c = allcombinations([1,2,3,4],2)
>>> for s in c: >>> for s in c:
... print s ... print(s)
(1,) (1,)
(2,) (2,)
(3,) (3,)
@@ -2203,18 +2208,18 @@ def configSolvers():
""" """
configlist = [(cplex_dll_path,"cplexpath","CPLEX: "), configlist = [(cplex_dll_path,"cplexpath","CPLEX: "),
(coinMP_path, "coinmppath","CoinMP dll (windows only): ")] (coinMP_path, "coinmppath","CoinMP dll (windows only): ")]
print ("Please type the full path including filename and extension \n" + print("Please type the full path including filename and extension \n" +
"for each solver available") "for each solver available")
configdict = {} configdict = {}
for (default, key, msg) in configlist: for (default, key, msg) in configlist:
value = raw_input(msg + "[" + str(default) +"]") value = input(msg + "[" + str(default) +"]")
if value: if value:
configdict[key] = value configdict[key] = value
setConfigInformation(**configdict) setConfigInformation(**configdict)
def pulpTestAll(): def pulpTestAll():
from tests import pulpTestSolver from .tests import pulpTestSolver
solvers = [PULP_CBC_CMD, solvers = [PULP_CBC_CMD,
CPLEX_DLL, CPLEX_DLL,
CPLEX_CMD, CPLEX_CMD,
@@ -2231,14 +2236,14 @@ def pulpTestAll():
for s in solvers: for s in solvers:
if s().available(): if s().available():
#~ try: try:
pulpTestSolver(s) pulpTestSolver(s)
print "* Solver", s, "passed." print("* Solver %s passed." % s)
#~ except Exception, e: except Exception as e:
#~ print e print(e)
#~ print "* Solver", s, "failed." print("* Solver", s, "failed.")
else: else:
print "Solver", s, "unavailable." print("Solver %s unavailable" % s)
def pulpDoctest(): def pulpDoctest():
""" """
@@ -2246,7 +2251,7 @@ def pulpDoctest():
""" """
import doctest import doctest
if __name__ != '__main__': if __name__ != '__main__':
import pulp from . import pulp
doctest.testmod(pulp) doctest.testmod(pulp)
else: else:
doctest.testmod() doctest.testmod()

View File

@@ -34,12 +34,15 @@ import os
import subprocess import subprocess
import sys import sys
from time import clock from time import clock
import ConfigParser try:
import sparse import configparser
except ImportError:
import ConfigParser as configparser
from . import sparse
import collections import collections
import warnings import warnings
from tempfile import mktemp from tempfile import mktemp
from constants import * from .constants import *
import logging import logging
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@@ -54,42 +57,46 @@ class PulpSolverError(PulpError):
def initialize(filename): def initialize(filename):
""" reads the configuration file to initialise the module""" """ reads the configuration file to initialise the module"""
here = os.path.dirname(filename) here = os.path.dirname(filename)
config = ConfigParser.SafeConfigParser({'here':here}) config = configparser.SafeConfigParser({'here':here})
config.read(filename) config.read(filename)
try: try:
cplex_dll_path = config.get("locations", "CplexPath") cplex_dll_path = config.get("locations", "CplexPath")
except ConfigParser.Error: except configparser.Error:
cplex_dll_path = 'libcplex110.so' cplex_dll_path = 'libcplex110.so'
try: try:
ilm_cplex_license = config.get("licenses", try:
ilm_cplex_license = config.get("licenses",
"ilm_cplex_license").decode("string-escape").replace('"','') "ilm_cplex_license").decode("string-escape").replace('"','')
except ConfigParser.Error: except AttributeError:
ilm_cplex_license = config.get("licenses",
"ilm_cplex_license").replace('"','')
except configparser.Error:
ilm_cplex_license = '' ilm_cplex_license = ''
try: try:
ilm_cplex_license_signature = config.getint("licenses", ilm_cplex_license_signature = config.getint("licenses",
"ilm_cplex_license_signature") "ilm_cplex_license_signature")
except ConfigParser.Error: except configparser.Error:
ilm_cplex_license_signature = 0 ilm_cplex_license_signature = 0
try: try:
coinMP_path = config.get("locations", "CoinMPPath").split(', ') coinMP_path = config.get("locations", "CoinMPPath").split(', ')
except ConfigParser.Error: except configparser.Error:
coinMP_path = ['libCoinMP.so'] coinMP_path = ['libCoinMP.so']
try: try:
gurobi_path = config.get("locations", "GurobiPath") gurobi_path = config.get("locations", "GurobiPath")
except ConfigParser.Error: except configparser.Error:
gurobi_path = '/opt/gurobi201/linux32/lib/python2.5' gurobi_path = '/opt/gurobi201/linux32/lib/python2.5'
try: try:
cbc_path = config.get("locations", "CbcPath") cbc_path = config.get("locations", "CbcPath")
except ConfigParser.Error: except configparser.Error:
cbc_path = 'cbc' cbc_path = 'cbc'
try: try:
glpk_path = config.get("locations", "GlpkPath") glpk_path = config.get("locations", "GlpkPath")
except ConfigParser.Error: except configparser.Error:
glpk_path = 'glpsol' glpk_path = 'glpsol'
try: try:
pulp_cbc_path = config.get("locations", "PulpCbcPath") pulp_cbc_path = config.get("locations", "PulpCbcPath")
except ConfigParser.Error: except configparser.Error:
pulp_cbc_path = 'cbc' pulp_cbc_path = 'cbc'
for i,path in enumerate(coinMP_path): for i,path in enumerate(coinMP_path):
if not os.path.dirname(path): if not os.path.dirname(path):
@@ -112,7 +119,7 @@ if __name__ != '__main__':
config_filename = os.path.join(DIRNAME, config_filename = os.path.join(DIRNAME,
PULPCFGFILE) PULPCFGFILE)
else: #run as a script else: #run as a script
from pulp import __file__ as fname from .pulp import __file__ as fname
DIRNAME = os.path.dirname(fname) DIRNAME = os.path.dirname(fname)
config_filename = os.path.join(DIRNAME, config_filename = os.path.join(DIRNAME,
PULPCFGFILE) PULPCFGFILE)
@@ -185,7 +192,7 @@ class LpSolver:
NumVarDoubleArray = ctypes.c_double * numVars NumVarDoubleArray = ctypes.c_double * numVars
objectCoeffs=NumVarDoubleArray() objectCoeffs=NumVarDoubleArray()
#print "Get objective Values" #print "Get objective Values"
for v,val in lp.objective.iteritems(): for v,val in lp.objective.items():
objectCoeffs[self.v2n[v]]=val objectCoeffs[self.v2n[v]]=val
#values for variables #values for variables
objectConst = ctypes.c_double(0.0) objectConst = ctypes.c_double(0.0)
@@ -228,7 +235,7 @@ class LpSolver:
i = i+1 i = i+1
#return the coefficient matrix as a series of vectors #return the coefficient matrix as a series of vectors
coeffs = lp.coefficients() coeffs = lp.coefficients()
sparseMatrix = sparse.Matrix(range(numRows), range(numVars)) sparseMatrix = sparse.Matrix(list(range(numRows)), list(range(numVars)))
for var,row,coeff in coeffs: for var,row,coeff in coeffs:
sparseMatrix.add(self.c2n[row], self.vname2n[var], coeff) sparseMatrix.add(self.c2n[row], self.vname2n[var], coeff)
(numels, mystartsBase, mylenBase, myindBase, (numels, mystartsBase, mylenBase, myindBase,
@@ -325,7 +332,7 @@ class GLPK_CMD(LpSolver_CMD):
def actualSolve(self, lp): def actualSolve(self, lp):
"""Solve a well formulated lp problem""" """Solve a well formulated lp problem"""
if not self.executable(self.path): if not self.executable(self.path):
raise PulpSolverError, "PuLP: cannot execute "+self.path raise PulpSolverError("PuLP: cannot execute "+self.path)
if not self.keepFiles: if not self.keepFiles:
pid = os.getpid() pid = os.getpid()
tmpLp = os.path.join(self.tmpDir, "%d-pulp.lp" % pid) tmpLp = os.path.join(self.tmpDir, "%d-pulp.lp" % pid)
@@ -345,18 +352,18 @@ class GLPK_CMD(LpSolver_CMD):
rc = subprocess.call(proc, stdout = pipe, rc = subprocess.call(proc, stdout = pipe,
stderr = pipe) stderr = pipe)
if rc: if rc:
raise PulpSolverError, "PuLP: Error while trying to execute "+self.path raise PulpSolverError("PuLP: Error while trying to execute "+self.path)
else: else:
if os.name != 'nt': if os.name != 'nt':
rc = os.spawnvp(os.P_WAIT, self.path, proc) rc = os.spawnvp(os.P_WAIT, self.path, proc)
else: else:
rc = os.spawnv(os.P_WAIT, self.executable(self.path), proc) rc = os.spawnv(os.P_WAIT, self.executable(self.path), proc)
if rc == 127: if rc == 127:
raise PulpSolverError, "PuLP: Error while trying to execute "+self.path raise PulpSolverError("PuLP: Error while trying to execute "+self.path)
self.solution_time += clock() self.solution_time += clock()
if not os.path.exists(tmpSol): if not os.path.exists(tmpSol):
raise PulpSolverError, "PuLP: Error while executing "+self.path raise PulpSolverError("PuLP: Error while executing "+self.path)
lp.status, values = self.readsol(tmpSol) lp.status, values = self.readsol(tmpSol)
lp.assignVarsVals(values) lp.assignVarsVals(values)
if not self.keepFiles: if not self.keepFiles:
@@ -368,7 +375,7 @@ class GLPK_CMD(LpSolver_CMD):
def readsol(self,filename): def readsol(self,filename):
"""Read a GLPK solution file""" """Read a GLPK solution file"""
f = file(filename) f = open(filename)
f.readline() f.readline()
rows = int(f.readline().split()[1]) rows = int(f.readline().split()[1])
cols = int(f.readline().split()[1]) cols = int(f.readline().split()[1])
@@ -386,7 +393,7 @@ class GLPK_CMD(LpSolver_CMD):
} }
#print "statusString ",statusString #print "statusString ",statusString
if statusString not in glpkStatus: if statusString not in glpkStatus:
raise PulpSolverError, "Unknown status returned by GLPK" raise PulpSolverError("Unknown status returned by GLPK")
status = glpkStatus[statusString] status = glpkStatus[statusString]
isInteger = statusString in ["INTEGER NON-OPTIMAL","INTEGER OPTIMAL","INTEGER UNDEFINED"] isInteger = statusString in ["INTEGER NON-OPTIMAL","INTEGER OPTIMAL","INTEGER UNDEFINED"]
values = {} values = {}
@@ -421,7 +428,7 @@ class CPLEX_CMD(LpSolver_CMD):
def actualSolve(self, lp): def actualSolve(self, lp):
"""Solve a well formulated lp problem""" """Solve a well formulated lp problem"""
if not self.executable(self.path): if not self.executable(self.path):
raise PulpSolverError, "PuLP: cannot execute "+self.path raise PulpSolverError("PuLP: cannot execute "+self.path)
if not self.keepFiles: if not self.keepFiles:
pid = os.getpid() pid = os.getpid()
tmpLp = os.path.join(self.tmpDir, "%d-pulp.lp" % pid) tmpLp = os.path.join(self.tmpDir, "%d-pulp.lp" % pid)
@@ -452,7 +459,7 @@ class CPLEX_CMD(LpSolver_CMD):
cplex_cmds += "quit\n" cplex_cmds += "quit\n"
cplex.communicate(cplex_cmds) cplex.communicate(cplex_cmds)
if cplex.returncode != 0: if cplex.returncode != 0:
raise PulpSolverError, "PuLP: Error while trying to execute "+self.path raise PulpSolverError("PuLP: Error while trying to execute "+self.path)
if not self.keepFiles: if not self.keepFiles:
try: os.remove(tmpLp) try: os.remove(tmpLp)
except: pass except: pass
@@ -486,7 +493,7 @@ class CPLEX_CMD(LpSolver_CMD):
"optimal":LpStatusOptimal, "optimal":LpStatusOptimal,
} }
if statusString not in cplexStatus: if statusString not in cplexStatus:
raise PulpSolverError, "Unknown status returned by CPLEX: "+statusString raise PulpSolverError("Unknown status returned by CPLEX: "+statusString)
status = cplexStatus[statusString] status = cplexStatus[statusString]
shadowPrices = {} shadowPrices = {}
@@ -638,13 +645,13 @@ try:
status = CPLEX_DLL.lib.CPXgetobjval(self.env, self.hprob, status = CPLEX_DLL.lib.CPXgetobjval(self.env, self.hprob,
byref(objectiveValue)) byref(objectiveValue))
if status != 0 and status != 1217: #no solution exists if status != 0 and status != 1217: #no solution exists
raise PulpSolverError, ("Error in CPXgetobjval status=" raise PulpSolverError("Error in CPXgetobjval status="
+ str(status)) + str(status))
status = CPLEX_DLL.lib.CPXgetx(self.env, self.hprob, status = CPLEX_DLL.lib.CPXgetx(self.env, self.hprob,
byref(x), 0, numcols - 1) byref(x), 0, numcols - 1)
if status != 0 and status != 1217: if status != 0 and status != 1217:
raise PulpSolverError, "Error in CPXgetx status=" + str(status) raise PulpSolverError("Error in CPXgetx status=" + str(status))
else: else:
status = CPLEX_DLL.lib.CPXsolution(self.env, self.hprob, status = CPLEX_DLL.lib.CPXsolution(self.env, self.hprob,
byref(solutionStatus), byref(solutionStatus),
@@ -676,7 +683,7 @@ try:
lp.assignConsSlack(constraintslackvalues) lp.assignConsSlack(constraintslackvalues)
#TODO: clear up the name of self.n2c #TODO: clear up the name of self.n2c
if self.msg: if self.msg:
print "Cplex status=", solutionStatus.value print("Cplex status=", solutionStatus.value)
lp.resolveOK = True lp.resolveOK = True
for var in lp.variables(): for var in lp.variables():
var.isModified = False var.isModified = False
@@ -710,14 +717,14 @@ try:
# has another license. Let us forgive bad user # has another license. Let us forgive bad user
# configuration: # configuration:
if not (runtime_status == 0) and self.msg: if not (runtime_status == 0) and self.msg:
print ( print(
"CPLEX library failed to load the runtime license" + "CPLEX library failed to load the runtime license" +
"the call returned status=%s" % str(runtime_status) + "the call returned status=%s" % str(runtime_status) +
"Please check the pulp config file.") "Please check the pulp config file.")
self.env = CPLEX_DLL.lib.CPXopenCPLEX(ctypes.byref(status)) self.env = CPLEX_DLL.lib.CPXopenCPLEX(ctypes.byref(status))
self.hprob = None self.hprob = None
if not(status.value == 0): if not(status.value == 0):
raise PulpSolverError, ("CPLEX library failed on " + raise PulpSolverError("CPLEX library failed on " +
"CPXopenCPLEX status=" + str(status)) "CPXopenCPLEX status=" + str(status))
@@ -727,7 +734,7 @@ try:
status=CPLEX_DLL.lib.CPXcloseCPLEX(self.env) status=CPLEX_DLL.lib.CPXcloseCPLEX(self.env)
self.env = self.hprob = None self.env = self.hprob = None
else: else:
raise PulpSolverError, "No CPLEX enviroment to close" raise PulpSolverError("No CPLEX enviroment to close")
def callSolver(self, isMIP): def callSolver(self, isMIP):
"""Solves the problem with cplex """Solves the problem with cplex
@@ -737,12 +744,12 @@ try:
if isMIP and self.mip: if isMIP and self.mip:
status= CPLEX_DLL.lib.CPXmipopt(self.env, self.hprob) status= CPLEX_DLL.lib.CPXmipopt(self.env, self.hprob)
if status != 0: if status != 0:
raise PulpSolverError, ("Error in CPXmipopt status=" raise PulpSolverError("Error in CPXmipopt status="
+ str(status)) + str(status))
else: else:
status = CPLEX_DLL.lib.CPXlpopt(self.env, self.hprob) status = CPLEX_DLL.lib.CPXlpopt(self.env, self.hprob)
if status != 0: if status != 0:
raise PulpSolverError, ("Error in CPXlpopt status=" raise PulpSolverError("Error in CPXlpopt status="
+ str(status)) + str(status))
self.cplexTime += clock() self.cplexTime += clock()
@@ -756,7 +763,7 @@ try:
self.hprob = CPLEX_DLL.lib.CPXcreateprob(self.env, self.hprob = CPLEX_DLL.lib.CPXcreateprob(self.env,
byref(status), lp.name) byref(status), lp.name)
if status.value != 0: if status.value != 0:
raise PulpSolverError, ("Error in CPXcreateprob status=" raise PulpSolverError("Error in CPXcreateprob status="
+ str(status)) + str(status))
(numcols, numrows, numels, rangeCount, (numcols, numrows, numels, rangeCount,
objSense, obj, objconst, objSense, obj, objconst,
@@ -768,14 +775,14 @@ try:
objSense, obj, rhs, rowSense, matbeg, matcnt, objSense, obj, rhs, rowSense, matbeg, matcnt,
matind, matval, lb, ub, None, colname, rowname) matind, matval, lb, ub, None, colname, rowname)
if status.value != 0: if status.value != 0:
raise PulpSolverError, ("Error in CPXcopylpwnames status=" + raise PulpSolverError("Error in CPXcopylpwnames status=" +
str(status)) str(status))
if lp.isMIP() and self.mip: if lp.isMIP() and self.mip:
status.value = CPLEX_DLL.lib.CPXcopyctype(self.env, status.value = CPLEX_DLL.lib.CPXcopyctype(self.env,
self.hprob, self.hprob,
xctype) xctype)
if status.value != 0: if status.value != 0:
raise PulpSolverError, ("Error in CPXcopyctype status=" + raise PulpSolverError("Error in CPXcopyctype status=" +
str(status)) str(status))
#set the initial solution #set the initial solution
self.callSolver(lp.isMIP()) self.callSolver(lp.isMIP())
@@ -867,9 +874,9 @@ try:
#return the coefficient matrix as a series of vectors #return the coefficient matrix as a series of vectors
myobjectCoeffs = {} myobjectCoeffs = {}
numRows = len(lp.constraints) numRows = len(lp.constraints)
sparseMatrix = sparse.Matrix(range(numRows), range(numVars)) sparseMatrix = sparse.Matrix(list(range(numRows)), list(range(numVars)))
for var in vars: for var in vars:
for row,coeff in var.expression.iteritems(): for row,coeff in var.expression.items():
if row.name == lp.objective.name: if row.name == lp.objective.name:
myobjectCoeffs[var] = coeff myobjectCoeffs[var] = coeff
else: else:
@@ -911,8 +918,8 @@ try:
v2n = self.v2n v2n = self.v2n
else: else:
v2n = dict((v, self.v2n[v]) for v in vars) v2n = dict((v, self.v2n[v]) for v in vars)
ifirst = min(v2n.itervalues()) ifirst = min(v2n.values())
ilast = max(v2n.itervalues()) ilast = max(v2n.values())
row_t = ctypes.c_double * (ilast - ifirst + 1) row_t = ctypes.c_double * (ilast - ifirst + 1)
lo = row_t() lo = row_t()
@@ -921,10 +928,10 @@ try:
status.value = CPLEX_DLL.lib.CPXobjsa(self.env, self.hprob, status.value = CPLEX_DLL.lib.CPXobjsa(self.env, self.hprob,
ifirst, ilast, lo, hi) ifirst, ilast, lo, hi)
if status.value != 0: if status.value != 0:
raise PulpSolverError, ("Error in CPXobjsa, status=" raise PulpSolverError("Error in CPXobjsa, status="
+ str(status)) + str(status))
return dict((v, (lo[i - ifirst], hi[i - ifirst])) return dict((v, (lo[i - ifirst], hi[i - ifirst]))
for v, i in v2n.iteritems()) for v, i in v2n.items())
@@ -937,7 +944,7 @@ except (ImportError,OSError):
return False return False
def actualSolve(self, lp): def actualSolve(self, lp):
"""Solve a well formulated lp problem""" """Solve a well formulated lp problem"""
raise PulpSolverError, "CPLEX_DLL: Not Available" raise PulpSolverError("CPLEX_DLL: Not Available")
CPLEX = CPLEX_CMD CPLEX = CPLEX_CMD
try: try:
@@ -950,7 +957,7 @@ except (ImportError):
return False return False
def actualSolve(self, lp): def actualSolve(self, lp):
"""Solve a well formulated lp problem""" """Solve a well formulated lp problem"""
raise PulpSolverError, "CPLEX_PY: Not Available" raise PulpSolverError("CPLEX_PY: Not Available")
else: else:
class CPLEX_PY(LpSolver): class CPLEX_PY(LpSolver):
""" """
@@ -1071,7 +1078,7 @@ else:
#if the constraint is empty #if the constraint is empty
rows.append(([],[])) rows.append(([],[]))
else: else:
rows.append(zip(*expr)) rows.append(list(zip(*expr)))
if constraint.sense == LpConstraintLE: if constraint.sense == LpConstraintLE:
senses.append('L') senses.append('L')
elif constraint.sense == LpConstraintGE: elif constraint.sense == LpConstraintGE:
@@ -1079,7 +1086,7 @@ else:
elif constraint.sense == LpConstraintEQ: elif constraint.sense == LpConstraintEQ:
senses.append('E') senses.append('E')
else: else:
raise PulpSolverError, 'Detected an invalid constraint type' raise PulpSolverError('Detected an invalid constraint type')
rownames.append(name) rownames.append(name)
rhs.append(float(-constraint.constant)) rhs.append(float(-constraint.constant))
lp.solverModel.linear_constraints.add(lin_expr=rows, senses=senses, lp.solverModel.linear_constraints.add(lin_expr=rows, senses=senses,
@@ -1148,7 +1155,7 @@ else:
#put pi and slack variables against the constraints #put pi and slack variables against the constraints
#TODO: clear up the name of self.n2c #TODO: clear up the name of self.n2c
if self.msg: if self.msg:
print "Cplex status=", lp.cplex_status print("Cplex status=", lp.cplex_status)
lp.resolveOK = True lp.resolveOK = True
for var in lp.variables(): for var in lp.variables():
var.isModified = False var.isModified = False
@@ -1175,7 +1182,7 @@ class XPRESS(LpSolver_CMD):
def actualSolve(self, lp): def actualSolve(self, lp):
"""Solve a well formulated lp problem""" """Solve a well formulated lp problem"""
if not self.executable(self.path): if not self.executable(self.path):
raise PulpSolverError, "PuLP: cannot execute "+self.path raise PulpSolverError("PuLP: cannot execute "+self.path)
if not self.keepFiles: if not self.keepFiles:
pid = os.getpid() pid = os.getpid()
tmpLp = os.path.join(self.tmpDir, "%d-pulp.lp" % pid) tmpLp = os.path.join(self.tmpDir, "%d-pulp.lp" % pid)
@@ -1198,7 +1205,7 @@ class XPRESS(LpSolver_CMD):
xpress.write("WRITEPRTSOL "+tmpSol+"\n") xpress.write("WRITEPRTSOL "+tmpSol+"\n")
xpress.write("QUIT\n") xpress.write("QUIT\n")
if xpress.close() != None: if xpress.close() != None:
raise PulpSolverError, "PuLP: Error while executing "+self.path raise PulpSolverError("PuLP: Error while executing "+self.path)
status, values = self.readsol(tmpSol) status, values = self.readsol(tmpSol)
if not self.keepFiles: if not self.keepFiles:
try: os.remove(tmpLp) try: os.remove(tmpLp)
@@ -1213,7 +1220,7 @@ class XPRESS(LpSolver_CMD):
def readsol(self,filename): def readsol(self,filename):
"""Read an XPRESS solution file""" """Read an XPRESS solution file"""
f = file(filename) f = open(filename)
for i in range(6): f.readline() for i in range(6): f.readline()
l = f.readline().split() l = f.readline().split()
@@ -1225,7 +1232,7 @@ class XPRESS(LpSolver_CMD):
"Optimal":LpStatusOptimal, "Optimal":LpStatusOptimal,
} }
if statusString not in xpressStatus: if statusString not in xpressStatus:
raise PulpSolverError, "Unknow status returned by XPRESS: "+statusString raise PulpSolverError("Unknow status returned by XPRESS: "+statusString)
status = xpressStatus[statusString] status = xpressStatus[statusString]
values = {} values = {}
while 1: while 1:
@@ -1282,8 +1289,8 @@ class COIN_CMD(LpSolver_CMD):
def solve_CBC(self, lp, use_mps=True): def solve_CBC(self, lp, use_mps=True):
"""Solve a MIP problem using CBC""" """Solve a MIP problem using CBC"""
if not self.executable(self.path): if not self.executable(self.path):
raise PulpSolverError, "Pulp: cannot execute %s cwd: %s"%(self.path, raise PulpSolverError("Pulp: cannot execute %s cwd: %s"%(self.path,
os.getcwd()) os.getcwd()))
if not self.keepFiles: if not self.keepFiles:
pid = os.getpid() pid = os.getpid()
tmpLp = os.path.join(self.tmpDir, "%d-pulp.lp" % pid) tmpLp = os.path.join(self.tmpDir, "%d-pulp.lp" % pid)
@@ -1333,10 +1340,10 @@ class COIN_CMD(LpSolver_CMD):
cbc = subprocess.Popen((self.path + cmds).split(), stdout = pipe, cbc = subprocess.Popen((self.path + cmds).split(), stdout = pipe,
stderr = pipe) stderr = pipe)
if cbc.wait() != 0: if cbc.wait() != 0:
raise PulpSolverError, "Pulp: Error while trying to execute " + \ raise PulpSolverError("Pulp: Error while trying to execute " + \
self.path self.path)
if not os.path.exists(tmpSol): if not os.path.exists(tmpSol):
raise PulpSolverError, "Pulp: Error while executing "+self.path raise PulpSolverError("Pulp: Error while executing "+self.path)
if use_mps: if use_mps:
lp.status, values, reducedCosts, shadowPrices, slacks = self.readsol_MPS( lp.status, values, reducedCosts, shadowPrices, slacks = self.readsol_MPS(
tmpSol, lp, lp.variables(), tmpSol, lp, lp.variables(),
@@ -1367,10 +1374,10 @@ class COIN_CMD(LpSolver_CMD):
values = {} values = {}
reverseVn = {} reverseVn = {}
for k, n in variablesNames.iteritems(): for k, n in variablesNames.items():
reverseVn[n] = k reverseVn[n] = k
reverseCn = {} reverseCn = {}
for k, n in constraintsNames.iteritems(): for k, n in constraintsNames.items():
reverseCn[n] = k reverseCn[n] = k
@@ -1384,7 +1391,7 @@ class COIN_CMD(LpSolver_CMD):
'Infeasible': LpStatusInfeasible, 'Infeasible': LpStatusInfeasible,
'Unbounded': LpStatusUnbounded, 'Unbounded': LpStatusUnbounded,
'Stopped': LpStatusNotSolved} 'Stopped': LpStatusNotSolved}
f = file(filename) f = open(filename)
statusstr = f.readline().split()[0] statusstr = f.readline().split()[0]
status = cbcStatus.get(statusstr, LpStatusUndefined) status = cbcStatus.get(statusstr, LpStatusUndefined)
for l in f: for l in f:
@@ -1416,7 +1423,7 @@ class COIN_CMD(LpSolver_CMD):
'Infeasible': LpStatusInfeasible, 'Infeasible': LpStatusInfeasible,
'Unbounded': LpStatusUnbounded, 'Unbounded': LpStatusUnbounded,
'Stopped': LpStatusNotSolved} 'Stopped': LpStatusNotSolved}
f = file(filename) f = open(filename)
statusstr = f.readline().split()[0] statusstr = f.readline().split()[0]
status = cbcStatus.get(statusstr, LpStatusUndefined) status = cbcStatus.get(statusstr, LpStatusUndefined)
for l in f: for l in f:
@@ -1458,7 +1465,7 @@ class PULP_CBC_CMD(COIN_CMD):
return False return False
def actualSolve(self, lp, callback = None): def actualSolve(self, lp, callback = None):
"""Solve a well formulated lp problem""" """Solve a well formulated lp problem"""
raise PulpSolverError, "PULP_CBC_CMD: Not Available (check permissions on %s)" % self.arch_pulp_cbc_path raise PulpSolverError("PULP_CBC_CMD: Not Available (check permissions on %s)" % self.arch_pulp_cbc_path)
else: else:
def __init__(self, path=None, *args, **kwargs): def __init__(self, path=None, *args, **kwargs):
""" """
@@ -1501,7 +1508,7 @@ class COINMP_DLL(LpSolver):
return False return False
def actualSolve(self, lp): def actualSolve(self, lp):
"""Solve a well formulated lp problem""" """Solve a well formulated lp problem"""
raise PulpSolverError, "COINMP_DLL: Not Available" raise PulpSolverError("COINMP_DLL: Not Available")
else: else:
COIN_INT_LOGLEVEL = 7 COIN_INT_LOGLEVEL = 7
COIN_REAL_MAXSECONDS = 16 COIN_REAL_MAXSECONDS = 16
@@ -1584,7 +1591,7 @@ class COINMP_DLL(LpSolver):
ctypes.c_double(self.fracGap)) ctypes.c_double(self.fracGap))
#CoinGetInfinity is needed for varibles with no bounds #CoinGetInfinity is needed for varibles with no bounds
coinDblMax = self.lib.CoinGetInfinity() coinDblMax = self.lib.CoinGetInfinity()
if self.debug: print "Before getCoinMPArrays" if self.debug: print("Before getCoinMPArrays")
(numVars, numRows, numels, rangeCount, (numVars, numRows, numels, rangeCount,
objectSense, objectCoeffs, objectConst, objectSense, objectCoeffs, objectConst,
rhsValues, rangeValues, rowType, startsBase, rhsValues, rangeValues, rowType, startsBase,
@@ -1606,7 +1613,7 @@ class COINMP_DLL(LpSolver):
savestdout = os.dup(1) savestdout = os.dup(1)
os.close(1) os.close(1)
if os.dup(tempfile.fileno()) != 1: if os.dup(tempfile.fileno()) != 1:
raise PulpSolverError, "couldn't redirect stdout - dup() error" raise PulpSolverError("couldn't redirect stdout - dup() error")
self.coinTime = -clock() self.coinTime = -clock()
self.lib.CoinOptimizeProblem(hProb, 0); self.lib.CoinOptimizeProblem(hProb, 0);
self.coinTime += clock() self.coinTime += clock()
@@ -1689,7 +1696,7 @@ class GUROBI(LpSolver):
return False return False
def actualSolve(self, lp, callback = None): def actualSolve(self, lp, callback = None):
"""Solve a well formulated lp problem""" """Solve a well formulated lp problem"""
raise PulpSolverError, "GUROBI: Not Available" raise PulpSolverError("GUROBI: Not Available")
else: else:
def __init__(self, def __init__(self,
mip = True, mip = True,
@@ -1751,7 +1758,7 @@ class GUROBI(LpSolver):
except gurobipy.GurobiError: except gurobipy.GurobiError:
pass pass
if self.msg: if self.msg:
print "Gurobi status=", solutionStatus print("Gurobi status=", solutionStatus)
lp.resolveOK = True lp.resolveOK = True
for var in lp.variables(): for var in lp.variables():
var.isModified = False var.isModified = False
@@ -1802,7 +1809,7 @@ class GUROBI(LpSolver):
log.debug("add the Constraints to the problem") log.debug("add the Constraints to the problem")
for name,constraint in lp.constraints.items(): for name,constraint in lp.constraints.items():
#build the expression #build the expression
expr = gurobipy.LinExpr(constraint.values(), expr = gurobipy.LinExpr(list(constraint.values()),
[v.solverVar for v in constraint.keys()]) [v.solverVar for v in constraint.keys()])
if constraint.sense == LpConstraintLE: if constraint.sense == LpConstraintLE:
relation = gurobipy.GRB.LESS_EQUAL relation = gurobipy.GRB.LESS_EQUAL
@@ -1811,7 +1818,7 @@ class GUROBI(LpSolver):
elif constraint.sense == LpConstraintEQ: elif constraint.sense == LpConstraintEQ:
relation = gurobipy.GRB.EQUAL relation = gurobipy.GRB.EQUAL
else: else:
raise PulpSolverError, 'Detected an invalid constraint type' raise PulpSolverError('Detected an invalid constraint type')
constraint.solverConstraint = lp.solverModel.addConstr(expr, constraint.solverConstraint = lp.solverModel.addConstr(expr,
relation, -constraint.constant, name) relation, -constraint.constant, name)
lp.solverModel.update() lp.solverModel.update()
@@ -1868,7 +1875,7 @@ class GUROBI_CMD(LpSolver_CMD):
def actualSolve(self, lp): def actualSolve(self, lp):
"""Solve a well formulated lp problem""" """Solve a well formulated lp problem"""
if not self.executable(self.path): if not self.executable(self.path):
raise PulpSolverError, "PuLP: cannot execute "+self.path raise PulpSolverError("PuLP: cannot execute "+self.path)
if not self.keepFiles: if not self.keepFiles:
pid = os.getpid() pid = os.getpid()
tmpLp = os.path.join(self.tmpDir, "%d-pulp.lp" % pid) tmpLp = os.path.join(self.tmpDir, "%d-pulp.lp" % pid)
@@ -1895,7 +1902,7 @@ class GUROBI_CMD(LpSolver_CMD):
return_code = subprocess.call(cmd.split(), stdout = pipe, stderr = pipe) return_code = subprocess.call(cmd.split(), stdout = pipe, stderr = pipe)
if return_code != 0: if return_code != 0:
raise PulpSolverError, "PuLP: Error while trying to execute "+self.path raise PulpSolverError("PuLP: Error while trying to execute "+self.path)
if not self.keepFiles: if not self.keepFiles:
try: os.remove(tmpLp) try: os.remove(tmpLp)
except: pass except: pass
@@ -1921,7 +1928,7 @@ class GUROBI_CMD(LpSolver_CMD):
"""Read a Gurobi solution file""" """Read a Gurobi solution file"""
my_file = open(filename) my_file = open(filename)
try: try:
my_file.next() # skip the objective value next(my_file) # skip the objective value
except StopIteration: except StopIteration:
# Empty file not solved # Empty file not solved
warnings.warn('GUROBI_CMD does provide good solution status of non optimal solutions') warnings.warn('GUROBI_CMD does provide good solution status of non optimal solutions')
@@ -1964,7 +1971,7 @@ class PYGLPK(LpSolver):
return False return False
def actualSolve(self, lp, callback = None): def actualSolve(self, lp, callback = None):
"""Solve a well formulated lp problem""" """Solve a well formulated lp problem"""
raise PulpSolverError, "GLPK: Not Available" raise PulpSolverError("GLPK: Not Available")
else: else:
def __init__(self, def __init__(self,
mip = True, mip = True,
@@ -2051,7 +2058,7 @@ class PYGLPK(LpSolver):
if lp.sense == LpMaximize: if lp.sense == LpMaximize:
glpk.glp_set_obj_dir(prob, glpk.GLP_MAX) glpk.glp_set_obj_dir(prob, glpk.GLP_MAX)
log.debug("add the constraints to the problem") log.debug("add the constraints to the problem")
glpk.glp_add_rows(prob, len(lp.constraints.keys())) glpk.glp_add_rows(prob, len(list(lp.constraints.keys())))
for i, v in enumerate(lp.constraints.items(), start=1): for i, v in enumerate(lp.constraints.items(), start=1):
name, constraint = v name, constraint = v
glpk.glp_set_row_name(prob, i, name) glpk.glp_set_row_name(prob, i, name)
@@ -2065,7 +2072,7 @@ class PYGLPK(LpSolver):
glpk.glp_set_row_bnds(prob, i, glpk.GLP_FX, glpk.glp_set_row_bnds(prob, i, glpk.GLP_FX,
-constraint.constant, -constraint.constant) -constraint.constant, -constraint.constant)
else: else:
raise PulpSolverError, 'Detected an invalid constraint type' raise PulpSolverError('Detected an invalid constraint type')
constraint.glpk_index = i constraint.glpk_index = i
log.debug("add the variables to the problem") log.debug("add the variables to the problem")
glpk.glp_add_cols(prob, len(lp.variables())) glpk.glp_add_cols(prob, len(lp.variables()))
@@ -2097,7 +2104,7 @@ class PYGLPK(LpSolver):
glpk.glp_set_obj_coef(prob, var.glpk_index, value) glpk.glp_set_obj_coef(prob, var.glpk_index, value)
log.debug("set the problem matrix") log.debug("set the problem matrix")
for constraint in lp.constraints.values(): for constraint in lp.constraints.values():
l = len(constraint.items()) l = len(list(constraint.items()))
ind = glpk.intArray(l + 1) ind = glpk.intArray(l + 1)
val = glpk.doubleArray(l + 1) val = glpk.doubleArray(l + 1)
for j, v in enumerate(constraint.items(), start=1): for j, v in enumerate(constraint.items(), start=1):
@@ -2149,7 +2156,7 @@ class PYGLPK(LpSolver):
glpk.glp_set_row_bnds(prob, i, glpk.GLP_FX, glpk.glp_set_row_bnds(prob, i, glpk.GLP_FX,
-constraint.constant, -constraint.constant) -constraint.constant, -constraint.constant)
else: else:
raise PulpSolverError, 'Detected an invalid constraint type' raise PulpSolverError('Detected an invalid constraint type')
self.callSolver(lp, callback = callback) self.callSolver(lp, callback = callback)
#get the solution information #get the solution information
solutionStatus = self.findSolutionValues(lp) solutionStatus = self.findSolutionValues(lp)
@@ -2180,7 +2187,7 @@ class YAPOSIB(LpSolver):
return False return False
def actualSolve(self, lp, callback = None): def actualSolve(self, lp, callback = None):
"""Solve a well formulated lp problem""" """Solve a well formulated lp problem"""
raise PulpSolverError, "YAPOSIB: Not Available" raise PulpSolverError("YAPOSIB: Not Available")
else: else:
def __init__(self, def __init__(self,
mip = True, mip = True,
@@ -2224,7 +2231,7 @@ class YAPOSIB(LpSolver):
constr.pi = constr.solverConstraint.dual constr.pi = constr.solverConstraint.dual
constr.slack = -constr.constant - constr.solverConstraint.activity constr.slack = -constr.constant - constr.solverConstraint.activity
if self.msg: if self.msg:
print "yaposib status=", solutionStatus print("yaposib status=", solutionStatus)
lp.resolveOK = True lp.resolveOK = True
for var in lp.variables(): for var in lp.variables():
var.isModified = False var.isModified = False
@@ -2245,7 +2252,7 @@ class YAPOSIB(LpSolver):
savestdout = os.dup(1) savestdout = os.dup(1)
os.close(1) os.close(1)
if os.dup(tempfile.fileno()) != 1: if os.dup(tempfile.fileno()) != 1:
raise PulpSolverError, "couldn't redirect stdout - dup() error" raise PulpSolverError("couldn't redirect stdout - dup() error")
self.solveTime = -clock() self.solveTime = -clock()
lp.solverModel.solve(self.mip) lp.solverModel.solve(self.mip)
self.solveTime += clock() self.solveTime += clock()
@@ -2290,7 +2297,7 @@ class YAPOSIB(LpSolver):
row.upperbound = -constraint.constant row.upperbound = -constraint.constant
row.lowerbound = -constraint.constant row.lowerbound = -constraint.constant
else: else:
raise PulpSolverError, 'Detected an invalid constraint type' raise PulpSolverError('Detected an invalid constraint type')
row.name = name row.name = name
constraint.solverConstraint = row constraint.solverConstraint = row
@@ -2332,7 +2339,7 @@ class YAPOSIB(LpSolver):
row.upperbound = -constraint.constant row.upperbound = -constraint.constant
row.lowerbound = -constraint.constant row.lowerbound = -constraint.constant
else: else:
raise PulpSolverError, 'Detected an invalid constraint type' raise PulpSolverError('Detected an invalid constraint type')
self.callSolver(lp, callback = callback) self.callSolver(lp, callback = callback)
#get the solution information #get the solution information
solutionStatus = self.findSolutionValues(lp) solutionStatus = self.findSolutionValues(lp)

View File

@@ -46,19 +46,19 @@ class Matrix(dict):
self.rowdict[row][col] = item self.rowdict[row][col] = item
self.coldict[col][row] = item self.coldict[col][row] = item
else: else:
print self.cols print(self.cols)
raise RuntimeError, "col %s is not in the matrix columns"%col raise RuntimeError("col %s is not in the matrix columns"%col)
else: else:
raise RuntimeError, "row %s is not in the matrix rows"%row raise RuntimeError("row %s is not in the matrix rows"%row)
def addcol(self,col,rowitems): def addcol(self,col,rowitems):
"""adds a column """adds a column
""" """
if col in self.cols: if col in self.cols:
for row,item in rowitems.iteritems(): for row,item in rowitems.items():
self.add(row, col, item, colcheck = False) self.add(row, col, item, colcheck = False)
else: else:
raise RuntimeError, "col is not in the matrix columns" raise RuntimeError("col is not in the matrix columns")
@@ -73,8 +73,8 @@ class Matrix(dict):
lenBase = [] lenBase = []
for i,col in enumerate(self.cols): for i,col in enumerate(self.cols):
startsBase.append(len(elemBase)) startsBase.append(len(elemBase))
elemBase.extend(self.coldict[col].values()) elemBase.extend(list(self.coldict[col].values()))
indBase.extend(self.coldict[col].keys()) indBase.extend(list(self.coldict[col].keys()))
lenBase.append(len(elemBase) - startsBase[-1]) lenBase.append(len(elemBase) - startsBase[-1])
startsBase.append(len(elemBase)) startsBase.append(len(elemBase))
return numEls, startsBase, lenBase, indBase, elemBase return numEls, startsBase, lenBase, indBase, elemBase
@@ -82,11 +82,11 @@ class Matrix(dict):
if __name__ == "__main__": if __name__ == "__main__":
""" unit test """ unit test
""" """
rows = range(10) rows = list(range(10))
cols = range(50,60) cols = list(range(50,60))
mat = Matrix(rows,cols) mat = Matrix(rows,cols)
mat.add(1,52,"item") mat.add(1,52,"item")
mat.add(2,54,"stuff") mat.add(2,54,"stuff")
print mat.col_based_arrays() print(mat.col_based_arrays())

View File

@@ -1,7 +1,7 @@
""" """
Tests for pulp Tests for pulp
""" """
from pulp import * from .pulp import *
def pulpTestCheck(prob, solver, okstatus, sol = {}, def pulpTestCheck(prob, solver, okstatus, sol = {},
reducedcosts = None, reducedcosts = None,
@@ -16,41 +16,41 @@ def pulpTestCheck(prob, solver, okstatus, sol = {},
if status not in okstatus: if status not in okstatus:
prob.writeLP("debug.lp") prob.writeLP("debug.lp")
prob.writeMPS("debug.mps") prob.writeMPS("debug.mps")
print "Failure: status ==", status, "not in", okstatus print("Failure: status ==", status, "not in", okstatus)
print "Failure: status ==", LpStatus[status], "not in", \ print("Failure: status ==", LpStatus[status], "not in", \
[LpStatus[s] for s in okstatus] [LpStatus[s] for s in okstatus])
raise PulpError, "Tests failed for solver %s"%solver raise PulpError("Tests failed for solver %s"%solver)
if sol: if sol:
for v,x in sol.iteritems(): for v,x in sol.items():
if abs(v.varValue - x) > eps: if abs(v.varValue - x) > eps:
prob.writeLP("debug.lp") prob.writeLP("debug.lp")
prob.writeMPS("debug.mps") prob.writeMPS("debug.mps")
print "Test failed: var", v, "==", v.varValue, "!=", x print("Test failed: var", v, "==", v.varValue, "!=", x)
raise PulpError, "Tests failed for solver %s"%solver raise PulpError("Tests failed for solver %s"%solver)
if reducedcosts: if reducedcosts:
for v,dj in reducedcosts.iteritems(): for v,dj in reducedcosts.items():
if abs(v.dj - dj) > eps: if abs(v.dj - dj) > eps:
prob.writeLP("debug.lp") prob.writeLP("debug.lp")
prob.writeMPS("debug.mps") prob.writeMPS("debug.mps")
print "Test failed: var.dj", v, "==", v.dj, "!=", dj print("Test failed: var.dj", v, "==", v.dj, "!=", dj)
raise PulpError, "Tests failed for solver %s"%solver raise PulpError("Tests failed for solver %s"%solver)
if duals: if duals:
for cname,p in duals.iteritems(): for cname,p in duals.items():
c = prob.constraints[cname] c = prob.constraints[cname]
if abs(c.pi - p) > eps: if abs(c.pi - p) > eps:
prob.writeLP("debug.lp") prob.writeLP("debug.lp")
prob.writeMPS("debug.mps") prob.writeMPS("debug.mps")
print "Test failed: constraint.pi", cname , "==", c.pi, "!=", p print("Test failed: constraint.pi", cname , "==", c.pi, "!=", p)
raise PulpError, "Tests failed for solver %s"%solver raise PulpError("Tests failed for solver %s"%solver)
if slacks: if slacks:
for cname,slack in slacks.iteritems(): for cname,slack in slacks.items():
c = prob.constraints[cname] c = prob.constraints[cname]
if abs(c.slack - slack) > eps: if abs(c.slack - slack) > eps:
prob.writeLP("debug.lp") prob.writeLP("debug.lp")
prob.writeMPS("debug.mps") prob.writeMPS("debug.mps")
print ("Test failed: constraint.slack", cname , "==", print(("Test failed: constraint.slack", cname , "==",
c.slack, "!=", slack) c.slack, "!=", slack))
raise PulpError, "Tests failed for solver %s"%solver raise PulpError("Tests failed for solver %s"%solver)
def pulpTest001(solver): def pulpTest001(solver):
""" """
@@ -61,7 +61,7 @@ def pulpTest001(solver):
z = LpVariable("z", 0) z = LpVariable("z", 0)
c1 = x+y <= 5 c1 = x+y <= 5
c2 = c1 + z -z c2 = c1 + z -z
print "\t Testing zero subtraction" print("\t Testing zero subtraction")
assert str(c2) #will raise an exception assert str(c2) #will raise an exception
def pulpTest010(solver): def pulpTest010(solver):
@@ -76,7 +76,7 @@ def pulpTest010(solver):
prob += x+z >= 10, "c2" prob += x+z >= 10, "c2"
prob += -y+z == 7, "c3" prob += -y+z == 7, "c3"
prob += w >= 0, "c4" prob += w >= 0, "c4"
print "\t Testing continuous LP solution" print("\t Testing continuous LP solution")
pulpTestCheck(prob, solver, [LpStatusOptimal], {x:4, y:-1, z:6, w:0}) pulpTestCheck(prob, solver, [LpStatusOptimal], {x:4, y:-1, z:6, w:0})
def pulpTest011(solver): def pulpTest011(solver):
@@ -91,7 +91,7 @@ def pulpTest011(solver):
prob += x+z >= 10, "c2" prob += x+z >= 10, "c2"
prob += -y+z == 7, "c3" prob += -y+z == 7, "c3"
prob += w >= 0, "c4" prob += w >= 0, "c4"
print "\t Testing maximize continuous LP solution" print("\t Testing maximize continuous LP solution")
pulpTestCheck(prob, solver, [LpStatusOptimal], {x:4, y:1, z:8, w:0}) pulpTestCheck(prob, solver, [LpStatusOptimal], {x:4, y:1, z:8, w:0})
def pulpTest012(solver): def pulpTest012(solver):
@@ -106,13 +106,13 @@ def pulpTest012(solver):
prob += x+z >= 10, "c2" prob += x+z >= 10, "c2"
prob += -y+z == 7, "c3" prob += -y+z == 7, "c3"
prob += w >= 0, "c4" prob += w >= 0, "c4"
print "\t Testing unbounded continuous LP solution" print("\t Testing unbounded continuous LP solution")
if solver.__class__ in [GUROBI, CPLEX_CMD, YAPOSIB, CPLEX_PY]: if solver.__class__ in [GUROBI, CPLEX_CMD, YAPOSIB, CPLEX_PY]:
# These solvers report infeasible or unbounded # These solvers report infeasible or unbounded
pulpTestCheck(prob, solver, [LpStatusInfeasible]) pulpTestCheck(prob, solver, [LpStatusInfeasible])
elif solver.__class__ in [COINMP_DLL,]: elif solver.__class__ in [COINMP_DLL,]:
# COINMP_DLL is just plain wrong # COINMP_DLL is just plain wrong
print '\t\t Error in CoinMP it reports Optimal' print('\t\t Error in CoinMP it reports Optimal')
pulpTestCheck(prob, solver, [LpStatusOptimal]) pulpTestCheck(prob, solver, [LpStatusOptimal])
elif solver.__class__ is GLPK_CMD: elif solver.__class__ is GLPK_CMD:
# GLPK_CMD Does not report unbounded problems, correctly # GLPK_CMD Does not report unbounded problems, correctly
@@ -136,7 +136,7 @@ def pulpTest013(solver):
prob += x+z >= 10, "c2" prob += x+z >= 10, "c2"
prob += -y+z == 7, "c3" prob += -y+z == 7, "c3"
prob += w >= 0, "c4" prob += w >= 0, "c4"
print "\t Testing Long Names" print("\t Testing Long Names")
if solver.__class__ in [CPLEX_CMD, GLPK_CMD, GUROBI_CMD]: if solver.__class__ in [CPLEX_CMD, GLPK_CMD, GUROBI_CMD]:
try: try:
pulpTestCheck(prob, solver, [LpStatusOptimal], {x:4, y:-1, z:6, w:0}) pulpTestCheck(prob, solver, [LpStatusOptimal], {x:4, y:-1, z:6, w:0})
@@ -158,7 +158,7 @@ def pulpTest014(solver):
prob += x+z >= 10, "c2" prob += x+z >= 10, "c2"
prob += -y+z == 7, "c3" prob += -y+z == 7, "c3"
prob += w >= 0, "c4" prob += w >= 0, "c4"
print "\t Testing repeated Names" print("\t Testing repeated Names")
if solver.__class__ in [COIN_CMD, PULP_CBC_CMD, CPLEX_CMD, CPLEX_PY, if solver.__class__ in [COIN_CMD, PULP_CBC_CMD, CPLEX_CMD, CPLEX_PY,
GLPK_CMD, GUROBI_CMD]: GLPK_CMD, GUROBI_CMD]:
try: try:
@@ -182,7 +182,7 @@ def pulpTest015(solver):
prob += -y+z == 7, "c3" prob += -y+z == 7, "c3"
prob += w >= 0, "c4" prob += w >= 0, "c4"
prob += lpSum([0, 0]) <= 0, "c5" prob += lpSum([0, 0]) <= 0, "c5"
print "\t Testing zero constraint" print("\t Testing zero constraint")
pulpTestCheck(prob, solver, [LpStatusOptimal], {x:4, y:-1, z:6, w:0}) pulpTestCheck(prob, solver, [LpStatusOptimal], {x:4, y:-1, z:6, w:0})
def pulpTest016(solver): def pulpTest016(solver):
@@ -197,7 +197,7 @@ def pulpTest016(solver):
prob += -y+z == 7, "c3" prob += -y+z == 7, "c3"
prob += w >= 0, "c4" prob += w >= 0, "c4"
prob += lpSum([0, 0]) <= 0, "c5" prob += lpSum([0, 0]) <= 0, "c5"
print "\t Testing zero objective" print("\t Testing zero objective")
pulpTestCheck(prob, solver, [LpStatusOptimal]) pulpTestCheck(prob, solver, [LpStatusOptimal])
def pulpTest017(solver): def pulpTest017(solver):
@@ -213,7 +213,7 @@ def pulpTest017(solver):
prob += -y+z == 7, "c3" prob += -y+z == 7, "c3"
prob += w >= 0, "c4" prob += w >= 0, "c4"
prob += lpSum([0, 0]) <= 0, "c5" prob += lpSum([0, 0]) <= 0, "c5"
print "\t Testing LpVariable (not LpAffineExpression) objective" print("\t Testing LpVariable (not LpAffineExpression) objective")
pulpTestCheck(prob, solver, [LpStatusOptimal]) pulpTestCheck(prob, solver, [LpStatusOptimal])
def pulpTest018(solver): def pulpTest018(solver):
@@ -229,7 +229,7 @@ def pulpTest018(solver):
prob += -y+z == 7, "c3" prob += -y+z == 7, "c3"
prob += w >= 0, "c4" prob += w >= 0, "c4"
if solver.__class__ in [COIN_CMD]: if solver.__class__ in [COIN_CMD]:
print "\t Testing Long lines in LP" print("\t Testing Long lines in LP")
pulpTestCheck(prob, solver, [LpStatusOptimal], {x:4, y:-1, z:6, w:0}, pulpTestCheck(prob, solver, [LpStatusOptimal], {x:4, y:-1, z:6, w:0},
use_mps=False) use_mps=False)
@@ -243,7 +243,7 @@ def pulpTest020(solver):
prob += x+y <= 5, "c1" prob += x+y <= 5, "c1"
prob += x+z >= 10, "c2" prob += x+z >= 10, "c2"
prob += -y+z == 7.5, "c3" prob += -y+z == 7.5, "c3"
print "\t Testing MIP solution" print("\t Testing MIP solution")
pulpTestCheck(prob, solver, [LpStatusOptimal], {x:3, y:-0.5, z:7}) pulpTestCheck(prob, solver, [LpStatusOptimal], {x:3, y:-0.5, z:7})
def pulpTest030(solver): def pulpTest030(solver):
@@ -257,7 +257,7 @@ def pulpTest030(solver):
prob += x+z >= 10, "c2" prob += x+z >= 10, "c2"
prob += -y+z == 7.5, "c3" prob += -y+z == 7.5, "c3"
solver.mip = 0 solver.mip = 0
print "\t Testing MIP relaxation" print("\t Testing MIP relaxation")
if solver.__class__ in [GUROBI_CMD]: if solver.__class__ in [GUROBI_CMD]:
#gurobi command does not let the problem be relaxed #gurobi command does not let the problem be relaxed
pulpTestCheck(prob, solver, [LpStatusOptimal], {x:3.0, y:-0.5, z:7}) pulpTestCheck(prob, solver, [LpStatusOptimal], {x:3.0, y:-0.5, z:7})
@@ -274,7 +274,7 @@ def pulpTest040(solver):
prob += x+y <= 5, "c1" prob += x+y <= 5, "c1"
prob += x+z >= 10, "c2" prob += x+z >= 10, "c2"
prob += -y+z == 7.5, "c3" prob += -y+z == 7.5, "c3"
print "\t Testing feasibility problem (no objective)" print("\t Testing feasibility problem (no objective)")
pulpTestCheck(prob, solver, [LpStatusOptimal]) pulpTestCheck(prob, solver, [LpStatusOptimal])
@@ -287,7 +287,7 @@ def pulpTest050(solver):
prob += x+y <= 5.2, "c1" prob += x+y <= 5.2, "c1"
prob += x+z >= 10.3, "c2" prob += x+z >= 10.3, "c2"
prob += -y+z == 17.5, "c3" prob += -y+z == 17.5, "c3"
print "\t Testing an infeasible problem" print("\t Testing an infeasible problem")
if solver.__class__ is GLPK_CMD: if solver.__class__ is GLPK_CMD:
# GLPK_CMD return codes are not informative enough # GLPK_CMD return codes are not informative enough
pulpTestCheck(prob, solver, [LpStatusUndefined]) pulpTestCheck(prob, solver, [LpStatusUndefined])
@@ -306,14 +306,14 @@ def pulpTest060(solver):
prob += x+y <= 5.2, "c1" prob += x+y <= 5.2, "c1"
prob += x+z >= 10.3, "c2" prob += x+z >= 10.3, "c2"
prob += -y+z == 7.4, "c3" prob += -y+z == 7.4, "c3"
print "\t Testing an integer infeasible problem" print("\t Testing an integer infeasible problem")
if solver.__class__ in [GLPK_CMD, COIN_CMD, PULP_CBC_CMD]: if solver.__class__ in [GLPK_CMD, COIN_CMD, PULP_CBC_CMD]:
# GLPK_CMD returns InfeasibleOrUnbounded # GLPK_CMD returns InfeasibleOrUnbounded
pulpTestCheck(prob, solver, [LpStatusInfeasible, LpStatusUndefined]) pulpTestCheck(prob, solver, [LpStatusInfeasible, LpStatusUndefined])
elif solver.__class__ in [COINMP_DLL]: elif solver.__class__ in [COINMP_DLL]:
#Currently there is an error in COINMP for problems where #Currently there is an error in COINMP for problems where
#presolve eliminates too many variables #presolve eliminates too many variables
print "\t\t Error in CoinMP to be fixed, reports Optimal" print("\t\t Error in CoinMP to be fixed, reports Optimal")
pulpTestCheck(prob, solver, [LpStatusOptimal]) pulpTestCheck(prob, solver, [LpStatusOptimal])
elif solver.__class__ in [GUROBI_CMD]: elif solver.__class__ in [GUROBI_CMD]:
pulpTestCheck(prob, solver, [LpStatusNotSolved]) pulpTestCheck(prob, solver, [LpStatusNotSolved])
@@ -337,7 +337,7 @@ def pulpTest070(solver):
x = LpVariable("x", 0, 4, LpContinuous, obj + a + b) x = LpVariable("x", 0, 4, LpContinuous, obj + a + b)
y = LpVariable("y", -1, 1, LpContinuous, 4*obj + a - c) y = LpVariable("y", -1, 1, LpContinuous, 4*obj + a - c)
z = LpVariable("z", 0, None, LpContinuous, 9*obj + b + c) z = LpVariable("z", 0, None, LpContinuous, 9*obj + b + c)
print "\t Testing column based modelling" print("\t Testing column based modelling")
pulpTestCheck(prob, solver, [LpStatusOptimal], {x:4, y:-1, z:6}) pulpTestCheck(prob, solver, [LpStatusOptimal], {x:4, y:-1, z:6})
def pulpTest075(solver): def pulpTest075(solver):
@@ -359,7 +359,7 @@ def pulpTest075(solver):
z = LpVariable("z", 0, None, LpContinuous, 9*obj + b + c) z = LpVariable("z", 0, None, LpContinuous, 9*obj + b + c)
if solver.__class__ in [CPLEX_DLL, CPLEX_CMD, COINMP_DLL, YAPOSIB, if solver.__class__ in [CPLEX_DLL, CPLEX_CMD, COINMP_DLL, YAPOSIB,
PYGLPK]: PYGLPK]:
print "\t Testing column based modelling with empty constraints" print("\t Testing column based modelling with empty constraints")
pulpTestCheck(prob, solver, [LpStatusOptimal], {x:4, y:-1, z:6}) pulpTestCheck(prob, solver, [LpStatusOptimal], {x:4, y:-1, z:6})
def pulpTest080(solver): def pulpTest080(solver):
@@ -381,7 +381,7 @@ def pulpTest080(solver):
if solver.__class__ in [CPLEX_DLL, CPLEX_CMD, COINMP_DLL, if solver.__class__ in [CPLEX_DLL, CPLEX_CMD, COINMP_DLL,
PULP_CBC_CMD, YAPOSIB, PYGLPK]: PULP_CBC_CMD, YAPOSIB, PYGLPK]:
print "\t Testing dual variables and slacks reporting" print("\t Testing dual variables and slacks reporting")
pulpTestCheck(prob, solver, [LpStatusOptimal], pulpTestCheck(prob, solver, [LpStatusOptimal],
sol = {x:4, y:-1, z:6}, sol = {x:4, y:-1, z:6},
reducedcosts = {x:0, y:12, z:0}, reducedcosts = {x:0, y:12, z:0},
@@ -408,7 +408,7 @@ def pulpTest090(solver):
prob.resolve() prob.resolve()
z = LpVariable("z", 0, None, LpContinuous, 9*obj + b + c) z = LpVariable("z", 0, None, LpContinuous, 9*obj + b + c)
if solver.__class__ in [CPLEX_DLL, COINMP_DLL]: if solver.__class__ in [CPLEX_DLL, COINMP_DLL]:
print "\t Testing resolve of problem" print("\t Testing resolve of problem")
prob.resolve() prob.resolve()
#difficult to check this is doing what we want as the resolve is #difficult to check this is doing what we want as the resolve is
#over ridden if it is not implemented #over ridden if it is not implemented
@@ -429,7 +429,7 @@ def pulpTest100(solver):
prob += x <= 1, "c1" prob += x <= 1, "c1"
if solver.__class__ in [CPLEX_DLL, COINMP_DLL, GUROBI]: if solver.__class__ in [CPLEX_DLL, COINMP_DLL, GUROBI]:
print "\t Testing Sequential Solves" print("\t Testing Sequential Solves")
status = prob.sequentialSolve([obj1,obj2], solver = solver) status = prob.sequentialSolve([obj1,obj2], solver = solver)
pulpTestCheck(prob, solver, [[LpStatusOptimal,LpStatusOptimal]], pulpTestCheck(prob, solver, [[LpStatusOptimal,LpStatusOptimal]],
sol = {x:0, y:1}, sol = {x:0, y:1},
@@ -450,7 +450,7 @@ def pulpTest110(solver):
prob += -y+z == 7, "c3" prob += -y+z == 7, "c3"
prob += w >= 0, "c4" prob += w >= 0, "c4"
prob += LpFractionConstraint(x, z, LpConstraintEQ, 0.5, name = 'c5') prob += LpFractionConstraint(x, z, LpConstraintEQ, 0.5, name = 'c5')
print "\t Testing fractional constraints" print("\t Testing fractional constraints")
pulpTestCheck(prob, solver, [LpStatusOptimal], pulpTestCheck(prob, solver, [LpStatusOptimal],
{x:10/3.0, y:-1/3.0, z:20/3.0, w:0}) {x:10/3.0, y:-1/3.0, z:20/3.0, w:0})
@@ -468,7 +468,7 @@ def pulpTest120(solver):
prob += x+z >= 10, "c2" prob += x+z >= 10, "c2"
prob += -y+z == 7, "c3" prob += -y+z == 7, "c3"
prob.extend((w >= -1).makeElasticSubProblem()) prob.extend((w >= -1).makeElasticSubProblem())
print "\t Testing elastic constraints (no change)" print("\t Testing elastic constraints (no change)")
pulpTestCheck(prob, solver, [LpStatusOptimal], pulpTestCheck(prob, solver, [LpStatusOptimal],
{x:4, y:-1, z:6, w:-1}) {x:4, y:-1, z:6, w:-1})
@@ -486,7 +486,7 @@ def pulpTest121(solver):
prob += x+z >= 10, "c2" prob += x+z >= 10, "c2"
prob += -y+z == 7, "c3" prob += -y+z == 7, "c3"
prob.extend((w >= -1).makeElasticSubProblem(proportionFreeBound = 0.1)) prob.extend((w >= -1).makeElasticSubProblem(proportionFreeBound = 0.1))
print "\t Testing elastic constraints (freebound)" print("\t Testing elastic constraints (freebound)")
pulpTestCheck(prob, solver, [LpStatusOptimal], pulpTestCheck(prob, solver, [LpStatusOptimal],
{x:4, y:-1, z:6, w:-1.1}) {x:4, y:-1, z:6, w:-1.1})
@@ -504,7 +504,7 @@ def pulpTest122(solver):
prob += x+z >= 10, "c2" prob += x+z >= 10, "c2"
prob += -y+z == 7, "c3" prob += -y+z == 7, "c3"
prob.extend((w >= -1).makeElasticSubProblem(penalty = 1.1)) prob.extend((w >= -1).makeElasticSubProblem(penalty = 1.1))
print "\t Testing elastic constraints (penalty unchanged)" print("\t Testing elastic constraints (penalty unchanged)")
prob.writeLP('debug.lp') prob.writeLP('debug.lp')
pulpTestCheck(prob, solver, [LpStatusOptimal], pulpTestCheck(prob, solver, [LpStatusOptimal],
{x:4, y:-1, z:6, w:-1.0}) {x:4, y:-1, z:6, w:-1.0})
@@ -523,7 +523,7 @@ def pulpTest123(solver):
prob += x+z >= 10, "c2" prob += x+z >= 10, "c2"
prob += -y+z == 7, "c3" prob += -y+z == 7, "c3"
prob.extend((w >= -1).makeElasticSubProblem(penalty = 0.9)) prob.extend((w >= -1).makeElasticSubProblem(penalty = 0.9))
print "\t Testing elastic constraints (penalty unbounded)" print("\t Testing elastic constraints (penalty unbounded)")
prob.writeLP('debug.lp') prob.writeLP('debug.lp')
if solver.__class__ in [COINMP_DLL, GUROBI, CPLEX_CMD, CPLEX_PY, YAPOSIB]: if solver.__class__ in [COINMP_DLL, GUROBI, CPLEX_CMD, CPLEX_PY, YAPOSIB]:
# COINMP_DLL Does not report unbounded problems, correctly # COINMP_DLL Does not report unbounded problems, correctly

View File

@@ -1,5 +1,5 @@
from pulp.amply import Amply, AmplyError from pulp.amply import Amply, AmplyError
from StringIO import StringIO from io import StringIO
from nose.tools import assert_raises from nose.tools import assert_raises
@@ -38,7 +38,10 @@ def test_attr_access():
assert result == 4 assert result == 4
def test_from_file(): def test_from_file():
s = StringIO("param T:= 4;") try:
s = StringIO("param T:= 4;")
except TypeError:
s = StringIO(u"param T:= 4;")
assert Amply.from_file(s).T == 4 assert Amply.from_file(s).T == 4
def test_load_string(): def test_load_string():
@@ -50,7 +53,10 @@ def test_load_string():
def test_load_file(): def test_load_file():
a = Amply("param T:= 4; param X{foo};") a = Amply("param T:= 4; param X{foo};")
s = StringIO("param S := 6; param X := 1 2;") try:
s = StringIO("param S := 6; param X := 1 2;")
except TypeError:
s = StringIO(u"param S := 6; param X := 1 2;")
a.load_file(s) a.load_file(s)
assert a.T == 4 assert a.T == 4
assert a.S == 6 assert a.S == 6