fix for asCplexAffineExpression and duals from cbc
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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)]
|
||||
|
||||
@@ -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):
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user