Exemple #1
0
    def solve(self, *args, **kw):
        if len(args) > 1:
            self.err('''
            incorrect number of arguments for solve(), 
            must be at least 1 (solver), other must be keyword arguments''')
        solver = args[0] if len(args) != 0 else kw.get('solver', self.solver)

        graph = self.graph  # must be networkx instance
        nodes = graph.nodes()
        edges = graph.edges()

        n = len(nodes)

        node2index = dict([(node, i) for i, node in enumerate(nodes)])
        index2node = dict([(i, node) for i, node in enumerate(nodes)])

        import FuncDesigner as fd, openopt
        x = fd.oovars(n, domain=bool)
        objective = fd.sum(x)
        startPoint = {x: [0] * n}

        fixedVars = {}

        includedNodes = getattr(kw, 'includedNodes', None)
        if includedNodes is None:
            includedNodes = getattr(self, 'includedNodes', ())
        for node in includedNodes:
            fixedVars[x[node2index[node]]] = 1

        excludedNodes = getattr(kw, 'excludedNodes', None)
        if excludedNodes is None:
            excludedNodes = getattr(self, 'excludedNodes', ())
        for node in excludedNodes:
            fixedVars[x[node2index[node]]] = 0

        if openopt.oosolver(solver).__name__ == 'interalg':
            constraints = [
                fd.NAND(x[node2index[i]], x[node2index[j]]) for i, j in edges
            ]
            P = openopt.GLP
        else:
            constraints = [
                x[node2index[i]] + x[node2index[j]] <= 1 for i, j in edges
            ]
            P = openopt.MILP

        p = P(objective,
              startPoint,
              constraints=constraints,
              fixedVars=fixedVars,
              goal='max')

        for key, val in kw.items():
            setattr(p, key, val)
        r = p.solve(solver, **kw)
        r.solution = [index2node[i] for i in range(n) if r.xf[x[i]] == 1]
        r.ff = len(r.solution)
        return r
Exemple #2
0
 def startOptimization(self, root, varsRoot, AddVar, currValues, \
                       ValsColumnName, ObjEntry, ExperimentNumber, Next, NN, goal, objtol, C):
     AddVar.destroy()
     ValsColumnName.set('Experiment parameters')
     n = len(self.NameEntriesList)
     Names, Lb, Ub, Tol, x0 = [], [], [], [], []
     for i in range(n):
         N, L, U, T, valEntry = \
         self.NameEntriesList[i], self.LB_EntriesList[i], self.UB_EntriesList[i], self.TolEntriesList[i], self.ValueEntriesList[i]
         N.config(state=DISABLED)
         L.config(state=DISABLED)
         U.config(state=DISABLED)
         T.config(state=DISABLED)
         #valEntry.config(state=DISABLED)
         name, lb, ub, tol, val = N.get(), L.get(), U.get(), T.get(), valEntry.get()
         Names.append(name)
         x0.append(float(val))
         Lb.append(float(lb) if lb != '' else -inf)
         Ub.append(float(ub) if ub != '' else inf)
         
         # TODO: fix zero
         Tol.append(float(tol) if tol != '' else 0) 
         
     x0, Tol, Lb, Ub = asfarray(x0), asfarray(Tol), asfarray(Lb), asfarray(Ub)
     x0 *= xtolScaleFactor / Tol
     #self.x0 = copy(x0)
     from openopt import NLP, oosolver
     p = NLP(objective, x0, lb = Lb * xtolScaleFactor / Tol, ub=Ub * xtolScaleFactor / Tol)
     self.prob = p
     #calculated_points = [(copy(x0), copy(float(ObjEntry.get())))
     p.args = (Tol, self, ObjEntry, p, root, ExperimentNumber, Next, NN, objtol, C)
     #p.graphics.rate = -inf
     #p.f_iter = 2
     solver = oosolver('bobyqa', useStopByException = False)
     p.solve(solver, iprint = 1, goal = goal)#, plot=1, xlabel='nf')
     self.solved = True
     if p.stopcase >= 0:
         self.ValsColumnName.set('Best parameters')
         NN.set('Best obtained objective value:')
     #Next.config(state=DISABLED)
     Next.destroy()
     #reverse = True if goal == 'min' else False
     
     calculated_items = self.calculated_points.items() if isinstance(self.calculated_points, dict) else self.calculated_points
     vals = [calculated_items[i][1] for i in range(len(calculated_items))]
     ind = argsort(vals)
     j = ind[0] if goal == 'min' else ind[-1]
     key, val = calculated_items[j]
     text_coords = key.split(' ')
     for i in range(len(self.ValueEntriesList)):
         self.ValueEntriesList[i].delete(0, END)
         self.ValueEntriesList[i].insert(0, text_coords[i])
     ObjEntry.delete(0, END)
     obj_tol = self.ObjTolEntry.get()
     val = float(val) * 1e4 * objtol
     ObjEntry.insert(0, str(val))
     ObjEntry.config(state=DISABLED)
Exemple #3
0
    def solve(self, *args, **kw):
        if len(args) > 1:
            self.err('''
            incorrect number of arguments for solve(), 
            must be at least 1 (solver), other must be keyword arguments''')
        solver = args[0] if len(args) != 0 else kw.get('solver', self.solver)
        
        graph = self.graph # must be networkx instance
        nodes = graph.nodes()
        edges = graph.edges()
        
        n = len(nodes)
        
        node2index = dict([(node, i) for i, node in enumerate(nodes)])
        index2node = dict([(i, node) for i, node in enumerate(nodes)])
        
        import FuncDesigner as fd, openopt
        x = fd.oovars(n, domain=bool)
        objective = fd.sum(x)
        startPoint = {x:[0]*n}
        
        fixedVars = {}
       
        includedNodes = getattr(kw, 'includedNodes', None)
        if includedNodes is None:
            includedNodes = getattr(self, 'includedNodes', ())
        for node in includedNodes:
            fixedVars[x[node2index[node]]] = 1

        excludedNodes = getattr(kw, 'excludedNodes', None)
        if excludedNodes is None:
            excludedNodes = getattr(self, 'excludedNodes', ())
        for node in excludedNodes:
            fixedVars[x[node2index[node]]] = 0

        if openopt.oosolver(solver).__name__ == 'interalg':
            constraints =  [fd.NAND(x[node2index[i]], x[node2index[j]]) for i, j in edges]
            P = openopt.GLP
        else:
            constraints =  [x[node2index[i]]+x[node2index[j]] <=1 for i, j in edges]
            P = openopt.MILP
            
        p = P(objective, startPoint, constraints = constraints, fixedVars = fixedVars, goal = 'max')
        
        for key, val in kw.items():
            setattr(p, key, val)
        r = p.solve(solver, **kw)
        r.solution = [index2node[i] for i in range(n) if r.xf[x[i]] == 1]
        r.ff = len(r.solution)
        return r
Exemple #4
0
    def _solve(self, *args, **kwargs):

        #!!!!! TODO: determing LP, MILP, MINLP if possible
        try:
            import openopt
        except ImportError:
            raise FuncDesignerException(
                'to perform the operation you should have openopt installed')

        constraints = self._getAllConstraints()

        # TODO: mention it in doc
        if 'constraints' in kwargs:
            tmp = set(kwargs['constraints'])
            tmp.update(set(constraints))
            kwargs['constraints'] = tmp
        else:
            kwargs['constraints'] = constraints

        freeVars, fixedVars = kwargs.get('freeVars',
                                         None), kwargs.get('fixedVars', None)
        isSystemOfEquations = kwargs['goal'] == 'solution'

        isLinear = all([(c.oofun.getOrder(freeVars, fixedVars) < 2)
                        for c in constraints])

        if isSystemOfEquations:
            if isLinear:  # Linear equations system
                p = sle(list(kwargs['constraints']), *args, **kwargs)
            else:  # Nonlinear equations system
                f = kwargs['constraints']
                ############################################
                #cons = self._getAllConstraints()

                # OLD
                #                if not all([array_equal(c.lb, c.ub) for c in f]):
                #                    raise FuncDesignerException('Solving constrained nonlinear systems is not implemented for oosystem yet, use SNLE constructor instead')
                #                kwargs['constraints'] = ()

                # NEW
                C, F = [], []
                for c in f:
                    F.append(c) if array_equal(c.lb, c.ub) else C.append(c)
                kwargs['constraints'] = C
                f = F
                ############################################

                p = openopt.SNLE(f, *args, **kwargs)
                if 'nlpSolver' in kwargs:
                    p.solver = kwargs['nlpSolver']

        else:  # an optimization problem
            assert len(
                args) > 0, 'you should have objective function as 1st argument'
            objective = args[0]
            if isinstance(objective, BaseFDConstraint):
                raise FuncDesignerException(
                    "1st argument can't be of type 'FuncDesigner constraint', it should be 'FuncDesigner oofun'"
                )
            elif not isinstance(objective, oofun):
                raise FuncDesignerException(
                    '1st argument should be objective function of type "FuncDesigner oofun"'
                )

            isLinear &= objective.getOrder(freeVars, fixedVars) < 2

            if isLinear:
                p = openopt.LP(*args, **kwargs)
                if 'solver' not in kwargs:
                    for solver in self.lpSolvers:
                        if (':' not in solver
                                and not openopt.oosolver(solver).isInstalled
                            ) or (
                                solver == 'glpk' and
                                not openopt.oosolver('cvxopt_lp').isInstalled):
                            continue
                        if solver == 'glpk':
                            p2 = openopt.LP([1, -1], lb=[1, 1], ub=[10, 10])
                            try:
                                r = p2.solve('glpk', iprint=-5)
                            except:
                                continue
                            if r.istop < 0:
                                continue
                            else:
                                break
                    if ':' in solver:
                        pWarn(
                            'You have linear problem but no linear solver (lpSolve, glpk, cvxopt_lp) is installed; converter to NLP will be used.'
                        )
                    p.solver = solver
                else:
                    solverName = kwargs['solver']
                    if type(solverName) != str:
                        solverName = solverName.__name__
                    if solverName not in self.lpSolvers:
                        solverName = 'nlp:' + solverName
                        p.solver = solverName
                        p.warn(
                            'you are solving linear problem with non-linear solver'
                        )
            else:
                p = openopt.NLP(*args, **kwargs)
                if 'solver' not in kwargs:
                    p.solver = 'ralg'

        # TODO: solver autoselect
        #if p.iprint >= 0: p.disp('The optimization problem is  ' + p.probType)
        p._isFDmodel = lambda *args, **kwargs: True
        return p.solve() if kwargs.get('manage', False) in (False,
                                                            0) else p.manage()
