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 reset(self): self.__resetcalls = self.__resetcalls + 1 start = time.process_time() n = len(self.__clist) if n > 0: while n != 0: lpsolve('del_constraint', self.__solver_obj, 1) n -= 1 self.__clist = [] # [({varname : weight}, rel, b)] self.__obj = {} # {varname : weight} self.__resettime = self.__resettime + time.process_time() - start
def set_doms(self): ''' expects doms = {varname : [(lb,ub)]} ''' for varname in self.__doms: if varname in self.__var_mapping: for dom in self.__doms[varname]: lb = dom[0] ub = dom[1] if lb != 'none': lpsolve('set_lowbo', self.__solver_obj, self.__var_mapping[varname], lb) if ub != 'none': lpsolve('set_upbo', self.__solver_obj, self.__var_mapping[varname], ub)
def add_constr(self, clist): ''' expects clist = [({varname : weight}, rel, b)] ''' self.__addcalls = self.__addcalls + 1 start = time.process_time() self.__clist.extend(clist) nvar = len(self.__var_mapping) for constr in clist: tmp = [0] * nvar for varname in constr[0]: tmp[self.__var_mapping[varname] - 1] = constr[0][varname] lpsolve('add_constraint', self.__solver_obj, tmp, constr[1], constr[2]) self.__addtime = self.__addtime + time.process_time() - start
def is_valid(self): if self.__clist == []: return False status = lpsolve('get_status', self.__solver_obj) if status in [0, 1, 2, 3, 4]: return True return False
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 __init__(self, mapping, doms, ilp): self.__var_mapping = {} # {varname : position} self.__doms = doms # {varname : [(lb,ub)]} self.__clist = [] # [({varname : weight}, rel, b)] self.__obj = {} # {varname : weight} self.__stime = 0.0 self.__scalls = 0 self.__addtime = 0.0 self.__addcalls = 0 self.__resettime = 0.0 self.__resetcalls = 0 self.__mode = '' self.set_mapping(mapping) nvar = len(self.__var_mapping) self.__solver_obj = lpsolve('make_lp', 0, nvar) lpsolve('set_verbose', self.__solver_obj, lp_solve.IMPORTANT) self.set_doms() if ilp: self.set_ilp()
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_solution(self, accuracy): if self.is_sat(): sdict = {} slist = [] res = lpsolve('get_variables', self.__solver_obj)[0] if isinstance(res, float): slist.append(res) else: slist.extend(res) obj = lpsolve('get_objective', self.__solver_obj) if accuracy > 0 and accuracy < 15: for var in self.__var_mapping: sdict[var] = round(slist[self.__var_mapping[var] - 1], accuracy) else: for var in self.__var_mapping: sdict[var] = round( round(slist[self.__var_mapping[var] - 1], 1), 0) slist = (obj, sdict) elif self.is_sat() is None: slist = 'Error' else: slist = 'Unsat' return slist
def set_obj(self, wopt, mode): ''' expects wopt = {varname : weights}; mode = max/min ''' self.__obj = dict(wopt) self.__mode = mode if mode == 'max': lpsolve('set_maxim', self.__solver_obj) else: if mode != 'min': self.__mode = 'default min' lpsolve('set_minim', self.__solver_obj) tmp = [0] * len(self.__var_mapping) for varname in wopt: tmp[self.__var_mapping[varname] - 1] = wopt[varname] lpsolve('set_obj_fn', self.__solver_obj, tmp)
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 is_sat(self): status = lpsolve('get_status', self.__solver_obj) if status in [0, 1, 3]: return True elif status == 2: return False
def solve_lp(self): self.__scalls = self.__scalls + 1 start = time.process_time() lpsolve('solve', self.__solver_obj) self.__stime = self.__stime + time.process_time() - start
def set_ilp(self): for i in range(len(self.__var_mapping)): lpsolve('set_int', self.__solver_obj, i + 1, 1)