fix for asCplexAffineExpression and duals from cbc

This commit is contained in:
Stuart Mitchell
2013-10-31 23:00:25 +13:00
parent 5bbbfcc06c
commit 4aa7bbde0c
4 changed files with 39 additions and 40 deletions

View File

@@ -1 +1 @@
1.5.4
1.5.5

View File

@@ -16,54 +16,54 @@ class Pattern:
totalRollLength = 20
lenOpts = ["5", "7", "9"]
numPatterns = 0
def __init__(self, name, lengths = None):
self.name = name
self.lengthsdict = dict(zip(self.lenOpts,lengths))
Pattern.numPatterns += 1
def __str__(self):
return self.name
def trim(self):
return Pattern.totalRollLength - sum([int(i)*int(self.lengthsdict[i]) for i in self.lengthsdict])
def createMaster():
rollData = {#Length Demand SalePrice
"5": [150, 0.25],
"7": [200, 0.33],
"9": [300, 0.40]}
(rollDemand,surplusPrice) = splitDict(rollData)
# The variable 'prob' is created
prob = LpProblem("MasterSpongeRollProblem",LpMinimize)
# The variable 'obj' is created and set as the LP's objective function
obj = LpConstraintVar("Obj")
prob.setObjective(obj)
# The constraints are initialised and added to prob
constraints = {}
for l in Pattern.lenOpts:
constraints[l]= LpConstraintVar("Min" + str(l), LpConstraintGE, rollDemand[l])
prob += constraints[l]
# The surplus variables are created
surplusVars = []
surplusVars = []
for i in Pattern.lenOpts:
surplusVars += [LpVariable("Surplus "+ i,0,None,LpContinuous, -surplusPrice[i] * obj - constraints[i])]
return prob,obj,constraints
def addPatterns(obj,constraints,newPatterns):
# A list called Patterns is created to contain all the Pattern class
# objects created in this function call
Patterns = []
for i in newPatterns:
# The new patterns are checked to see that their length does not exceed
# the total roll length
lsum = 0
@@ -71,66 +71,66 @@ def addPatterns(obj,constraints,newPatterns):
lsum += j * int(k)
if lsum > Pattern.totalRollLength:
raise "Length Options too large for Roll"
# The number of rolls of each length in each new pattern is printed
# The number of rolls of each length in each new pattern is printed
print "P"+str(Pattern.numPatterns),"=",i
# The patterns are instantiated as Pattern objects
Patterns += [Pattern("P" + str(Pattern.numPatterns),i)]
# The pattern variables are created
pattVars = []
for i in Patterns:
for i in Patterns:
pattVars += [LpVariable("Pattern "+i.name,0,None,LpContinuous, (i.cost - Pattern.trimValue*i.trim()) * obj\
+ lpSum([constraints[l]*i.lengthsdict[l] for l in Pattern.lenOpts]))]
def masterSolve(prob,relax = True):
# Unrelaxes the Integer Constraint
if not relax:
for v in prob.variables():
v.cat = LpInteger
# The problem is solved and rounded
prob.solve()
prob.solve(PULP_CBC_CMD())
prob.roundSolution()
if relax:
# A dictionary of dual variable values is returned
duals = {}
for i,name in zip(Pattern.lenOpts,["Min5","Min7","Min9"]):
duals[i] = prob.constraints[name].pi
duals[i] = prob.constraints[name].pi
return duals
else:
# A dictionary of variable values and the objective value are returned
varsdict = {}
for v in prob.variables():
varsdict[v.name] = v.varValue
return value(prob.objective), varsdict
def subSolve(duals):
# The variable 'prob' is created
prob = LpProblem("SubProb",LpMinimize)
# The problem variables are created
vars = LpVariable.dicts("Roll Length", Pattern.lenOpts, 0, None, LpInteger)
trim = LpVariable("Trim", 0 ,None,LpInteger)
# The objective function is entered: the reduced cost of a new pattern
prob += (Pattern.cost - Pattern.trimValue*trim) - lpSum([vars[i]*duals[i] for i in Pattern.lenOpts]), "Objective"
# The conservation of length constraint is entered
prob += lpSum([vars[i]*int(i) for i in Pattern.lenOpts]) + trim == Pattern.totalRollLength, "lengthEquate"
# The problem is solved
# The problem is solved
prob.solve()
# The variable values are rounded
prob.roundSolution()
newPatterns = []
# Check if there are more patterns which would reduce the master LP objective function further
if value(prob.objective) < -10**-5:
@@ -139,5 +139,5 @@ def subSolve(duals):
varsdict[v.name] = v.varValue
# Adds the new pattern to the newPatterns list
newPatterns += [[int(varsdict["Roll_Length_5"]),int(varsdict["Roll_Length_7"]),int(varsdict["Roll_Length_9"])]]
return newPatterns

View File

@@ -1,6 +1,6 @@
#! /usr/bin/env python
# PuLP : Python LP Modeler
# Version 1.5.1
# Copyright (c) 2002-2005, Jean-Sebastien Roy (js@jeannot.org)
# Modifications Copyright (c) 2007- Stuart Anthony Mitchell (s.mitchell@auckland.ac.nz)
@@ -681,7 +681,7 @@ class LpAffineExpression(_DICT_TYPE):
term = " + %s" % self.constant
if self._count_characters(line) + len(term) > LpCplexLPLineSize:
result += ["".join(line)]
line += [term]
line = [term]
else:
line += [term]
result += ["".join(line)]

View File

@@ -1323,8 +1323,7 @@ class COIN_CMD(LpSolver_CMD):
cmds += "branch "
else:
cmds += "initialSolve "
if lp.isMIP:
cmds += "printingOptions rows "
cmds += "printingOptions rows "
cmds += "solution "+tmpSol+" "
if self.msg:
pipe = None
@@ -1459,7 +1458,7 @@ class PULP_CBC_CMD(COIN_CMD):
return False
def actualSolve(self, lp, callback = None):
"""Solve a well formulated lp problem"""
raise PulpSolverError, "PULP_CBC_CMD: Not Available (check permissions on %s)" % arch_pulp_cbc_path
raise PulpSolverError, "PULP_CBC_CMD: Not Available (check permissions on %s)" % self.arch_pulp_cbc_path
else:
def __init__(self, path=None, *args, **kwargs):
"""