Exemple #5
0
    def __solver__(self, p):

        alp, h0, nh, q1, q2 = self.alp, self.h0, self.nh, self.q1, self.q2
        
        if isPyPy:
            if p.nc != 0 or p.nh != 0:
                p.warn("in PyPy ralg may work incorrectly with nonlinear constraints yet")
            if p.nbeq != 0 or any(p.lb==p.ub):
                p.err('in PyPy ralg cannot handle linear equality constraints yet')
        
        if type(q1) == str:
            if p.probType== 'NLP' and p.isUC: q1 = 0.9
            else: q1 = 1.0
        T = self.T
        # alternatively instead of alp=self.alp etc you can use directly self.alp etc

        n = p.n
        x0 = p.x0
        
        if p.nbeq == 0 or any(abs(p._get_AeqX_eq_Beq_residuals(x0))>p.contol): # TODO: add "or Aeqconstraints(x0) out of contol"
            x0[x0<p.lb] = p.lb[x0<p.lb]
            x0[x0>p.ub] = p.ub[x0>p.ub]
        
        ind_box_eq = where(p.lb==p.ub)[0]
        nEQ = ind_box_eq.size
        if nEQ != 0:
            initLenBeq = p.nbeq
            Aeq, beq, nbeq = copy(p.Aeq), copy(p.beq), p.nbeq
            p.Aeq = zeros([Len(p.beq) + nEQ, p.n])
            p.beq = zeros(Len(p.beq) + nEQ)
            p.beq[:Len(beq)] = beq
            p.Aeq[:Len(beq)] = Aeq
            for i in range(len(ind_box_eq)):
                p.Aeq[initLenBeq+i, ind_box_eq[i]] = 1
                p.beq[initLenBeq+i] = p.lb[ind_box_eq[i]] # = p.ub[indEQ[i]], because they are the same
            p.nbeq += nEQ
            
        if not self.newLinEq or p.nbeq == 0:
            needProjection = False
            B0 = eye(n,  dtype=T)
            restoreProb = lambda *args: 0
            Aeq_r, beq_r, nbeq_r = None, None, 0
        else:
            needProjection = True
            B0 = self.getPrimevalDilationMatrixWRTlinEqConstraints(p)
            #Aeq, beq, nbeq = p.Aeq, p.beq, p.nbeq
            
            if any(abs(p._get_AeqX_eq_Beq_residuals(x0))>p.contol/16.0):
                #p.debugmsg('old point Aeq residual:'+str(norm(dot(Aeq, x0)-beq)))
                try:
                    x0 = self.linEqProjection(x0, p.Aeq, p.beq)
                except LinAlgError:
                    s = 'Failed to obtain projection of start point to linear equality constraints subspace, probably the system is infeasible'
                    p.istop, p.msg = -25,  s
                    return
                    
                #p.debugmsg('new point Aeq residual:'+str(norm(dot(Aeq, x0)-beq)))
            if nEQ == 0:
                Aeq_r, beq_r, nbeq_r = p.Aeq, p.beq, p.nbeq
            else:
                Aeq_r, beq_r, nbeq_r = Aeq, beq, nbeq
            
            p.Aeq, p.beq, p.nbeq = None, None, 0
            
            # TODO: return prob with unmodified Aeq, beq
            
            def restoreProb():
                p.Aeq, p.beq, p.nbeq = Aeq_r, beq_r, nbeq_r
                #if nEQ != 0: restore lb, ub
                    
            
        b = B0.copy() if self.B is None else self.B
#        B_f = diag(ones(n))
#        B_constr = diag(ones(n))
        hs = asarray(h0, T)
        
        if self.innerState is not None:
            hs = self.innerState['hs']
            b = self.innerState['B']
        
        ls_arr = []
        w = asarray(1.0/alp-1.0, T)

        """                            Shor r-alg engine                           """
        bestPoint = p.point(array(copy(x0).tolist(), T)) # tolist() for PyPy compatibility
        prevIter_best_ls_point = bestPoint
        prevIter_PointForDilation = bestPoint

        g = bestPoint._getDirection(self.approach)
        prevDirectionForDilation = g
        moveDirection = g
        if not any(g) and all(isfinite(g)):
            # TODO: create ENUMs
            p.iterfcn(bestPoint)
            restoreProb()
            p.istop = 14 if bestPoint.isFeas(False) else -14
            p.msg = 'move direction has all-zero coords'
            return

        HS = []
        LS = []
        
        SwitchEncountered = False
        selfNeedRej = False
        doScale = False
        
        #directionVectorsList = []
#        #pass-by-ref! not copy!
#        if p.isFeas(p.x0): b = B_f
#        else: b = B_constr

#        if p.debug and hasattr(p, 'x_opt'):
#            import scipy
#            exactDirection = x0-p.x_opt
#            asdf_0 = exactDirection * (0.2+scipy.rand(n))
#            #asdf = asdf_0.copy()


        fTol = p.fTol if p.fTol is not None else 15*p.ftol
        
        # CHANGES
        if self.penalties:
            oldVal = p.f(p.x0)
            newVal = inf
            x = p.x0
            
            #H,  DH = p.h, p.dh
            if p.nh != 0:
                #S = 1.0
            
                _Aeq = p.dh(x)
                _beq = -p.h(x)
                df = p.df(x)
                if n>=150 and not scipyInstalled:
                    p.pWarn(scipyAbsentMsg)
                if n>100 and scipyInstalled:
                    from scipy.sparse import eye as Eye # to prevent numpy.eye overwrite
                    HH = Eye(n, n)
                else:
                    HH = eye(n)
                qp = openopt.QP(H=HH, f=df, Aeq=_Aeq, beq=_beq)
    #                print ('len(_beq): %d' % len(_beq))
    #                assert len(_beq) != 0
                QPsolver = openopt.oosolver('cvxopt_qp', iprint=-1)
                if not QPsolver.isInstalled:
                    #p.pWarn('to use ')
                    S = None
                else:
                    r = qp.solve(QPsolver)
                    #S = 2.0*abs(r.duals).sum() if r.istop > 0 else 0
                    S = 10.0*sum(abs(r.duals)) if r.istop > 0 else None
                
                while any(p.h(x)) > p.contol:
                    if S is not None:
                        p2 = getattr(openopt, p.probType)(p.f, x)
                        p.inspire(p2)
                        p2.x0 = x
                        p2.h = p2.dh = None
                        p2.userProvided.h = p2.userProvided.dh = False
                        p2.nh = 0
                        p2.f = lambda *args, **kwargs: p.f(*args, **kwargs) + sum(abs(S * p.h(*args, **kwargs)))
                        p2.df = lambda *args, **kwargs: p.df(*args, **kwargs) + dot(S * sign(p.h(*args, **kwargs)), p.dh(*args, **kwargs))
                        #p2.iterfcn = p.iterfcn
    #                    def df2(*args, **kwargs):
    #                        r1 = p.df(*args, **kwargs)
    #                        r2 = S * dot(p.dh(*args, **kwargs).reshape(-1, 1), sign(p.h(*args, **kwargs))).flatten()
    #                        #raise 0
    #                        return r1+r2
    #                    #p2.df = lambda *args, **kwargs: p.df(*args, **kwargs) + S * dot(p.dh(x).reshape(-1, 1), sign(p.h(*args, **kwargs))).flatten()
    #                    p2.df = df2
    #                    #raise 0
                        r2 = p2.solve(p.solver, iprint=10)
                        if r2.stopcase >= 0:
                            x = r2.xf
                            p.solver.innerState = r2.extras['innerState']
                            oldVal, newVal = newVal, r2.ff
                        else:
                            if r2.istop == IS_LINE_SEARCH_FAILED:
                                # TODO: custom S as raising penalties
                                pass
                        
                        if p.isFeas(p2.xk):
                            p.xf = p.xk = p2.xk
                            p.istop, p.msg = p2.istop, p2.msg
                            return
                        else:
                            S *= 50
                            #print('max residual:%0.2e'% r2.rf)
                        
                    else: # failed to solve QP
                        break
                    
        #print 'b:', b, '\nhs:', hs
        # CHANGES END

        """                           Ralg main cycle                                    """

        for itn in range(p.maxIter+10):
            doDilation = True
            lastPointOfSameType = None # to prevent possible bugs
            alp_addition = 0.0
            
            iterStartPoint = prevIter_best_ls_point
            x = iterStartPoint.x.copy()

            g_tmp = economyMult(b.T, moveDirection)
            if any(g_tmp): g_tmp /= p.norm(g_tmp)
            g1 = p.matmult(b, g_tmp)
            
#            norm_moveDirection = p.norm(g1)
#            if doScale:
#                g1 *= (norm_moveDirection_prev/norm_moveDirection) ** 0.5
#            norm_moveDirection_prev = norm_moveDirection

#            if p.debug and hasattr(p, 'x_opt'):
#                cos_phi_0 = p.matmult(moveDirection,  prevIter_best_ls_point.x - p.x_opt)/p.norm(moveDirection)/p.norm(prevIter_best_ls_point.x - p.x_opt)
#                cos_phi_1 = p.matmult(g1,  prevIter_best_ls_point.x - p.x_opt)/p.norm(g1)/p.norm(prevIter_best_ls_point.x - p.x_opt)
#                print('beforeDilation: %f  afterDilation: %f' % (cos_phi_0, cos_phi_1) )
#                asdf = asdf_0.copy()
#                g_tmp = economyMult(b.T, asdf)
#                
#                #g_tmp = p.matmult(b.T, asdf)
#                
#                if any(g_tmp): g_tmp /= p.norm(g_tmp)
#                asdf = p.matmult(b, g_tmp)
#                cos_phi = dot(asdf, exactDirection) / p.norm(asdf) / p.norm(exactDirection)
#                p.debugmsg('cos_phi:%f' % cos_phi)
#                assert cos_phi >0


            """                           Forward line search                          """

            hs_cumsum = 0
            hs_start = hs
            for ls in range(p.maxLineSearch):
                hs_mult = 1.0
                if ls > 20:
                    hs_mult = 2.0
                elif ls > 10:
                    hs_mult = 1.5
                elif ls > 2:
                    hs_mult = 1.05
                hs *= hs_mult

                x -= hs * g1
                hs_cumsum += hs

                newPoint = p.point(x) if ls == 0 else iterStartPoint.linePoint(hs_cumsum/(hs_cumsum-hs), oldPoint) #  TODO: take ls into account?
                
                if not p.isUC:
                    if newPoint.isFeas(True) == iterStartPoint.isFeas(True):
                        lastPointOfSameType = newPoint
              
                if self.show_nnan: p.info('ls: %d nnan: %d' % (ls, newPoint.__nnan__()))

                
                if ls == 0:
                    oldPoint = prevIter_best_ls_point#prevIterPoint
                    oldoldPoint = oldPoint
                    
                #if not self.checkTurnByGradient:
                if newPoint.betterThan(oldPoint, altLinInEq=True):
                    if newPoint.betterThan(bestPoint, altLinInEq=False): bestPoint = newPoint
                    oldoldPoint = oldPoint
                    oldPoint, newPoint = newPoint,  None
                else:
                    if not itn % 4: 
                        for fn in ['_lin_ineq', '_lin_eq']:
                            if hasattr(newPoint, fn): delattr(newPoint, fn)
                    break
                    
            hs /= hs_mult
            
            if ls == p.maxLineSearch-1:
                p.istop,  p.msg = IS_LINE_SEARCH_FAILED,  'maxLineSearch (' + str(p.maxLineSearch) + ') has been exceeded, the problem seems to be unbounded'
                restoreProb()
                return

            #iterPoint  = newPoint
            PointForDilation = newPoint
            #best_ls_point = newPoint if ls == 0 else oldPoint
            #if p.debug and ls != 0: assert not oldPoint.betterThan(best_ls_point)

            """                          Backward line search                          """
            mdx = max((150, 1.5*p.n))*p.xtol
            if itn == 0:  mdx = max((hs / 128.0, 128*p.xtol )) # TODO: set it after B rej as well
            ls_backward = 0
            maxLS = 3 if ls == 0 else 1
#            if ls <=3 or ls > 20:
            if self.doBackwardSearch:
                if self.new_bs:
                    best_ls_point,  PointForDilation, ls_backward = \
                    getBestPointAfterTurn(oldoldPoint, newPoint, maxLS = maxLS, maxDeltaF = 150*p.ftol, \
                                          maxDeltaX = mdx, altLinInEq = True, new_bs = True)
                    if PointForDilation.isFeas(True) == iterStartPoint.isFeas(True):
                        lastPointOfSameType = PointForDilation
