Source code for CyLP.py.pivots.DualDantzigPivot

'''
As a part of ``CyLP.python.pivots`` it implements Dantzig's
 Simplex dual pivot rule. Although it already exists in CLP,
for testing purposes we implement one in Python.
'''

import sys
import numpy as np
from operator import itemgetter
from random import shuffle
from math import floor
from DualPivotPythonBase import DualPivotPythonBase
#from CyLP.py.pivots import DantzigPivot


[docs]class DualDantzigPivot(DualPivotPythonBase): ''' Dantzig's dual pivot rule implementation. .. _custom-dual-pivot-usage: **Usage** >>> from CyLP.cy import CyClpSimplex >>> from CyLP.py.pivots.DualDantzigPivot import DualDantzigPivot >>> from CyLP.py.pivots.DualDantzigPivot import getMpsExample >>> # Get the path to a sample mps file >>> f = getMpsExample() >>> s = CyClpSimplex() >>> s.readMps(f) # Returns 0 if OK 0 >>> pivot = DualDantzigPivot(s) >>> s.setDualPivotMethod(pivot) >>> s.dual() 'optimal' >>> round(s.objectiveValue, 5) 2520.57174 ''' def __init__(self, clpModel): self.dim = clpModel.nRows + clpModel.nCols self.clpModel = clpModel def pivotRow(self): model = self.clpModel nConstraints = model.nConstraints basicVarInds = model.basicVariables u = model.upper[basicVarInds] l = model.lower[basicVarInds] s = model.solution[basicVarInds] infeasibilities = np.maximum(s - u, l - s) m = max(infeasibilities) if m > model.primalTolerance: return np.argmax(infeasibilities) return -1 def updateWeights(self, inp, spare, spare2, updatedColumn): model = self.clpModel pr = model.pivotRow() model.updateColumnFT(spare, updatedColumn) indices = updatedColumn.indices elements = updatedColumn.elements if updatedColumn.isInPackedMode: if pr in indices: ind = np.where(indices==pr)[0][0] return elements[ind] else: return elements[pr] return 0 def updatePrimalSolution(self, primalUpdate, primalRatio, objectiveChange): model = self.clpModel nConstraints = model.nConstraints basicVarInds = model.basicVariables rowNumbers = primalUpdate.indices elements = primalUpdate.elements nElements = primalUpdate.nElements changeObj = 0 sol = model.solution[basicVarInds[rowNumbers]] cost = model.cost[basicVarInds[rowNumbers]] if primalUpdate.isInPackedMode: change = primalRatio * elements[:nElements] model.solution[basicVarInds[rowNumbers]] -= change else: change = primalRatio * elements[rowNumbers] model.solution[basicVarInds[rowNumbers]] -= change changeObj = -np.dot(change, cost) primalUpdate.clear() objectiveChange[0] += changeObj return changeObj
def getMpsExample(): import os import inspect import sys cylpDir = os.environ['CYLP_SOURCE_DIR'] return os.path.join(cylpDir, 'CyLP', 'input', 'p0033.mps') if __name__ == "__main__": print sys.argv if len(sys.argv) == 1: import doctest doctest.testmod() else: from CyLP.cy import CyClpSimplex from CyLP.py.pivots import DualDantzigPivot s = CyClpSimplex() s.readMps(sys.argv[1]) # Returns 0 if OK pivot = DualDantzigPivot(s) s.setDualPivotMethod(pivot) s.dual()