/usr/share/pyshared/openopt/kernel/LP.py is in python-openopt 0.38+svn1589-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 | from baseProblem import MatrixProblem
from numpy import asarray, ones, inf, dot, nan, zeros, isnan, any, vstack, array, asfarray, atleast_1d
import NLP
class LP(MatrixProblem):
_optionalData = ['A', 'Aeq', 'b', 'beq', 'lb', 'ub']
expectedArgs = ['f', 'x0']
probType = 'LP'
allowedGoals = ['minimum', 'min', 'max', 'maximum']
showGoal = True
_lp_prepared = False
def __init__(self, *args, **kwargs):
self.goal = 'minimum'
MatrixProblem.__init__(self, *args, **kwargs)
if len(args) > 1 and not hasattr(args[0], 'is_oovar'):
self.err('No more than 1 argument is allowed for classic style LP constructor')
def _Prepare(self):
if self._lp_prepared: return
self._lp_prepared = True
MatrixProblem._Prepare(self)
if self.x0 is None: self.x0 = zeros(self.n)
if hasattr(self.f, 'is_oovar'): # hence is oofun or oovar
# freeVars and fixedVars are already rendered to both not-None here (if it's the case)
# but current .D() implementation doesn't allow to use both arguments
# BTW translator ignores fixed vars in derivatives, so passing fixedVars here can be omitted
# but is performed for more safety wrt future changes
_f = self._point2vector(self.f.D(self._x0, fixedVars = self.fixedVars))
self.f, self._f = _f, self.f
self._init_f_vector = _f # we don't take p.goal into account here
_c = self._f(self._x0) - dot(self.f, self.x0)
self._c = _c
else:
self._init_f_vector = self.f # we don't take p.goal into account here
self._c = 0
self.f = atleast_1d(self.f)
if not hasattr(self, 'n'): self.n = len(self.f)
#print 'lb:', self.lb, 'ub:', self.ub
if not hasattr(self, 'lb'): self.lb = -inf * ones(self.n)
if not hasattr(self, 'ub'): self.ub = inf * ones(self.n)
# if any(isnan(self.lb)):
# if self.lb.size != 1: self.err('NaN in lower bound for a variable from the problem')
# self.lb = -inf * ones(self.n)
# if any(isnan(self.ub)):
# if self.ub.size != 1: self.err('NaN in upper bound for a variable from the problem')
# self.ub = inf * ones(self.n)
if self.goal in ['max', 'maximum']:
self.f = -asfarray(self.f)
# TODO: handle this and SDP finalize in single func finalize_for_max
def __finalize__(self):
MatrixProblem.__finalize__(self)
if self.goal in ['max', 'maximum']:
self.f = -self.f
for fn in ['fk', ]:#not ff - it's handled in other place in RunProbSolver.py
if hasattr(self, fn):
setattr(self, fn, -getattr(self, fn))
if hasattr(self, '_f'):
self.f = self._f
def objFunc(self, x):
return dot(self.f, x) + self._c
def lp2nlp(self, solver, **solver_params):
if self.isConverterInvolved and self.goal in ['max', 'maximum']:
self.err('maximization problems are not implemented lp2nlp converter')
ff = lambda x: dot(x, self.f)+self._c
dff = lambda x: self.f
if hasattr(self,'x0'): p = NLP.NLP(ff, self.x0, df=dff)
else: p = NLP.NLP(ff, zeros(self.n), df=dff)
self.inspire(p)
self.iprint = -1
# for LP plot is via NLP
p.show = self.show
p.plot, self.plot = self.plot, 0
if self.isFDmodel:
p._x0 = self._x0 # may be used in interalg
r = p.solve(solver, **solver_params)
self.xf, self.ff, self.rf = r.xf, r.ff, r.rf
return r
def exportToMPS(self, filename, format='fixed', startIndex=0):
try: from lp_solve import lpsolve
except ImportError: self.err('To export LP/MILP in files you should have lpsolve and its Python binding properly installed')
maxNameLength = 8 if format != 'free' else 255
handler = self.get_lpsolve_handler(maxNameLength, startIndex)
# TODO: uncomment it
ext = 'mps' if not filename.endswith('MPS') and not filename.endswith('mps') else ''
if ext != '': filename += '.' + ext
if format=='fixed':
r = bool(lpsolve('write_mps', handler, filename) )
elif format=='free':
r = bool(lpsolve('write_freemps', handler, filename) )
else:
self.err('incorrect MPS format, should be "fixed" or "free"')
if r != True:
self.warn('Failed to write MPS file, maybe read-only filesystem, incorrect path or write access is absent')
lpsolve('delete_lp', handler)
return r
def get_lpsolve_handler(self, maxNameLength=255, startIndex=0):
try: from lp_maker import lp_maker, lpsolve
except ImportError: self.err('To export LP/MILP in files you should have lpsolve and its Python binding properly installed')
self._Prepare()
from ooMisc import LinConst2WholeRepr
LinConst2WholeRepr(self)
# set goal to min/max
minim = 0 if self.goal in ['max', 'maximum'] else 1
# objective
f = self._init_f_vector
lp_handle = lp_maker(List(asarray(f).flatten()), List(self.Awhole), List(asarray(self.bwhole).flatten()), List(asarray(self.dwhole).flatten()), \
List(self.lb), List(self.ub), (1+asarray(self._intVars_vector)).tolist(), 0,minim)
#lp_handle = lpsolve('make_lp', len(self.beq)+len(self.b), self.n)
L = lambda action, *args: lpsolve(action, lp_handle, *args)
# set name
L('set_lp_name', self.name)
# set boolean values if present
#if len(self.boolVars)>0:
#assert self.boolVars[0] in [True, False]
#L('set_binary', self.boolVars)
# set variables names
if self.isFDmodel:
assert not isinstance(self.freeVars, set), 'error in openopt kernel, inform developers'
#assert len(self.freeVars) == self.n, 'not implemented yet for oovars of size > 1'
#names = [oov.name for oov in self.freeVars]
x0 = self._x0
names = []
#assert not isinstance(self.freeVars, set), 'error in openopt kernel, inform developers'
for oov in self.freeVars:
if oov.name.startswith('unnamed'):
L('delete_lp')
self.err('For exporting FuncDesigner models into MPS files you cannot have variables with names starting with "unnamed"')
if ' ' in oov.name:
L('delete_lp')
self.err('For exporting FuncDesigner models into MPS files you cannot have variables with spaces in names')
Size = asarray(x0[oov]).size
if Size == 1:
Name = oov.name
names.append(Name)
else:
tmp = [(oov.name + ('_%d' % (startIndex+j))) for j in range(Size)]
names += tmp
Name = tmp[-1]
if maxNameLength < len(Name):
L('delete_lp')
self.err('incorrect name "%s" - for exporting FuncDesigner models into MPS files you cannot have variables with names of length > maxNameLength=%d'% maxNameLength)
# TODO: check are names unique
L('set_col_name', names)
return lp_handle
def List(x):
if isinstance(x, list): return x
elif x == None or x.size == 0: return None
else: return x.tolist()
|