#                        elif best_ls_point.isFeas(altLinInEq=True) == iterStartPoint.isFeas(altLinInEq=True):
#                            lastPointOfSameType = best_ls_point
                else:
                    best_ls_point, ls_backward = \
                    getBestPointAfterTurn(oldoldPoint, newPoint, maxLS = maxLS, altLinInEq = True, new_bs = False)
                    PointForDilation = best_ls_point

                # TODO: extract last point from backward search, that one is better than iterPoint
                if best_ls_point.betterThan(bestPoint): bestPoint = best_ls_point
                #p.debugmsg('ls_backward:%d' % ls_backward)
                if ls == 0 and ls_backward == -maxLS:
                    #pass
                    alp_addition += 0.25
                    #hs *= 0.9
                
                if ls_backward <= -1 and itn != 0:  # TODO: mb use -1 or 0 instead?
                    pass
                    #alp_addition -= 0.25*ls_backward # ls_backward less than zero
                
                #hs *= 2 ** min((ls_backward+1, 0))
            else:
                pass
                #hs *= 0.95
            
            best_ls_point = PointForDilation # elseware lots of difficulties
            
            """                                 Updating hs                                 """
            step_x = p.norm(PointForDilation.x - prevIter_PointForDilation.x)
            step_f = abs(PointForDilation.f() - prevIter_PointForDilation.f())
            HS.append(hs_start)
            assert ls >= 0
            LS.append(ls)
            if itn > 3:
                mean_ls = (3*LS[-1] + 2*LS[-2]+LS[-3]) / 6.0
                j0 = 3.3
                if mean_ls > j0:
                    hs = (mean_ls - j0 + 1)**0.5 * hs_start
                else:
                    #hs = (ls/j0) ** 0.5 * hs_start
                    hs = hs_start
                    if ls == 0 and ls_backward == -maxLS:
                        shift_x = step_x / p.xtol
                        RD = log10(shift_x+1e-100)
                        if PointForDilation.isFeas(True) or prevIter_PointForDilation.isFeas(True):
                            RD = min((RD, asscalar(asarray(log10(step_f / p.ftol + 1e-100)))))
                        if RD > 1.0:
                            mp = (0.5, (ls/j0) ** 0.5, 1 - 0.2*RD)
                            hs *= max(mp)
                            #from numpy import argmax
                            #print argmax(mp), mp

            """                            Handling iterPoints                            """
               
            best_ls_point = PointForDilation
            
            #if not SwitchEncountered and p.nh != 0 and PointForDilation.isFeas(altLinInEq=False) != prevIter_PointForDilation.isFeas(altLinInEq=False):
                #SwitchEncountered = True
                #selfNeedRej = True
            
            involve_lastPointOfSameType = False
            if lastPointOfSameType is not None and PointForDilation.isFeas(True) != prevIter_PointForDilation.isFeas(True):
                # TODO: add middle point for the case ls = 0
                assert self.dilationType == 'plain difference'
                #directionForDilation = lastPointOfSameType._getDirection(self.approach) 
                PointForDilation = lastPointOfSameType
                involve_lastPointOfSameType = True
                
            
           
           
            #directionForDilation = newPoint.__getDirection__(self.approach) # used for dilation direction obtaining
            
#            if not self.new_bs or ls != 0:
#                moveDirection = iterPoint.__getDirection__(self.approach)
#            else:
#                moveDirection = best_ls_point.__getDirection__(self.approach)
                
                #directionForDilation = pointForDilation.__getDirection__(self.approach) 
                
                
#                cos_phi = -p.matmult(moveDirection, prevIterPoint.__getDirection__(self.approach))
#                assert cos_phi.size == 1
#                if cos_phi> 0:
#                    g2 = moveDirection#pointForDilation.__getDirection__(self.approach) 
#                else:
#                    g2 = pointForDilation.__getDirection__(self.approach) 
                
            if itn == 0:
                p.debugmsg('hs: ' + str(hs))
                p.debugmsg('ls: ' + str(ls))
            if self.showLS: p.info('ls: ' + str(ls))
            if self.show_hs: p.info('hs: ' + str(hs))
            if self.show_nnan: p.info('nnan: ' + str(best_ls_point.__nnan__()))
            if self.showRes:
                r, fname, ind = best_ls_point.mr(True)
                p.info(fname+str(ind))

            """                         Set dilation direction                            """

            #if sum(p.dotmult(g, g2))>0:
                #p.debugmsg('ralg warning: slope angle less than pi/2. Mb dilation for the iter will be omitted.')
                #doDilation = False



                    
            # CHANGES
#            if lastPointOfSameType is None:
#                if currIterPointIsFeasible and not prevIterPointIsFeasible:
#                    alp_addition += 0.1
#                elif prevIterPointIsFeasible and not currIterPointIsFeasible:
#                    alp_addition -= 0.0
                
            # CHANGES END
            
#            r_p, ind_p, fname_p = prevIter_best_ls_point.mr(1)
#            r_, ind_, fname_ = PointForDilation.mr(1)


            #else:
            

            #print itn,'>>>>>>>>>', currIterPointIsFeasible
            
            """                                    Excluding derivatives switched to/from NaN                                    """
            
            if self.skipPrevIterNaNsInDilation:
                c_prev, c_current = prevIter_PointForDilation.c(), PointForDilation.c()
                h_prev, h_current = prevIter_PointForDilation.h(), PointForDilation.h()
                
            """                                             Handling switch to NaN                                            """
            NaN_derivatives_excluded = False
            if self.skipPrevIterNaNsInDilation:
                assert self.approach == 'all active'
                
                if not prevIter_PointForDilation.isFeas(True):
                    """                          processing NaNs in nonlin inequality constraints                          """
                    ind_switch_ineq_to_nan = where(logical_and(isnan(c_current), c_prev>0))[0]              
                    if len(ind_switch_ineq_to_nan) != 0:
                        NaN_derivatives_excluded = True
                        tmp = prevIter_PointForDilation.dc(ind_switch_ineq_to_nan)
                        if hasattr(tmp, 'toarray'):
                            tmp = tmp.A
                        if len(ind_switch_ineq_to_nan)>1:
                            tmp *= (c_prev[ind_switch_ineq_to_nan] /sqrt((tmp**2).sum(1))).reshape(-1, 1)
                        else:
                            tmp *= c_prev[ind_switch_ineq_to_nan] / norm(tmp)
                        if tmp.ndim>1: tmp = tmp.sum(0)
                        if not isinstance(tmp, ndarray) or isinstance(tmp, matrix): tmp = tmp.A.flatten() # dense or sparse matrix
                        #print '1: excluded:', norm(tmp), norm(prevDirectionForDilation)
                        prevDirectionForDilation -= tmp
                        #print '1: result=', norm(prevDirectionForDilation)
                        
                    """                           processing NaNs in nonlin equality constraints                           """
                    ind_switch_eq_to_nan = where(logical_and(isnan(h_current), h_prev>0))[0]       
                    if len(ind_switch_eq_to_nan) != 0:
                        NaN_derivatives_excluded = True
                        tmp = prevIter_PointForDilation.dh(ind_switch_eq_to_nan)                        
                        if tmp.ndim>1: tmp = tmp.sum(0)
                        if not isinstance(tmp, ndarray) or isinstance(tmp, matrix): tmp = tmp.A.flatten() # dense or sparse matrix
                        prevDirectionForDilation -= tmp

                    ind_switch_eq_to_nan = where(logical_and(isnan(h_current), h_prev<0))[0]                
                    if len(ind_switch_eq_to_nan) != 0:
                        NaN_derivatives_excluded = True
                        tmp = prevIter_PointForDilation.dh(ind_switch_eq_to_nan)
                        if tmp.ndim>1: tmp = tmp.sum(0)
                        if not isinstance(tmp, ndarray) or isinstance(tmp, matrix): tmp = tmp.A.flatten() # dense or sparse matrix
                        prevDirectionForDilation += tmp
                
            directionForDilation = PointForDilation._getDirection(self.approach) 
            
            """                                            Handling switch from NaN                                           """
            if self.skipPrevIterNaNsInDilation:
                
                if not PointForDilation.isFeas(True):
                    
                    """                          processing NaNs in nonlin inequality constraints                          """
                    ind_switch_ineq_from_nan = where(logical_and(isnan(c_prev), c_current>0))[0]
                    if len(ind_switch_ineq_from_nan) != 0:
                        NaN_derivatives_excluded = True
                        tmp = PointForDilation.dc(ind_switch_ineq_from_nan)
                        if hasattr(tmp, 'toarray'):
                            tmp = tmp.A                        
                        if len(ind_switch_ineq_from_nan)>1:
                            tmp *= (c_current[ind_switch_ineq_from_nan] /sqrt((tmp**2).sum(1))).reshape(-1, 1)
                        else:
                            tmp *= c_current[ind_switch_ineq_from_nan] / norm(tmp)                        
                        if tmp.ndim>1: tmp = tmp.sum(0)
                        if not isinstance(tmp, ndarray) or isinstance(tmp, matrix): tmp = tmp.A.flatten() # dense or sparse matrix
                        #print '2: excluded:', norm(tmp), norm(directionForDilation)
                        directionForDilation -= tmp
                        #print '2: result=', norm(directionForDilation)
                        
                        
                    """                           processing NaNs in nonlin equality constraints                           """
                    ind_switch_eq_from_nan = where(logical_and(isnan(h_prev), h_current>0))[0]
                    if len(ind_switch_eq_from_nan) != 0:
                        NaN_derivatives_excluded = True
                        tmp = PointForDilation.dh(ind_switch_eq_from_nan)
                        if tmp.ndim>1: tmp = tmp.sum(0)
                        if not isinstance(tmp, ndarray) or isinstance(tmp, matrix): tmp = tmp.A.flatten() # dense or sparse matrix
                        directionForDilation -= tmp

                    ind_switch_eq_from_nan = where(logical_and(isnan(h_prev), h_current<0))[0]
                    if len(ind_switch_eq_from_nan) != 0:
                        NaN_derivatives_excluded = True
                        tmp = PointForDilation.dh(ind_switch_eq_from_nan)
                        if tmp.ndim>1: tmp = tmp.sum(0)
                        if not isinstance(tmp, ndarray) or isinstance(tmp, matrix): tmp = tmp.A.flatten() # dense or sparse matrix
                        directionForDilation += tmp

#            # CHANGES
#            gn = g2/norm(g2)
#            if len(directionVectorsList) == 0 or n < 3: pass
#            else:
#                if len(directionVectorsList) == 1 or abs(dot(directionVectorsList[-1], directionVectorsList[-2]))>0.999:
#                    projectionComponentLenght = abs(dot(directionVectorsList[-1], gn))
#                    restLength = sqrt(1 - min((1, projectionComponentLenght))**2)
#                else: 
#                    e1 = directionVectorsList[-1]
#                    e2 = directionVectorsList[-2] - dot(directionVectorsList[-1], directionVectorsList[-2]) * directionVectorsList[-1]
#                    e2 /= norm(e2)
#                   
#                    proj1, proj2 = dot(e1, gn), dot(e2, gn)
#                    rest = gn - proj1 * e1 - proj2 * e2
#                    restLength = norm(rest)
#                if restLength > 1+1e-5: p.pWarn('possible error in ralg solver: incorrect restLength, exceeds 1.0')
#                
#                # TODO: make it parameters of ralg
#                commonCoeff, alp_add_coeff = 0.5, 1.0
#                
#                if restLength < commonCoeff * (n - 2.0) / n:
#                    #pass
#                    alpAddition = 0.5+(arctan((n - 2.0) / (n * restLength)) - pi / 4.0) / (pi / 2.0) * alp_add_coeff
#                    #p.debugmsg('alpAddition:' + str(alpAddition))
#                    assert alpAddition > 0 # if someone incorrectly modifies commonCoeff it can be less than zero
#                    alp_addition += alpAddition
#                    #p.debugmsg('alp_addition:' + str(alp_addition))
#                    
#            directionVectorsList.append(gn)
#            if len(directionVectorsList) > 2: directionVectorsList = directionVectorsList[:-2]
#            # CHANGES END

                
            if self.dilationType == 'normalized' and (not fname_p in ('lb', 'ub', 'lin_eq', 'lin_ineq') \
                                                      or not fname_ in ('lb', 'ub', 'lin_eq', 'lin_ineq')) and (fname_p != fname_  or ind_p != ind_):
                G2,  G = directionForDilation/norm(directionForDilation), prevDirectionForDilation/norm(prevDirectionForDilation)
            else:
                G2,  G = directionForDilation, prevDirectionForDilation            
           
            if prevIter_PointForDilation.isFeas(True) == PointForDilation.isFeas(True):
                g1 = G2 - G
            elif prevIter_PointForDilation.isFeas(True):
                g1 = G2.copy()
            else:
                g1 = G.copy()
                alp_addition += 0.05
                
            #print p.getMaxResidual(PointForDilation.x, 1)
            ##############################################
            # the case may be occured when 
            #  1) lastPointOfSameType is used 
            # or
            #  2) some NaN from constraints have been excluded
            if norm(G2 - G) < 1e-12 * min((norm(G2), norm(G))) and (involve_lastPointOfSameType or NaN_derivatives_excluded):
                p.debugmsg("ralg: 'last point of same type gradient' is used")
                g1 = G2
            ##############################################


                #g1 = -G.copy() # signum doesn't matter here


            # changes wrt infeas constraints
