예제 #1
0
    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
예제 #2
0
 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
예제 #3
0
 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)
예제 #4
0
 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
예제 #5
0
 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
예제 #6
0
 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
예제 #7
0
 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()
예제 #8
0
 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
예제 #9
0
 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
예제 #10
0
 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)
예제 #11
0
    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
예제 #12
0
 def is_sat(self):
     status = lpsolve('get_status', self.__solver_obj)
     if status in [0, 1, 3]:
         return True
     elif status == 2:
         return False
예제 #13
0
 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
예제 #14
0
 def set_ilp(self):
     for i in range(len(self.__var_mapping)):
         lpsolve('set_int', self.__solver_obj, i + 1, 1)