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
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)
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
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()
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)
""" 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])
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
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
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
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])
# 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):
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']))
""" 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])
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])
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)
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()
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
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)