#            if prevIterPoint.nNaNs() != 0:
#                cp, hp = prevIterPoint.c(), prevIterPoint.h()
#                ind_infeas_cp, ind_infeas_hp = isnan(cp), isnan(hp)
#                
#                c, h = iterPoint.c(), iterPoint.h()
#                ind_infeas_c, ind_infeas_h = isnan(c), isnan(h)
#                
#                ind_goodChange_c = logical_and(ind_infeas_cp,  logical_not(ind_infeas_c))
#                ind_goodChange_h = logical_and(ind_infeas_hp,  logical_not(ind_infeas_h))
#                
#                any_c, any_h = any(ind_goodChange_c), any(ind_goodChange_h)
#                altDilation = zeros(n)
#                if any_c:
#                    altDilation += sum(atleast_2d(iterPoint.dc(where(ind_goodChange_c)[0])), 0)
#                    assert not any(isnan(altDilation))
#                if any_h:
#                    altDilation += sum(atleast_2d(iterPoint.dh(where(ind_goodChange_h)[0])), 0)
#                if any_c or any_h:
#                    #print '!>', altDilation
#                    #g1 = altDilation
#                    pass
            # changes end


            """                             Perform dilation                               """

            # CHANGES
#            g = economyMult(b.T, g1)
#            gn = g/norm(g)
#            if len(directionVectorsList) == 0 or n < 3 or norm(g1) < 1e-20: pass
#            else:
#                if len(directionVectorsList) == 1 or abs(dot(directionVectorsList[-1], directionVectorsList[-2]))>0.999:
#                    projectionComponentLenght = abs(dot(directionVectorsList[-1], gn))
#                    restLength = sqrt(1 - min((1, projectionComponentLenght))**2)
#                else: 
#                    e1 = directionVectorsList[-1]
#                    e2 = directionVectorsList[-2] - dot(directionVectorsList[-1], directionVectorsList[-2]) * directionVectorsList[-1]
#                    print dot(directionVectorsList[-1], directionVectorsList[-2])
#                    e2 /= norm(e2)
#                    proj1, proj2 = dot(e1, gn), dot(e2, gn)
#                    rest = gn - proj1 * e1 - proj2 * e2
#                    restLength = norm(rest)
#                assert restLength < 1+1e-5, 'error in ralg solver: incorrect restLength'
#                
#                # TODO: make it parameters of ralg
#                commonCoeff, alp_add_coeff = 0.5, 1.0
#                
#                if restLength < commonCoeff * (n - 2.0) / n:
#                    #pass
#                    alpAddition = 0.5+(arctan((n - 2.0) / (n * restLength)) - pi / 4.0) / (pi / 2.0) * alp_add_coeff
#                    #p.debugmsg('alpAddition:' + str(alpAddition))
#                    assert alpAddition > 0 # if someone incorrectly modifies commonCoeff it can be less than zero
#                    alp_addition += alpAddition
#                    #p.debugmsg('alp_addition:' + str(alp_addition))
#                    
#            directionVectorsList.append(gn)
#            if len(directionVectorsList) > 2: directionVectorsList = directionVectorsList[:-2]
            # CHANGES END

            if doDilation:
                g = economyMult(b.T, g1)
                ng = p.norm(g)

                if self.needRej(p, b, g1, g) or selfNeedRej:
                    selfNeedRej = False
                    if self.showRej or p.debug:
                        p.info('debug msg: matrix B restoration in ralg solver')
                    b = B0.copy()
                    hs = p.norm(prevIter_best_ls_point.x - best_ls_point.x)
                    # TODO: iterPoint = projection(iterPoint,Aeq) if res_Aeq > 0.75*contol

                if ng < 1e-40: 
                    hs *= 0.9
                    p.debugmsg('small dilation direction norm (%e), skipping' % ng)
                if all(isfinite(g)) and ng > 1e-50 and doDilation:
                    g = (g / ng).reshape(-1,1)
                    vec1 = economyMult(b, g).reshape(-1,1)# TODO: remove economyMult, use dot?
                    #if alp_addition != 0: p.debugmsg('alp_addition:' + str(alp_addition))
                    w = asarray(1.0/(alp+alp_addition)-1.0, T) 
                    vec2 = w * g.T
                    b += p.matmult(vec1, vec2)
            

            """                               Call OO iterfcn                                """
            if hasattr(p, '_df'): delattr(p, '_df')
            if best_ls_point.isFeas(False) and hasattr(best_ls_point, '_df'): 
                p._df = best_ls_point.df().copy()           
                
            p.iterfcn(best_ls_point)
            

            """                             Check stop criteria                           """

            cond_same_point = array_equal(best_ls_point.x, prevIter_best_ls_point.x)
            if cond_same_point and not p.istop:
                p.istop = 14
                p.msg = 'X[k-1] and X[k] are same'
                p.stopdict[SMALL_DELTA_X] = True
                restoreProb()
                self.innerState = {'B': b, 'hs': hs}
                return
            
            s2 = 0
            if p.istop and not p.userStop:
                if p.istop not in p.stopdict: p.stopdict[p.istop] = True # it's actual for converters, TODO: fix it
                if SMALL_DF in p.stopdict:
                    if best_ls_point.isFeas(False): s2 = p.istop
                    p.stopdict.pop(SMALL_DF)
                if SMALL_DELTA_F in p.stopdict:
                    # TODO: implement it more properly
                    if best_ls_point.isFeas(False) and prevIter_best_ls_point.f() != best_ls_point.f(): s2 = p.istop
                    p.stopdict.pop(SMALL_DELTA_F)
                if SMALL_DELTA_X in p.stopdict:
                    if best_ls_point.isFeas(False) or not prevIter_best_ls_point.isFeas(False) or cond_same_point: s2 = p.istop
                    p.stopdict.pop(SMALL_DELTA_X)
#                if s2 and (any(isnan(best_ls_point.c())) or any(isnan(best_ls_point.h()))) \
#                and not p.isNaNInConstraintsAllowed\
#                and not cond_same_point:
#                    s2 = 0
                    
                if not s2 and any(p.stopdict.values()):
                    for key,  val in p.stopdict.items():
                        if val == True:
                            s2 = key
                            break
                p.istop = s2
                
                for key,  val in p.stopdict.items():
                    if key < 0 or key in set([FVAL_IS_ENOUGH, USER_DEMAND_STOP, BUTTON_ENOUGH_HAS_BEEN_PRESSED]):
                        p.iterfcn(bestPoint)
                        self.innerState = {'B': b, 'hs': hs}
                        return
            """                                If stop required                                """
            
            if p.istop:
#                if self.needRej(p, b, g1, g) or not feasiblePointWasEncountered:
#                    b = B0.copy()
#                    hs = max((p.norm(prevIter_best_ls_point.x - best_ls_point.x) , 128*p.xtol))
#                    p.istop = 0
#                else:
                    restoreProb()
                    p.iterfcn(bestPoint)
                    #p.istop, p.msg = istop, msg
                    self.innerState = {'B': b, 'hs': hs}
                    return


            """                Some final things for ralg main cycle                """
#            p.debugmsg('new point Aeq residual:'+str(norm(dot(Aeq, iterPoint.x)-beq)))
#            if needProjection and itn!=0:
#                #pass
#                x2 = self.linEqProjection(iterPoint.x, Aeq, beq)
#                p.debugmsg('norm(delta):' + str(norm(iterPoint.x-x2))) 
#                iterPoint = p.point(x2)
#                p.debugmsg('2: new point Aeq residual:'+str(norm(dot(Aeq, iterPoint.x)-beq)))
            #p.hs.append(hs)
            #g = moveDirection.copy()
            
            #prevDirectionForDilation = directionForDilation

            #iterPoint = None
            #doScale = self.new_s and prevIter_PointForDilation.isFeas(True) !=  best_ls_point.isFeas(True)
            #print doScale
            prevIter_best_ls_point = best_ls_point
            prevIter_PointForDilation = best_ls_point
            prevDirectionForDilation = best_ls_point._getDirection(self.approach)
            moveDirection = best_ls_point._getDirection(self.approach)
Exemple #6
0
"""
The example illustrates oosolver usage
You should pay special attention for "isInstalled" field

oosolver work is untested for converters
"""
from openopt import oosolver, NLP

ipopt = oosolver('ipopt', color='r') # oosolver can hanlde prob parameters
ralg = oosolver('ralg', color='k', alp = 4.0) # as well as solver parameters
asdf = oosolver('asdf')

solvers = [ralg, asdf, ipopt]
# or just
# solvers = [oosolver('ipopt', color='r'), oosolver('asdf'), oosolver('ralg', color='k', alp = 4.0)]

for solver in solvers:
    if not solver.isInstalled:
        print 'solver ' + solver.__name__ + ' is not installed'
        continue
    p = NLP(x0 = 15, f = lambda x: x**4, df = lambda x: 4 * x**3, iprint = 0)
    r = p.solve(solver, plot=1, show = solver == solvers[-1])
Exemple #7
0
    def solve(self, *args, **kw):
        if len(args) > 1:
            self.err('''
            incorrect number of arguments for solve(), 
            must be at least 1 (solver), other must be keyword arguments''')
        if self.start is None and not self.returnToStart:
            self.err('for returnToStart=False mode you should provide start, other cases are unimplemented yet')
        solver = args[0] if len(args) != 0 else kw.get('solver', self.solver)
        KW = self.__init_kwargs.copy()
        KW.update(kw)
        
        objective = KW.get('objective', self.objective)
        if isinstance(objective, (list, tuple, set)):
            nCriteria = len(self.objective)
            if 3 * nCriteria != np.asarray(self.objective).size:
                objective = [(objective[3*i], objective[3*i+1], objective[3*i+2]) for i in range(int(round(np.asarray(self.objective).size / 3)))]
            if len(objective) == 1:
                KW['fTol'], KW['goal'] = objective[0][1:]
        else:
            objective = [(self.objective, KW.get('fTol', getattr(self, 'fTol')), KW.get('goal', getattr(self, 'goal')))]

        nCriteria = len(objective)
        isMOP = nCriteria > 1
        mainCr = objective[0][0]
         
        import FuncDesigner as fd, openopt as oo 
        solverName = solver if type(solver) == str else solver.__name__
        is_interalg = solverName == 'interalg'
        is_glp = solverName == 'sa'
        if is_glp:
            assert nCriteria == 1, 'you cannot solve multiobjective tsp by the solver'
            
        is_interalg_raw_mode = is_interalg and KW.get('dataHandling', oo.oosolver(solver).dataHandling) in ('auto','raw')
        KW.pop('objective', None)
        P = oo.MOP if nCriteria > 1 else oo.GLP if is_interalg else oo.MILP if not is_glp else oo.GLP

        import networkx as nx
        graph = self.graph # must be networkx Graph instance
        
        init_graph_is_directed = graph.is_directed()
        init_graph_is_multigraph = graph.is_multigraph()
        if not init_graph_is_multigraph or not init_graph_is_directed:
            graph = nx.MultiDiGraph(graph) #if init_graph_is_directed else nx.MultiGraph(graph)
        
        nodes = graph.nodes()
        edges = graph.edges()
        n = len(nodes)
        m = len(edges)

        node2index = dict([(node, i) for i, node in enumerate(nodes)])
        
        # TODO: implement MOP with interalg_gdp mode (requires interpolation interval analysis for non-monotone funcs)
        interalg_gdp = 1
        if not is_interalg:# or isMOP:
            # !!!!!!!!!!!!! TODO: add handling of MOP with interalg_gdp?
            interalg_gdp = 0 
            
        if interalg_gdp:
            x = []
            edge_ind2x_ind_val = {}
        else:
            pass
            #x = fd.oovars(m, domain=bool)

        #cr_values = dict([(obj[0], []) for obj in objective])
        cr_values = {}
        constraints = []
        EdgesDescriptors, EdgesCoords = [], []
        # mb rework it by successors etc?
        
        Funcs = {}
        Cons = KW.pop('constraints', [])
        if type(Cons) not in (list, tuple):
            Cons = [Cons]
        usedValues = getUsedValues(Cons)
        usedValues.update(getUsedValues([obj[0] for obj in objective]))
        
        MainCr = mainCr if type(mainCr) in (str, np.str_) else list(usedValues)[0]
        
        isMainCrMin = objective[0][2] in ('min', 'minimum')
        node_out_edges_num = []
        for node in nodes:
            Edges = graph[node]
            node_out_edges_num.append(len(Edges))
            out_nodes = Edges.keys()
            if len(out_nodes) == 0:
                self.err('input graph has node %s that does not lead to any other node; solution is impossible' % node)            
            
            if init_graph_is_multigraph and not isMOP and type(mainCr) in [str, np.str_]:
                W = {}
                for out_node in out_nodes:
                    ww = list(Edges[out_node].values())
                    for w in ww:
                        tmp = W.get(out_node, None)
                        if tmp is None:
                            W[out_node] = w
                            continue
                        th = tmp[mainCr]
                        w_main_cr_val = w[mainCr]
                        if isMainCrMin  == (th > w_main_cr_val):
                            W[out_node] = w
                Out_nodes, W = np.array(list(W.keys())), np.array(list(W.values()))
            else:
                W = np.hstack([list(Edges[out_node].values()) for out_node in out_nodes])
                Out_nodes = np.hstack([[out_node] * len(Edges[out_node]) for out_node in out_nodes])
            
            if interalg_gdp:
                rr = np.array([w[MainCr] for w in W])
                if isMainCrMin:
                    rr = -rr
                elif objective[0][2] not in ('max', 'maximum'):
                    self.err('unimplemented for fixed value goal in TSP yet, only min/max is possible for now')

                ind = rr.argsort()
                W = W[ind]
                Out_nodes = Out_nodes[ind]

            lc = 0
            for i, w in enumerate(W):
                if interalg_gdp:
                    edge_ind2x_ind_val[len(EdgesCoords)] = (len(x), lc)
                lc += 1
                EdgesCoords.append((node, Out_nodes[i]))
                EdgesDescriptors.append(w)

                for key, val in w.items():
                    # for undirected:
                    #if node2index[key] < node2index[out_node]: continue
                    Val = val if self.returnToStart or node != self.start else 0
                    if key in cr_values:
                        cr_values[key].append(Val)
                    else:
                        cr_values[key] = [Val]
            if interalg_gdp:
                x.append(fd.oovar(domain = np.arange(lc)))            
        
        m = len(EdgesCoords) # new value
        
        if is_glp:
            if type(mainCr) not in (str, np.str_):
                self.err('for the solver "sa" only text name objectives are implemented (e.g. "time", "price")')
            if init_graph_is_multigraph:
                self.err('the solver "sa" cannot handle multigraphs yet')
            if len(Cons) != 0:
                self.err('the solver "sa" cannot handle constrained TSP yet')
            M = np.empty((n, n))
            M.fill(np.nan)
            Cr_values = np.array(cr_values[mainCr])
            isMax = objective[0][-1] in ('max', 'maximum')
            if isMax:
                Cr_values = -Cr_values
            for i, w in enumerate(EdgesDescriptors):
                node_in, node_out = EdgesCoords[i]
                M[node_in, node_out] = Cr_values[i]
            S = np.abs(Cr_values).sum() + 1.0
            
            # TODO: check it
            M[np.isnan(M)] = S
            
            prob = P(lambda x: 0, np.zeros(n), iprint = 1)
            prob.f = lambda x: np.nan if not hasattr(prob, 'ff') else (prob.ff if isMax else -prob.ff)
            prob.M = dict([((i, j), M[i, j]) for i in range(n) for j in range(n) if i != j])
            r = prob.solve(solver, **KW)
            xf = [nodes[j] for j in np.array(r.xf, int)]
            r.nodes = xf#.tolist() 
            if self.start is not None:
                j = r.nodes.index(self.start)
                r.nodes = r.nodes[j:] + r.nodes[:j]
            if self.returnToStart:
                r.nodes += [r.nodes[0]]
            r.edges = [(r.nodes[i], r.nodes[i+1]) for i in range(n-1)] 
            r.Edges = [(r.nodes[i], r.nodes[i+1], graph[r.nodes[i]][r.nodes[i+1]][0]) for i in range(n-1)] 
            if self.returnToStart:
                r.edges.append((r.nodes[-2], r.nodes[0]))
                print(r.nodes[-1], r.nodes[0], type(r.nodes[-1]), type(r.nodes[0]), graph[2])
                r.Edges.append((r.nodes[-2], r.nodes[0], graph[r.nodes[-2]][r.nodes[0]][0]))
            #r.xf = r.xk = r.nodes
            # TODO: Edges
            return r
            
        
        #TODO: fix ooarray lb/ub
        #u = np.array([1] + [fd.oovar(lb=2, ub=n) for i in range(n-1)])
        u = fd.hstack((1, fd.oovars(n-1, lb=2, ub=n)))
        for i in range(1, u.size):
            u[i]('u' + str(i))
            
        
        if is_interalg_raw_mode:
            for i in range(n-1):
                u[1+i].domain = np.arange(2, n+1)
        
        if interalg_gdp: 
            assert len(x) == n
            x = fd.ooarray(x)
            
            # TODO: remove it when proper enum implementation in FD engine will be done
            for i in range(n):
                x[i]._init_domain = x[i].domain
                constraints.append(x[i]-x[i]._init_domain[-1] <= 0)
                x[i].domain = np.arange(int(2 ** np.ceil(np.log2(node_out_edges_num[i]))))
#            for i in range(n-1):
#                u[1+i]._init_domain = u[1+i].domain
#                constraints.append(u[1+i]-u[1+i]._init_domain[-1] <= 0)
#                u[1+i].domain = np.arange(u[1+i]._init_domain[0], u[1+i]._init_domain[0]+int(2 ** np.ceil(np.log2(u[1+i]._init_domain[-1]-u[1+i]._init_domain[0]+1))))
#                u[1+i].ub = u[1+i].domain[-1]

        else:
            x = fd.oovars(m, domain=bool) # new m value
        for i in range(x.size):
            x[i]('x'+str(i))
            
            
#        if init_graph_is_directed:
        dictFrom = dict([(node, []) for node in nodes])
        dictTo = dict([(node, []) for node in nodes])
        for i, edge in enumerate(EdgesCoords):
            From, To = edge
            dictFrom[From].append(i)
            dictTo[To].append(i)
        
        
        engine = fd.XOR
        
        # number of outcoming edges = 1
        if not interalg_gdp:
            for node, edges_inds in dictFrom.items():
                # !!!!!!!!!! TODO for interalg_raw_mode: and if all edges have sign similar to goal
                if 1 and is_interalg_raw_mode:
                    c = engine([x[j] for j in edges_inds])
                else:
                    nEdges = fd.sum([x[j] for j in edges_inds]) 
                    c =  nEdges >= 1 if self.allowRevisit else nEdges == 1
                constraints.append(c)

        # number of incoming edges = 1
        for node, edges_inds in dictTo.items():
            if len(edges_inds) == 0:
                self.err('input graph has node %s that has no edge from any other node; solution is impossible' % node)
            
            if interalg_gdp:
                x_inds, x_vals = [], []
                for elem in edges_inds:
                    x_ind, x_val = edge_ind2x_ind_val[elem]
                    x_inds.append(x_ind)
                    x_vals.append(x_val)
                c = engine([(x[x_ind] == x_val)(tol = 0.5) for x_ind, x_val in zip(x_inds, x_vals)])
            else:
                if 1 and is_interalg_raw_mode and engine == fd.XOR:
                    c = engine([x[j] for j in edges_inds])
                else:            
                    nEdges = fd.sum([x[j] for j in edges_inds]) 
                    c =  nEdges >= 1 if self.allowRevisit else nEdges == 1
            constraints.append(c)
        
        # MTZ
        for i, (I, J) in enumerate(EdgesCoords):
            ii, jj = node2index[I], node2index[J]
            if ii != 0 and jj != 0:
                if interalg_gdp:
                    x_ind, x_val = edge_ind2x_ind_val[i]
                    c = fd.ifThen((x[x_ind] == x_val)(tol=0.5), u[ii] - u[jj]  <= - 1.0)
                elif is_interalg_raw_mode:
                    c = fd.ifThen(x[i], u[ii] - u[jj]  <= - 1.0)#u[jj] - u[ii]  >= 1)
                else:
                    c = u[ii] - u[jj] + 1 <= (n-1) * (1-x[i])
                constraints.append(c)
        
        # handling objective(s)
        FF = []
        
        for optCrName in usedValues:
            
            tmp = cr_values.get(optCrName, [])

            if len(tmp) == 0:
                self.err('seems like graph edgs have no attribute "%s" to perform optimization on it' % optCrName)
            elif len(tmp) != m:
                self.err('for optimization creterion "%s" at least one edge has no this attribute' % optCrName)
            if interalg_gdp:
                F = []
                lc = 0
                for X in x:
                    domain = X._init_domain
                    vals = [tmp[i] for i in range(lc, lc + domain.size)]
                    lc += domain.size
                    #F = sum(x)
                    #F.append(fd.interpolator(domain, vals, k=1, s=0.00000001)(X))
                    F.append(fd.interpolator(domain, vals, k=1)(X))
                    #print(domain, vals)
                F = fd.sum(F)
            else:
                F = fd.sum(x*tmp)
            Funcs[optCrName] = F
        
        for obj in objective:
            FF.append((Funcs[obj[0]] if type(obj[0]) in (str, np.str_) else obj[0](Funcs), obj[1], obj[2]))

        for c in Cons:
            tmp = c(Funcs)
            if type(tmp) in (list, tuple, set):
                constraints += list(tmp)
            else:
                constraints.append(tmp)
        
        startPoint = {x:[0]*(m if not interalg_gdp else n)}
        startPoint.update(dict([(U, i+2) for i, U in enumerate(u[1:])]))

        p = P(FF if isMOP else FF[0][0], startPoint, constraints = constraints)#, fixedVars = fixedVars)
        for param in ('start', 'returnToStart'):
            KW.pop(param, None)
        r = p.solve(solver, **KW)

        if P != oo.MOP:
            r.ff = p.ff
            if interalg_gdp:
                x_ind_val2edge_ind = dict([(elem[1], elem[0]) for elem in edge_ind2x_ind_val.items()])
                SolutionEdges = [(EdgesCoords[i][0], EdgesCoords[i][1], EdgesDescriptors[i]) for i in [x_ind_val2edge_ind[(ind, x[ind](r))] for ind in range(n)]]
            else:
                SolutionEdges = [(EdgesCoords[i][0], EdgesCoords[i][1], EdgesDescriptors[i]) for i in range(m) if r.xf[x[i]] == 1]
            if len(SolutionEdges) == 0: 
                r.nodes = r.edges = r.Edges = []
                return r
                
            S = dict([(elem[0], elem) for elem in SolutionEdges])
            
            SE = [SolutionEdges[0]]
            for i in range(len(SolutionEdges)-1):
                SE.append(S[SE[-1][1]])
            SolutionEdgesCoords = [(elem[0], elem[1]) for elem in SE]

            nodes = [edge[1] for edge in SolutionEdgesCoords]
            if self.start is not None:
                shift_ind = nodes.index(self.start)
                nodes = nodes[shift_ind:] + nodes[:shift_ind]
            
            if self.returnToStart:
                nodes.append(nodes[0])

            edges = SolutionEdgesCoords[1:] + [SolutionEdgesCoords[0]]
            Edges = SE[1:] + [SE[0]]
            if self.start is not None:
                edges, Edges = edges[shift_ind:] + edges[:shift_ind], Edges[shift_ind:] + Edges[:shift_ind]
            if not self.returnToStart:
                edges, Edges = edges[:-1], Edges[:-1]
            r.nodes, r.edges, r.Edges = nodes, edges, Edges
        else:
            r.solution = 'for MOP see r.solutions instead of r.solution'
            tmp_c, tmp_v = r.solutions.coords, r.solutions.values
#            if interalg_gdp:
#                x_ind_val2edge_ind = dict([(elem[1], elem[0]) for elem in edge_ind2x_ind_val.items()])
#                SolutionEdges = [(EdgesCoords[i][0], EdgesCoords[i][1], EdgesDescriptors[i]) for i in [x_ind_val2edge_ind[(ind, x[ind](r))] for ind in range(n)]]
#            else:
#                SolutionEdges = [(EdgesCoords[i][0], EdgesCoords[i][1], EdgesDescriptors[i]) for i in range(m) if r.xf[x[i]] == 1]
            if interalg_gdp: # default for MOP
                x_ind_val2edge_ind = dict([(elem[1], elem[0]) for elem in edge_ind2x_ind_val.items()])
                r.solutions = MOPsolutions([[(EdgesCoords[i][0], EdgesCoords[i][1], EdgesDescriptors[i]) for i in [x_ind_val2edge_ind[(ind, x[ind](Point))] for ind in range(n)]] for Point in r.solutions])
            else:# non-default
                r.solutions = MOPsolutions([[(EdgesCoords[i][0], EdgesCoords[i][1], EdgesDescriptors[i]) for i in range(m) if Point[x[i]] == 1] for Point in r.solutions])
                
            r.solutions.values = tmp_v
        return r
Exemple #8
0

def cb(p):
    tmp = ceil(log10(norm(1.0 - p.xk)))
    if tmp < cb.TMP:
        #        print 'distance:', tmp, 'itn:', p.iter, 'n_func:', p.nEvals['f'], 'n_grad:', -p.nEvals['df']
        cb.TMP = tmp
        cb.stat['dist'].append(tmp)
        cb.stat['f'].append(p.nEvals['f'])
        cb.stat['df'].append(-p.nEvals['df'])
    return False


asa = lambda x: asarray(x).reshape(-1, 1)
solvers = ['ralg', 'amsg2p', 'gsubg']
solvers = [oosolver('amsg2p', gamma=2.0)]
Colors = ['r', 'k', 'b']
lines = []
R = {}
for Tol_p in range(-10, -31, -1):
    #print('Tol = 10^%d' % Tol_p)
    for i, solver in enumerate(solvers):
        p = NSP(obj,
                startPoint,
                maxIter=1700,
                name='Rzhevsky6 (nVars: ' + str(n) + ')',
                maxTime=300,
                maxFunEvals=1e7,
                color=Colors[i])
        p.fOpt = 0.0
        p.fTol = 10**Tol_p
Exemple #9
0
    def solve(self, *args, **kw):
        if len(args) > 1:
            self.err('''
            incorrect number of arguments for solve(), 
            must be at least 1 (solver), other must be keyword arguments''')
        if self.start is None and not self.returnToStart:
            self.err(
                'for returnToStart=False mode you should provide start, other cases are unimplemented yet'
            )
        solver = args[0] if len(args) != 0 else kw.get('solver', self.solver)
        KW = self.__init_kwargs.copy()
        KW.update(kw)

        objective = KW.get('objective', self.objective)
        if isinstance(objective, (list, tuple, set)):
            nCriteria = len(self.objective)
            if 3 * nCriteria != np.asarray(self.objective).size:
                objective = [
                    (objective[3 * i], objective[3 * i + 1],
                     objective[3 * i + 2]) for i in range(
                         int(round(np.asarray(self.objective).size / 3)))
                ]
            if len(objective) == 1:
                KW['fTol'], KW['goal'] = objective[0][1:]
        else:
            objective = [(self.objective, KW.get('fTol', getattr(self,
                                                                 'fTol')),
                          KW.get('goal', getattr(self, 'goal')))]

        nCriteria = len(objective)
        isMOP = nCriteria > 1
        mainCr = objective[0][0]

        import FuncDesigner as fd, openopt as oo
        solverName = solver if type(solver) == str else solver.__name__
        is_interalg = solverName == 'interalg'
        is_glp = solverName == 'sa'
        if is_glp:
            assert nCriteria == 1, 'you cannot solve multiobjective tsp by the solver'

        is_interalg_raw_mode = is_interalg and KW.get(
            'dataHandling',
            oo.oosolver(solver).dataHandling) in ('auto', 'raw')
        KW.pop('objective', None)
        P = oo.MOP if nCriteria > 1 else oo.GLP if is_interalg else oo.MILP if not is_glp else oo.GLP

        import networkx as nx
        graph = self.graph  # must be networkx Graph instance

        init_graph_is_directed = graph.is_directed()
        init_graph_is_multigraph = graph.is_multigraph()
        if not init_graph_is_multigraph or not init_graph_is_directed:
            graph = nx.MultiDiGraph(
                graph)  #if init_graph_is_directed else nx.MultiGraph(graph)

        nodes = graph.nodes()
        edges = graph.edges()
        n = len(nodes)
        m = len(edges)

        node2index = dict([(node, i) for i, node in enumerate(nodes)])

        # TODO: implement MOP with interalg_gdp mode (requires interpolation interval analysis for non-monotone funcs)
        interalg_gdp = 1
        if not is_interalg:  # or isMOP:
            # !!!!!!!!!!!!! TODO: add handling of MOP with interalg_gdp?
            interalg_gdp = 0

        if interalg_gdp:
            x = []
            edge_ind2x_ind_val = {}
        else:
            pass
            #x = fd.oovars(m, domain=bool)

        #cr_values = dict([(obj[0], []) for obj in objective])
        cr_values = {}
        constraints = []
        EdgesDescriptors, EdgesCoords = [], []
        # mb rework it by successors etc?

        Funcs = {}
        Cons = KW.pop('constraints', [])
        if type(Cons) not in (list, tuple):
            Cons = [Cons]
        usedValues = getUsedValues(Cons)
        usedValues.update(getUsedValues([obj[0] for obj in objective]))

        MainCr = mainCr if type(mainCr) in (str,
                                            np.str_) else list(usedValues)[0]

        isMainCrMin = objective[0][2] in ('min', 'minimum')
        node_out_edges_num = []
        for node in nodes:
            Edges = graph[node]
            node_out_edges_num.append(len(Edges))
            out_nodes = Edges.keys()
            if len(out_nodes) == 0:
                self.err(
                    'input graph has node %s that does not lead to any other node; solution is impossible'
                    % node)

            if init_graph_is_multigraph and not isMOP and type(mainCr) in [
                    str, np.str_
            ]:
                W = {}
                for out_node in out_nodes:
                    ww = list(Edges[out_node].values())
                    for w in ww:
                        tmp = W.get(out_node, None)
                        if tmp is None:
                            W[out_node] = w
                            continue
                        th = tmp[mainCr]
                        w_main_cr_val = w[mainCr]
                        if isMainCrMin == (th > w_main_cr_val):
                            W[out_node] = w
                Out_nodes, W = np.array(list(W.keys())), np.array(
                    list(W.values()))
            else:
                W = np.hstack(
                    [list(Edges[out_node].values()) for out_node in out_nodes])
                Out_nodes = np.hstack([[out_node] * len(Edges[out_node])
                                       for out_node in out_nodes])

            if interalg_gdp:
                rr = np.array([w[MainCr] for w in W])
                if isMainCrMin:
                    rr = -rr
                elif objective[0][2] not in ('max', 'maximum'):
                    self.err(
                        'unimplemented for fixed value goal in TSP yet, only min/max is possible for now'
                    )

                ind = rr.argsort()
                W = W[ind]
                Out_nodes = Out_nodes[ind]

            lc = 0
            for i, w in enumerate(W):
                if interalg_gdp:
                    edge_ind2x_ind_val[len(EdgesCoords)] = (len(x), lc)
                lc += 1
                EdgesCoords.append((node, Out_nodes[i]))
                EdgesDescriptors.append(w)

                for key, val in w.items():
                    # for undirected:
                    #if node2index[key] < node2index[out_node]: continue
                    Val = val if self.returnToStart or node != self.start else 0
                    if key in cr_values:
                        cr_values[key].append(Val)
                    else:
                        cr_values[key] = [Val]
            if interalg_gdp:
                x.append(fd.oovar(domain=np.arange(lc)))

        m = len(EdgesCoords)  # new value

        if is_glp:
            if type(mainCr) not in (str, np.str_):
                self.err(
                    'for the solver "sa" only text name objectives are implemented (e.g. "time", "price")'
                )
            if init_graph_is_multigraph:
                self.err('the solver "sa" cannot handle multigraphs yet')
            if len(Cons) != 0:
                self.err('the solver "sa" cannot handle constrained TSP yet')
            M = np.empty((n, n))
            M.fill(np.nan)
            Cr_values = np.array(cr_values[mainCr])
            isMax = objective[0][-1] in ('max', 'maximum')
            if isMax:
                Cr_values = -Cr_values
            for i, w in enumerate(EdgesDescriptors):
                node_in, node_out = EdgesCoords[i]
                M[node_in, node_out] = Cr_values[i]
            S = np.abs(Cr_values).sum() + 1.0

            # TODO: check it
            M[np.isnan(M)] = S

            prob = P(lambda x: 0, np.zeros(n), iprint=1)
            prob.f = lambda x: np.nan if not hasattr(prob, 'ff') else (
                prob.ff if isMax else -prob.ff)
            prob.M = dict([((i, j), M[i, j]) for i in range(n)
                           for j in range(n) if i != j])
            r = prob.solve(solver, **KW)
            xf = [nodes[j] for j in np.array(r.xf, int)]
            r.nodes = xf  #.tolist()
            if self.start is not None:
                j = r.nodes.index(self.start)
                r.nodes = r.nodes[j:] + r.nodes[:j]
            if self.returnToStart:
                r.nodes += [r.nodes[0]]
            r.edges = [(r.nodes[i], r.nodes[i + 1]) for i in range(n - 1)]
            r.Edges = [(r.nodes[i], r.nodes[i + 1],
                        graph[r.nodes[i]][r.nodes[i + 1]][0])
                       for i in range(n - 1)]
            if self.returnToStart:
                r.edges.append((r.nodes[-2], r.nodes[0]))
                print(r.nodes[-1], r.nodes[0], type(r.nodes[-1]),
                      type(r.nodes[0]), graph[2])
                r.Edges.append((r.nodes[-2], r.nodes[0],
                                graph[r.nodes[-2]][r.nodes[0]][0]))
            #r.xf = r.xk = r.nodes
            # TODO: Edges
            return r

        #TODO: fix ooarray lb/ub
        #u = np.array([1] + [fd.oovar(lb=2, ub=n) for i in range(n-1)])
        u = fd.hstack((1, fd.oovars(n - 1, lb=2, ub=n)))
        for i in range(1, u.size):
            u[i]('u' + str(i))

        if is_interalg_raw_mode:
            for i in range(n - 1):
                u[1 + i].domain = np.arange(2, n + 1)

        if interalg_gdp:
            assert len(x) == n
            x = fd.ooarray(x)

            # TODO: remove it when proper enum implementation in FD engine will be done
            for i in range(n):
                x[i]._init_domain = x[i].domain
                constraints.append(x[i] - x[i]._init_domain[-1] <= 0)
                x[i].domain = np.arange(
                    int(2**np.ceil(np.log2(node_out_edges_num[i]))))
#            for i in range(n-1):
#                u[1+i]._init_domain = u[1+i].domain
#                constraints.append(u[1+i]-u[1+i]._init_domain[-1] <= 0)
#                u[1+i].domain = np.arange(u[1+i]._init_domain[0], u[1+i]._init_domain[0]+int(2 ** np.ceil(np.log2(u[1+i]._init_domain[-1]-u[1+i]._init_domain[0]+1))))
#                u[1+i].ub = u[1+i].domain[-1]

        else:
            x = fd.oovars(m, domain=bool)  # new m value
        for i in range(x.size):
            x[i]('x' + str(i))


#        if init_graph_is_directed:
        dictFrom = dict([(node, []) for node in nodes])
        dictTo = dict([(node, []) for node in nodes])
        for i, edge in enumerate(EdgesCoords):
            From, To = edge
            dictFrom[From].append(i)
            dictTo[To].append(i)

        engine = fd.XOR

        # number of outcoming edges = 1
        if not interalg_gdp:
            for node, edges_inds in dictFrom.items():
                # !!!!!!!!!! TODO for interalg_raw_mode: and if all edges have sign similar to goal
                if 1 and is_interalg_raw_mode:
                    c = engine([x[j] for j in edges_inds])
                else:
                    nEdges = fd.sum([x[j] for j in edges_inds])
                    c = nEdges >= 1 if self.allowRevisit else nEdges == 1
                constraints.append(c)

        # number of incoming edges = 1
        for node, edges_inds in dictTo.items():
            if len(edges_inds) == 0:
                self.err(
                    'input graph has node %s that has no edge from any other node; solution is impossible'
                    % node)

            if interalg_gdp:
                x_inds, x_vals = [], []
                for elem in edges_inds:
                    x_ind, x_val = edge_ind2x_ind_val[elem]
                    x_inds.append(x_ind)
                    x_vals.append(x_val)
                c = engine([(x[x_ind] == x_val)(tol=0.5)
                            for x_ind, x_val in zip(x_inds, x_vals)])
            else:
                if 1 and is_interalg_raw_mode and engine == fd.XOR:
                    c = engine([x[j] for j in edges_inds])
                else:
                    nEdges = fd.sum([x[j] for j in edges_inds])
                    c = nEdges >= 1 if self.allowRevisit else nEdges == 1
            constraints.append(c)

        # MTZ
        for i, (I, J) in enumerate(EdgesCoords):
            ii, jj = node2index[I], node2index[J]
            if ii != 0 and jj != 0:
                if interalg_gdp:
                    x_ind, x_val = edge_ind2x_ind_val[i]
                    c = fd.ifThen((x[x_ind] == x_val)(tol=0.5),
                                  u[ii] - u[jj] <= -1.0)
                elif is_interalg_raw_mode:
                    c = fd.ifThen(x[i],
                                  u[ii] - u[jj] <= -1.0)  #u[jj] - u[ii]  >= 1)
                else:
                    c = u[ii] - u[jj] + 1 <= (n - 1) * (1 - x[i])
                constraints.append(c)

        # handling objective(s)
        FF = []

        for optCrName in usedValues:

            tmp = cr_values.get(optCrName, [])

            if len(tmp) == 0:
                self.err(
                    'seems like graph edgs have no attribute "%s" to perform optimization on it'
                    % optCrName)
            elif len(tmp) != m:
                self.err(
                    'for optimization creterion "%s" at least one edge has no this attribute'
                    % optCrName)
            if interalg_gdp:
                F = []
                lc = 0
                for X in x:
                    domain = X._init_domain
                    vals = [tmp[i] for i in range(lc, lc + domain.size)]
                    lc += domain.size
                    #F = sum(x)
                    #F.append(fd.interpolator(domain, vals, k=1, s=0.00000001)(X))
                    F.append(fd.interpolator(domain, vals, k=1)(X))
                    #print(domain, vals)
                F = fd.sum(F)
            else:
                F = fd.sum(x * tmp)
            Funcs[optCrName] = F

        for obj in objective:
            FF.append(
                (Funcs[obj[0]] if type(obj[0]) in (str,
                                                   np.str_) else obj[0](Funcs),
                 obj[1], obj[2]))

        for c in Cons:
            tmp = c(Funcs)
            if type(tmp) in (list, tuple, set):
                constraints += list(tmp)
            else:
                constraints.append(tmp)

        startPoint = {x: [0] * (m if not interalg_gdp else n)}
        startPoint.update(dict([(U, i + 2) for i, U in enumerate(u[1:])]))

        p = P(FF if isMOP else FF[0][0], startPoint,
              constraints=constraints)  #, fixedVars = fixedVars)
        for param in ('start', 'returnToStart'):
            KW.pop(param, None)
        r = p.solve(solver, **KW)

        if P != oo.MOP:
            r.ff = p.ff
            if interalg_gdp:
                x_ind_val2edge_ind = dict([
                    (elem[1], elem[0]) for elem in edge_ind2x_ind_val.items()
                ])
                SolutionEdges = [
                    (EdgesCoords[i][0], EdgesCoords[i][1], EdgesDescriptors[i])
                    for i in
                    [x_ind_val2edge_ind[(ind, x[ind](r))] for ind in range(n)]
                ]
            else:
                SolutionEdges = [(EdgesCoords[i][0], EdgesCoords[i][1],
                                  EdgesDescriptors[i]) for i in range(m)
                                 if r.xf[x[i]] == 1]
            if len(SolutionEdges) == 0:
                r.nodes = r.edges = r.Edges = []
                return r

            S = dict([(elem[0], elem) for elem in SolutionEdges])

            SE = [SolutionEdges[0]]
            for i in range(len(SolutionEdges) - 1):
                SE.append(S[SE[-1][1]])
            SolutionEdgesCoords = [(elem[0], elem[1]) for elem in SE]

            nodes = [edge[1] for edge in SolutionEdgesCoords]
            if self.start is not None:
                shift_ind = nodes.index(self.start)
                nodes = nodes[shift_ind:] + nodes[:shift_ind]

            if self.returnToStart:
                nodes.append(nodes[0])

            edges = SolutionEdgesCoords[1:] + [SolutionEdgesCoords[0]]
            Edges = SE[1:] + [SE[0]]
            if self.start is not None:
                edges, Edges = edges[shift_ind:] + edges[:shift_ind], Edges[
                    shift_ind:] + Edges[:shift_ind]
            if not self.returnToStart:
                edges, Edges = edges[:-1], Edges[:-1]
            r.nodes, r.edges, r.Edges = nodes, edges, Edges
        else:
            r.solution = 'for MOP see r.solutions instead of r.solution'
            tmp_c, tmp_v = r.solutions.coords, r.solutions.values
            #            if interalg_gdp:
            #                x_ind_val2edge_ind = dict([(elem[1], elem[0]) for elem in edge_ind2x_ind_val.items()])
            #                SolutionEdges = [(EdgesCoords[i][0], EdgesCoords[i][1], EdgesDescriptors[i]) for i in [x_ind_val2edge_ind[(ind, x[ind](r))] for ind in range(n)]]
            #            else:
            #                SolutionEdges = [(EdgesCoords[i][0], EdgesCoords[i][1], EdgesDescriptors[i]) for i in range(m) if r.xf[x[i]] == 1]
            if interalg_gdp:  # default for MOP
                x_ind_val2edge_ind = dict([
                    (elem[1], elem[0]) for elem in edge_ind2x_ind_val.items()
                ])
                r.solutions = MOPsolutions([[
                    (EdgesCoords[i][0], EdgesCoords[i][1], EdgesDescriptors[i])
                    for i in [
                        x_ind_val2edge_ind[(ind, x[ind](Point))]
                        for ind in range(n)
                    ]
                ] for Point in r.solutions])
            else:  # non-default
                r.solutions = MOPsolutions([[
                    (EdgesCoords[i][0], EdgesCoords[i][1], EdgesDescriptors[i])
                    for i in range(m) if Point[x[i]] == 1
                ] for Point in r.solutions])

            r.solutions.values = tmp_v
        return r
Exemple #10
0
from numpy import arange
from numpy.linalg import norm
from openopt import NSP, oosolver
from FuncDesigner import *

N = 300
x = oovar('x')
startPoint = {x: 1 + 1.0 / arange(1, N)}
S = 1e4 ** (1.0/arange(1, N))

#f = abs(x[0]) + S * abs(x[1]) + S**2 * abs(x[2])
f = sum(abs(x)*S)


solvers = [oosolver('ralg')]
solvers = [oosolver('gsubg', addASG = True)]
#solvers = [oosolver('gsubg', zhurb = 20, dual=False)]
#solvers = ['ipopt']
#solvers = ['slmvm2']
#solvers = ['mma']
for solver in solvers:
    p = NSP(f, startPoint, maxIter = 10000, maxTime = 15000, maxFunEvals=1e7)
    p.fEnough = 1.5e1
    p.fTol = 1.0e1
    #p.constraints = (y > 5)(tol=1e-4) #x>1e-1 #[2*y<sin(arange(N))]
    #r = p.solve(solver, iprint=10, xtol = 1e-36, ftol = 1e-16, show = solver == solvers[-1])
    r = p.solve(solver, iprint=10, xtol = 1e-16, ftol = 1e-6, show = solver == solvers[-1])
    

Exemple #11
0
# or

#f2 = Max([5*abs(x[0])+1, 50*abs(x[1])+2, 500*x[2]**2+4])
#startPoint = {x:100 + cos(arange(3)), y:cos(arange(N))}


#----------------------------

f = f1 + f2 



print 'start point: f1 = %e   f2 = %e' % (f1(startPoint), f2(startPoint))
#print "start point: norm(f1') = %e   norm(f2') = %e" % (norm(f1.D(startPoint, y)), norm(f2.D(startPoint, x)))

ralg = oosolver('ralg')
gsubg = oosolver('gsubg', addASG = False)

solvers = [ralg]

#solvers = [oosolver('gsubg', zhurb = 20, dual=False)]
solvers = ['ipopt', gsubg, 'scipy_cg']
solvers = [gsubg]
#solvers = ['ipopt']
#solvers = ['slmvm2']
#solvers = ['slmvm1']
#solvers = ['mma']
Colors = ['r', 'k','b']

lines = []
for i, solver in enumerate(solvers):
Exemple #12
0
obj = sum(tmp)


startPoint = {x: 2*ones(n)}
def cb(p):
    tmp = ceil(log10(norm(1.0 - p.xk)))
    if tmp < cb.TMP:
#        print 'distance:', tmp, 'itn:', p.iter, 'n_func:', p.nEvals['f'], 'n_grad:', -p.nEvals['df']
        cb.TMP = tmp
        cb.stat['dist'].append(tmp)
        cb.stat['f'].append(p.nEvals['f'])
        cb.stat['df'].append(-p.nEvals['df'])
    return False
asa = lambda x:asarray(x).reshape(-1, 1)
solvers = ['ralg', 'amsg2p', 'gsubg']
solvers = [oosolver('amsg2p', gamma = 2.0)]
Colors = ['r', 'k','b']
lines = []
R = {}
for Tol_p in range(-10, -31, -1):
    #print('Tol = 10^%d' % Tol_p)
    for i, solver in enumerate(solvers):
        p = NSP(obj, startPoint, maxIter = 1700, name = 'Rzhevsky6 (nVars: ' + str(n)+')', maxTime = 300, maxFunEvals=1e7, color = Colors[i])
        p.fOpt = 0.0
        p.fTol = 10**Tol_p
        cb.TMP = 1000
        cb.stat = {'dist':[], 'f':[], 'df':[]}
        r = p.solve(solver, iprint=-1, xtol = 0, ftol = 0, callback = cb)
        R[solver] = hstack((asa(cb.stat['dist']), asa(cb.stat['f']), asa(cb.stat['df'])))
        print('itn df dx   %d   %0.1e   %0.1e' % (-r.evals['df'], r.ff-p.fOpt, norm(p.xk-1.0)))
#        print('objective evals: %d   gradient evals: %d ' % (r.evals['f'],r.evals['df']))
Exemple #13
0
"""
The example illustrates oosolver usage
You should pay special attention for "isInstalled" field

oosolver work is untested for converters
"""
from openopt import oosolver, NLP

ipopt = oosolver('ipopt', color='r')  # oosolver can hanlde prob parameters
ralg = oosolver('ralg', color='k', alp=4.0)  # as well as solver parameters
asdf = oosolver('asdf')

solvers = [ralg, asdf, ipopt]
# or just
# solvers = [oosolver('ipopt', color='r'), oosolver('asdf'), oosolver('ralg', color='k', alp = 4.0)]

for solver in solvers:
    if not solver.isInstalled:
        print 'solver ' + solver.__name__ + ' is not installed'
        continue
    p = NLP(x0=15, f=lambda x: x**4, df=lambda x: 4 * x**3, iprint=0)
    r = p.solve(solver, plot=1, show=solver == solvers[-1])
Exemple #14
0
from numpy import arange
from numpy.linalg import norm
from openopt import NSP, oosolver
from FuncDesigner import *

N = 100000
x = oovar('x')
startPoint = {x: 1 + 1.0 / arange(1, N+1)}
S = 1e4 ** (1.0/arange(1, N+1))

arr = sin(arange(N))
f = sum((x-arr)**2 * S) / 1e4


solvers = [oosolver('ralg')]
solvers = [oosolver('gsubg', dual=True, zhurb = 50)]
#solvers = [oosolver('gsubg', zhurb = 20, dual=False)]
#solvers = ['ipopt']
#solvers = ['slmvm2']
#solvers = ['mma']
for solver in solvers:
    p = NSP(f, startPoint, maxIter = 10000, maxTime = 15000, maxFunEvals=1e7)
    p.fEnough = 1.5e-1
    p.fTol = 5.0e-1
    #p.constraints = (y > 5)(tol=1e-4) #x>1e-1 #[2*y<sin(arange(N))]
    #r = p.solve(solver, iprint=10, xtol = 1e-36, ftol = 1e-16, show = solver == solvers[-1])
    r = p.manage(solver, iprint=1, xtol = 1e-8, ftol = 1e-7, show = solver == solvers[-1])
    

Exemple #15
0
    def startOptimization(self, root, varsRoot, AddVar, currValues, \
                          ValsColumnName, ObjEntry, ExperimentNumber, Next, NN, goal, objtol, C):
        AddVar.destroy()
        ValsColumnName.set('Experiment parameters')
        n = len(self.NameEntriesList)
        Names, Lb, Ub, Tol, x0 = [], [], [], [], []
        for i in range(n):
            N, L, U, T, valEntry = \
            self.NameEntriesList[i], self.LB_EntriesList[i], self.UB_EntriesList[i], self.TolEntriesList[i], self.ValueEntriesList[i]
            N.config(state=DISABLED)
            L.config(state=DISABLED)
            U.config(state=DISABLED)
            T.config(state=DISABLED)
            #valEntry.config(state=DISABLED)
            name, lb, ub, tol, val = N.get(), L.get(), U.get(), T.get(
            ), valEntry.get()
            Names.append(name)
            x0.append(float(val))
            Lb.append(float(lb) if lb != '' else -inf)
            Ub.append(float(ub) if ub != '' else inf)

            # TODO: fix zero
            Tol.append(float(tol) if tol != '' else 0)

        x0, Tol, Lb, Ub = asfarray(x0), asfarray(Tol), asfarray(Lb), asfarray(
            Ub)
        x0 *= xtolScaleFactor / Tol
        #self.x0 = copy(x0)
        from openopt import NLP, oosolver
        p = NLP(objective,
                x0,
                lb=Lb * xtolScaleFactor / Tol,
                ub=Ub * xtolScaleFactor / Tol)
        self.prob = p
        #calculated_points = [(copy(x0), copy(float(ObjEntry.get())))
        p.args = (Tol, self, ObjEntry, p, root, ExperimentNumber, Next, NN,
                  objtol, C)
        #p.graphics.rate = -inf
        #p.f_iter = 2
        solver = oosolver('bobyqa', useStopByException=False)
        p.solve(solver, iprint=1, goal=goal)  #, plot=1, xlabel='nf')
        self.solved = True
        if p.stopcase >= 0:
            self.ValsColumnName.set('Best parameters')
            NN.set('Best obtained objective value:')
        #Next.config(state=DISABLED)
        Next.destroy()
        #reverse = True if goal == 'min' else False

        calculated_items = self.calculated_points.items() if isinstance(
            self.calculated_points, dict) else self.calculated_points
        vals = [calculated_items[i][1] for i in range(len(calculated_items))]
        ind = argsort(vals)
        j = ind[0] if goal == 'min' else ind[-1]
        key, val = calculated_items[j]
        text_coords = key.split(' ')
        for i in range(len(self.ValueEntriesList)):
            self.ValueEntriesList[i].delete(0, END)
            self.ValueEntriesList[i].insert(0, text_coords[i])
        ObjEntry.delete(0, END)
        obj_tol = self.ObjTolEntry.get()
        val = float(val) * 1e4 * objtol
        ObjEntry.insert(0, str(val))
        ObjEntry.config(state=DISABLED)
Exemple #16
0
    def _solve(self, *args, **kwargs):
        
        #!!!!! TODO: determing LP, MILP, MINLP if possible
        try:
            import openopt
        except ImportError:
            raise FuncDesignerException('to perform the operation you should have openopt installed')
        
        
        constraints = self._getAllConstraints()
            
        # TODO: mention it in doc
        if 'constraints' in kwargs:
            tmp = set(kwargs['constraints'])
            tmp.update(set(constraints))
            kwargs['constraints'] = tmp
        else:
            kwargs['constraints'] = constraints
        
        freeVars, fixedVars = kwargs.get('freeVars', None), kwargs.get('fixedVars', None)
        isSystemOfEquations = kwargs['goal'] == 'solution'
        
        isLinear = all([(c.oofun.getOrder(freeVars, fixedVars) < 2) for c in constraints])
        
        if isSystemOfEquations:
            if isLinear: # Linear equations system
                p = sle(list(kwargs['constraints']), *args, **kwargs)
            else: # Nonlinear equations system
                f = kwargs['constraints']
                ############################################
                #cons = self._getAllConstraints()
                
                # OLD
#                if not all([array_equal(c.lb, c.ub) for c in f]):
#                    raise FuncDesignerException('Solving constrained nonlinear systems is not implemented for oosystem yet, use SNLE constructor instead')
#                kwargs['constraints'] = ()
                
                # NEW
                C,  F = [], []
                for c in f:
                    F.append(c) if array_equal(c.lb, c.ub) else C.append(c)
                kwargs['constraints'] = C
                f = F
                ############################################
                
                p = openopt.SNLE(f, *args, **kwargs)
                if 'nlpSolver' in kwargs:
                    p.solver = kwargs['nlpSolver']
                    
                
        else: # an optimization problem
            assert len(args) > 0,  'you should have objective function as 1st argument'
            objective = args[0]
            if isinstance(objective, BaseFDConstraint):
                raise FuncDesignerException("1st argument can't be of type 'FuncDesigner constraint', it should be 'FuncDesigner oofun'")
            elif not isinstance(objective, oofun):
                raise FuncDesignerException('1st argument should be objective function of type "FuncDesigner oofun"')
            
            isLinear &= objective.getOrder(freeVars, fixedVars) < 2
            
            if isLinear:
                p = openopt.LP(*args, **kwargs)
                if 'solver' not in kwargs:
                    for solver in self.lpSolvers:
                        if (':' not in solver and not openopt.oosolver(solver).isInstalled )or (solver == 'glpk' and not openopt.oosolver('cvxopt_lp').isInstalled):
                            continue
                        if solver == 'glpk' :
                            p2 = openopt.LP([1, -1], lb = [1, 1], ub=[10, 10])
                            try:
                                r = p2.solve('glpk', iprint=-5)
                            except:
                                continue
                            if r.istop < 0:
                                continue
                            else:
                                break
                    if ':' in solver:
                        pWarn('You have linear problem but no linear solver (lpSolve, glpk, cvxopt_lp) is installed; converter to NLP will be used.')
                    p.solver = solver
                else:
                    solverName = kwargs['solver']
                    if type(solverName) != str:
                        solverName = solverName.__name__
                    if solverName not in self.lpSolvers: 
                        solverName = 'nlp:' + solverName
                        p.solver = solverName 
                        p.warn('you are solving linear problem with non-linear solver')
            else:
                p = openopt.NLP(*args, **kwargs)
                if 'solver' not in kwargs:
                    p.solver = 'ralg'
                
        # TODO: solver autoselect
        #if p.iprint >= 0: p.disp('The optimization problem is  ' + p.probType)
        p._isFDmodel = lambda *args,  **kwargs: True
        return p.solve() if kwargs.get('manage', False) in (False, 0) else p.manage()
Exemple #17
0
def set_routine(p,  *args, **kw):
    if len(args) > 1:
        p.err('''
        incorrect number of arguments for solve(), 
        must be at least 1 (solver), other must be keyword arguments''')
    solver = args[0] if len(args) != 0 else kw.get('solver', p.solver)
    
    import FuncDesigner as fd, openopt
    is_interalg = openopt.oosolver(solver).__name__ == 'interalg'
    
    graph = p.graph # must be networkx instance
    nodes = graph.nodes()
    edges = graph.edges()
    
    n = len(nodes)
    
    node2index = dict((node, i) for i, node in enumerate(nodes))
    index2node = dict((i, node) for i, node in enumerate(nodes))
    
    
    x = fd.oovars(n, domain=bool)
    objective = fd.sum(x)
    startPoint = {x:[0]*n}
    
    fixedVars = {}
   
    includedNodes = getattr(kw, 'includedNodes', None)
    if includedNodes is None:
        includedNodes = getattr(p, 'includedNodes', ())
    for node in includedNodes:
        fixedVars[x[node2index[node]]] = 1

    excludedNodes = getattr(kw, 'excludedNodes', None)
    if excludedNodes is None:
        excludedNodes = getattr(p, 'excludedNodes', ())
    for node in excludedNodes:
        fixedVars[x[node2index[node]]] = 0

    if p.probType == 'DSP':
        constraints = []
        engine = fd.OR if is_interalg else lambda List: fd.sum(List) >= 1
        Engine = lambda d, n: engine([x[node2index[k]] for k in (list(d.keys())+[n])]) 
        for node in nodes:
            adjacent_nodes_dict = graph[node]
            if len(adjacent_nodes_dict) == 0:
                fixedVars[x[node2index[node]]] = 1
                continue
            constraints.append(Engine(adjacent_nodes_dict, node))
    else:
        constraints = \
        [fd.NAND(x[node2index[i]], x[node2index[j]]) for i, j in edges] \
        if is_interalg else \
        [x[node2index[i]]+x[node2index[j]] <=1 for i, j in edges]
    
    P = openopt.GLP if is_interalg else openopt.MILP
    goal = 'min' if p.probType == 'DSP' else 'max' 
    p = P(objective, startPoint, constraints = constraints, fixedVars = fixedVars, goal = goal)
    
    for key, val in kw.items():
        setattr(p, key, val)
    r = p.solve(solver, **kw)
    r.solution = [index2node[i] for i in range(n) if r.xf[x[i]] == 1]
    r.ff = len(r.solution)
    return r
Exemple #18
0
from FuncDesigner import *
from openopt import NLP, oosolver
from numpy import arange
N = 10
a = oovar('a', size=N)
b = oovar('b', size=N)
f = (sum(abs(a*arange(1,N+1))**2.5)+sum(abs(b*arange(1,N+1))**1.5)) / 10000

startPoint = {a:cos(arange(N)), b:sin(arange(N))} # however, you'd better use numpy arrays instead of Python lists
p = NLP(f, startPoint)
#p.constraints = [(a>1)(tol=1e-5), a**2+b**2 < 0.1+a+b]# + [(a[i]**2+b[i]**2 < 3+abs(a[i])+abs(b[i])) for i in range(N)]

p.constraints = [a>1, 10*a>10]          # + [(a[i]**2+b[i]**2 < 3+abs(a[i])+abs(b[i])) for i in range(N)]
#p.constraints = []
#C = sum(a**2+b**2 - (0.1+a+b)
C = [ifThenElse(a[i]**2+b[i]**2 - (0.1+a[i]+b[i])<0,  0,  a[i]**2+b[i]**2 - (0.1+a[i]+b[i])) for i in range(N)]
p.constraints.append(sum(C)<0)
solver = 'ipopt'
solver = oosolver('ralg')
#solver = oosolver('ralg', approach='nqp')
r = p.minimize(solver, maxIter = 15000)