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 linear_render(f, D, Z): import FuncDesigner as fd if f.is_oovar: return f ff = f(Z) name, tol, _id = f.name, f.tol, f._id f = fd.sum([v * (val if type(val) != ndarray or val.ndim < 2 else val.flatten()) for v, val in D.items()]) \ + (ff if isscalar(ff) or ff.ndim <= 1 else asscalar(ff)) f.name, f.tol, f._id = name, tol, _id return f
def linear_render(f, D, Z): import FuncDesigner as fd if f.is_oovar: return f ff = f(Z) name, tol, _id = f.name, f.tol, f._id f = fd.sum([v * (val if type(val) != ndarray or val.ndim < 2 else val.flatten()) for v, val in D.items()]) \ + (ff if isscalar(ff) or ff.ndim <= 1 else asscalar(ff)) f.name, f.tol, f._id = name, tol, _id return f
def fit_kernel_model(kernel, loss, X, y, gamma, weights=None): n_samples = X.shape[0] gamma = float(gamma) if weights is not None: weights = weights / np.sum(weights) * weights.size # --- optimize bias term --- bias = fd.oovar('bias', size=1) if weights is None: obj_fun = fd.sum(loss(y, bias)) else: obj_fun = fd.sum(fd.dot(weights, loss(y, bias))) optimizer = NLP(obj_fun, {bias: 0.}, ftol=1e-6, iprint=-1) result = optimizer.solve('ralg') bias = result(bias) # --- optimize betas --- beta = fd.oovar('beta', size=n_samples) # gram matrix K = kernel(X, X) assert K.shape == (n_samples, n_samples) K_dot_beta = fd.dot(K, beta) penalization_term = gamma * fd.dot(beta, K_dot_beta) if weights is None: loss_term = fd.sum(loss(y - bias, K_dot_beta)) else: loss_term = fd.sum(fd.dot(weights, loss(y - bias, K_dot_beta))) obj_fun = penalization_term + loss_term beta0 = np.zeros((n_samples, )) optimizer = NLP(obj_fun, {beta: beta0}, ftol=1e-4, iprint=-1) result = optimizer.solve('ralg') beta = result(beta) return KernelModel(X, kernel, beta, bias)
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 linear_render(f, D, Z): import FuncDesigner as fd if f.is_oovar: return f ff = f(Z) name, tol, _id = f.name, f.tol, f._id tmp = [(v if isscalar(val) and val == 1.0 else v * (val if type(val) != ndarray or val.ndim < 2 else val.flatten())) for v, val in D.items()] c = ff if isscalar(ff) or ff.ndim <= 1 else asscalar(ff) if c != 0: tmp.append(c) f = tmp[0] if len(tmp) == 1 else tmp[0]+tmp[1] if len(tmp) == 2 else fd.sum(tmp) # f = fd.sum([v * (val if type(val) != ndarray or val.ndim < 2 else val.flatten()) for v, val in D.items()]) \ # + (ff if isscalar(ff) or ff.ndim <= 1 else asscalar(ff)) f.name, f.tol, f._id = name, tol, _id return f
def compressed_sensing2(x1, trans): """L1 compressed sensing :Parameters: x1 : array-like, shape=(n_outputs,) input sparse vector trans : array-like, shape=(n_outputs, n_inputs) transformation matrix :Returns: decoded vector, shape=(n_inpus,) :RType: array-like """ # obrain sizes of inputs and outputs (n_outputs, n_inputs) = trans.shape # define variable t = fd.oovar('t', size=n_inputs) x = fd.oovar('x', size=n_inputs) # objective to minimize: f x^T -> min objective = fd.sum(t) # init constraints constraints = [] # equality constraint: a_eq x^T = b_eq constraints.append(fd.dot(trans, x) == x1) # inequality constraint: -t < x < t constraints.append(-t <= x) constraints.append(x <= t) # start_point start_point = {x:np.zeros(n_inputs), t:np.zeros(n_inputs)} # solve linear programming prob = LP(objective, start_point, constraints=constraints) result = prob.minimize('pclp') # glpk, lpSolve... if available # print result # print "x =", result.xf # arguments at mimimum # print "objective =", result.ff # value of objective return result.xf[x]
def automaticdiffertest(): #from FuncDesigner import * a, b, c = fd.oovars('a', 'b', 'c') f1, f2 = fd.sin(a) + fd.cos(b) - fd.log2(c) + fd.sqrt(b), fd.sum(c) + c * fd.cosh(b) / fd.arctan(a) + c[0] * c[1] + c[-1] / (a * c.size) f3 = f1*f2 + 2*a + fd.sin(b) * (1+2*c.size + 3*f2.size) f = 2*a*b*c + f1*f2 + f3 + fd.dot(a+c, b+c) point = {a:1, b:2, c:[3, 4, 5]} # however, you'd better use numpy arrays instead of Python lists print(f(point)) print(f.D(point)) print(f.D(point, a)) print(f.D(point, [b])) print(f.D(point, fixedVars = [a, c]))
def Pyomo2FD_expression(exp, ipoint, vars, symbol_map): if isinstance(exp, expr._IntrinsicFunctionExpression): if not exp.name in intrinsic_function_expressions: logger.error("Unsupported intrinsic function (%s)", exp.name) raise TypeError("FuncDesigner does not support '{0}' expressions".format(exp.name)) args = [] for child_exp in exp._args: args.append( Pyomo2FD_expression(child_exp, ipoint, vars, symbol_map)) fn = intrinsic_function_expressions[exp.name] return fn(*tuple(args)) elif isinstance(exp, expr._SumExpression): args = [] for child_exp in exp._args: args.append( Pyomo2FD_expression(child_exp, ipoint, vars, symbol_map) ) iargs = args.__iter__() # # NOTE: this call to FuncDesigner.sum() _must_ be passed a list. If a # generator is passed to this function, then an unbalanced expression tree will # be generated that is not well-suited for large models! # if six.PY2: return FuncDesigner.sum([c*iargs.next() for c in exp._coef]) + exp._const else: return FuncDesigner.sum([c*next(iargs) for c in exp._coef]) + exp._const elif isinstance(exp, expr._ProductExpression): ans = exp._coef for n in exp._numerator: ans *= Pyomo2FD_expression(n, ipoint, vars, symbol_map) for n in exp._denominator: ans /= Pyomo2FD_expression(n, ipoint, vars, symbol_map) return ans #elif isinstance(exp, expr._InequalityExpression): #args = [] #for child_exp in exp._args: #args.append( Pyomo2FD_expression(child_exp, ipoint, vars, symbol_map) ) # #ans = args[0] #for i in xrange(len(args)-1): ## FD doesn't care whether the inequality is strict #ans = ans < args[i+1] #return ans #elif isinstance(exp, expr._InequalityExpression): #return Pyomo2FD_expression(exp._args[0], ipoint, vars) == Pyomo2FD_expression(exp._args[1], ipoint, vars, symbol_map) elif isinstance(exp, _ExpressionData): return Pyomo2FD_expression(exp._args[0], ipoint, vars, symbol_map) elif (isinstance(exp,var._VarData) or isinstance(exp,var.Var)) and not exp.is_fixed(): vname = symbol_map.getSymbol(exp, labeler) if not vname in vars: vars[vname] = FuncDesigner.oovar(vname) ipoint[vars[vname]] = 0.0 if exp.value is None else exp.value #symbol_map.getSymbol(exp, lambda obj,x: x, vname) return vars[vname] elif isinstance(exp,param._ParamData): return exp.value elif type(exp) in intlist: return exp elif isinstance(exp,numvalue.NumericConstant) or exp.is_fixed(): return exp.value else: raise ValueError("Unsupported expression type in Pyomo2FD_expression: "+str(type(exp)))
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 Pyomo2FD_expression(exp, ipoint, vars, symbol_map): if isinstance(exp, expr._IntrinsicFunctionExpression): if not exp.name in intrinsic_function_expressions: logger.error("Unsupported intrinsic function (%s)", exp.name) raise TypeError( "FuncDesigner does not support '{0}' expressions".format( exp.name)) args = [] for child_exp in exp._args: args.append( Pyomo2FD_expression(child_exp, ipoint, vars, symbol_map)) fn = intrinsic_function_expressions[exp.name] return fn(*tuple(args)) elif isinstance(exp, expr._SumExpression): args = [] for child_exp in exp._args: args.append( Pyomo2FD_expression(child_exp, ipoint, vars, symbol_map)) iargs = args.__iter__() # # NOTE: this call to FuncDesigner.sum() _must_ be passed a list. If a # generator is passed to this function, then an unbalanced expression tree will # be generated that is not well-suited for large models! # if six.PY2: return FuncDesigner.sum([c * iargs.next() for c in exp._coef]) + exp._const else: return FuncDesigner.sum([c * next(iargs) for c in exp._coef]) + exp._const elif isinstance(exp, expr._ProductExpression): ans = exp._coef for n in exp._numerator: ans *= Pyomo2FD_expression(n, ipoint, vars, symbol_map) for n in exp._denominator: ans /= Pyomo2FD_expression(n, ipoint, vars, symbol_map) return ans #elif isinstance(exp, expr._InequalityExpression): #args = [] #for child_exp in exp._args: #args.append( Pyomo2FD_expression(child_exp, ipoint, vars, symbol_map) ) # #ans = args[0] #for i in xrange(len(args)-1): ## FD doesn't care whether the inequality is strict #ans = ans < args[i+1] #return ans #elif isinstance(exp, expr._InequalityExpression): #return Pyomo2FD_expression(exp._args[0], ipoint, vars) == Pyomo2FD_expression(exp._args[1], ipoint, vars, symbol_map) elif isinstance(exp, _ExpressionData): return Pyomo2FD_expression(exp._args[0], ipoint, vars, symbol_map) elif (isinstance(exp, var._VarData) or isinstance(exp, var.Var)) and not exp.is_fixed(): vname = symbol_map.getSymbol(exp, labeler) if not vname in vars: vars[vname] = FuncDesigner.oovar(vname) ipoint[vars[vname]] = 0.0 if exp.value is None else exp.value #symbol_map.getSymbol(exp, lambda obj,x: x, vname) return vars[vname] elif isinstance(exp, param._ParamData): return exp.value elif type(exp) in intlist: return exp elif isinstance(exp, numvalue.NumericConstant) or exp.is_fixed(): return exp.value else: raise ValueError( "Unsupported expression type in Pyomo2FD_expression: " + str(type(exp)))
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
h = [] for i in range(n): if i == j: h.append(12+n/(i+1.0)) elif i == j + 1: h.append(0) elif j == i + 2: h.append(0) else: h.append(15/((i+1)+0.1*(j+1))) H.append(h) #print H #H = [[15,0,4.83871], # [12.5,13.5,0], # [0,6.52174,13]] #print H x = fd.oovars(n) f = fd.dot(fd.dot(x, H), x) startPoint = {x: np.zeros(n)} constraints = [] constraints.append(x > np.zeros(n)) constraints.append(fd.sum(x) == 1) p = QP(f, startPoint, constraints=constraints) r = p.solve("qlcp") x_opt = r(x) print(math.sqrt(r.ff)) # problem # http://abel.ee.ucla.edu/cvxopt/examples/tutorial/qp.html
def solve(self, *args, **kw): import FuncDesigner as fd, openopt as oo 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) KW = self.__init_kwargs.copy() KW.update(kw) bins, items = self.bins, self.items #n = len(items) # 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 = 1#len(objective) isMOP = nCriteria > 1 #mainCr = objective[0][0] solverName = solver if type(solver) == str else solver.__name__ is_interalg = solverName == 'interalg' is_glp = False#solverName == 'sa' if is_glp: assert nCriteria == 1, 'you cannot solve multiobjective KSP 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 item_numbers = [item.get('n', 1) for item in items] nItemTypes = len(items) nItems = sum(item_numbers) Cons = KW.pop('constraints', []) if type(Cons) not in (list, tuple): Cons = [Cons] Funcs = {} usedValues = getUsedValues(Cons) bins_keys = set(bins.keys()) for Set in (bins_keys, usedValues): if 'n' in Set: Set.remove('n') UsedValues = usedValues.copy() UsedValues.update(bins_keys) cr_values = {} for val in UsedValues: if val == 'nItems': cr_values[val] = 1 else: cr_values[val] = [obj[val] for obj in items] nBins = bins.get('n', -1) if nBins == -1: if len(UsedValues) == 1 and type(bins) == dict: Tmp_items = sum(list(cr_values.values()[0])) Tmp_bins = bins[list(UsedValues)[0]] approx_n_bins = int(np.ceil((2.0 * Tmp_items) / Tmp_bins)) else: approx_n_bins = nItems nBins = approx_n_bins X = fd.oovars(nBins * nItemTypes, domain=int, lb=0).view(np.ndarray).reshape(nItemTypes, nBins) requireCount = False for item in items: if 'n' in item: # x[i].domain = np.arange(obj['n']+1) if is_interalg else int # x[i].ub = obj['n'] # x[i].lb = 0 requireCount = True break y = fd.oovars(nBins, domain = bool)('y') aux_objective = fd.sum(y) #cr_values = dict([(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') # handling objective(s) # FF = [] for optCrName in UsedValues: F = [fd.sum(X[:, j].view(fd.ooarray) * cr_values[optCrName]) for j in range(nBins)] Funcs[optCrName] = F FUNCS = [dict((optCrName, Funcs[optCrName][j]) for optCrName in UsedValues) for j in range(nBins)] # for obj in objective: # FF.append((Funcs[obj[0]](obj[0]) if type(obj[0]) in (str, np.str_) else obj[0](Funcs), obj[1], obj[2])) constraints = [] # 1. Constraints from p.constraints for c in Cons: tmp = [c(F) for F in FUNCS] constraints += tmp # 2. Constraints from bins parameters for k, v in bins.items(): if k != 'n': constraints += [fd.sum(X[:, j].view(fd.ooarray) * cr_values[k]) <= v*y[j] for j in range(nBins)] # 3. Number of items of type i from all bins equals to item_numbers[i] constraints += [fd.sum(X[i].view(fd.ooarray)) == item_numbers[i] for i in range(nItemTypes)] startPoint = dict((X[i, j], 0) for i in range(nItemTypes) for j in range(nBins)) startPoint[y] = [0]*nBins p = P(aux_objective, startPoint, constraints = constraints) # p = P(FF if isMOP else FF[0][0], startPoint, constraints = constraints)#, fixedVars = fixedVars) if not isMOP: p.goal=self.goal r = p.solve(solver, **KW) if P != oo.MOP: r.ff = p.ff if isMOP: assert 0, 'unimplemented' # #assert not requireCount, 'MOP with nItem > 1 is unimplemented yet' # r.solution = 'for MOP see r.solutions instead of r.solution' # #tmp_c, tmp_v = r.solutions.coords, r.solutions.values # if len(r.solutions): # S = [] # for s in r.solutions: # tmp = [((i, int(s[x[i]])) if requireCount else i) for i in range(n) if s[x[i]]>=1] # if 'name' in items[0]: # tmp = [(items[i]['name'], k) for i, k in tmp] if requireCount else [items[i]['name'] for i in tmp] # S.append(dict(tmp) if requireCount else tmp) # Vals = dict([(ff[0].name, r.solutions.values[:, i]) for i, ff in enumerate(FF)]) # # Dicts = [s.copy() for s in S] # for v in usedValues: # if v != 'nItems': # for i, d in enumerate(Dicts): # d[v] = Vals[v][i] # r.solutions = MOPsolutions(Dicts) # r.solutions.coords = S # r.solutions.values = Vals else: if requireCount: xf = [dict((item.get('name',i), int(r.xf[X[i, j]])) for i, item in enumerate(items) if r.xf[X[i, j]]>0) for j in range(nBins) if r.xf[y[j]]] else: xf = [tuple(item.get('name',i) for i, item in enumerate(items) if r.xf[X[i, j]]==1) for j in range(nBins) if r.xf[y[j]]] r.values = dict((optCrName, tuple(sum(item[optCrName]*r.xf[X[i, j]] for i, item in enumerate(items)) for j in range(nBins) if r.xf[y[j]])) for optCrName in UsedValues) r.xf = xf # tmp = [((i, int(r.xf[x[i]])) if requireCount else i) for i in range(n) if r.xf[x[i]]>=1] # if 'name' in items[0]: # tmp = [(items[i]['name'], k) for i, k in tmp] if requireCount else [items[i]['name'] for i in tmp] # r.xf = dict(tmp) if requireCount else tmp return r
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 solve(self, *args, **kw): import FuncDesigner as fd, openopt as oo 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) KW = self.__init_kwargs.copy() KW.update(kw) items = self.items n = len(items) 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] solverName = solver if type(solver) == str else solver.__name__ is_interalg = solverName == 'interalg' is_glp = False #solverName == 'sa' if is_glp: assert nCriteria == 1, 'you cannot solve multiobjective KSP 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 x = fd.oovars(n, domain=bool) requireCount = False for i, obj in enumerate(items): if 'n' in obj: x[i].domain = np.arange(obj['n'] + 1) if is_interalg else int x[i].ub = obj['n'] x[i].lb = 0 requireCount = True #cr_values = dict([(obj[0], []) for obj in objective]) constraints = [] 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])) cr_values = {} for val in usedValues: if val == 'nItems': cr_values[val] = 1 else: cr_values[val] = [obj[val] for obj in items] # MainCr = mainCr if type(mainCr) in (str, np.str_) else list(usedValues)[0] # # isMainCrMin = objective[0][2] in ('min', 'minimum') # handling objective(s) FF = [] for optCrName in usedValues: F = fd.sum(x * cr_values[optCrName]) Funcs[optCrName] = F for obj in objective: FF.append((Funcs[obj[0]](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] * n} p = P(FF if isMOP else FF[0][0], startPoint, constraints=constraints) #, fixedVars = fixedVars) if not isMOP: p.goal = self.goal r = p.solve(solver, **KW) if P != oo.MOP: r.ff = p.ff if isMOP: #assert not requireCount, 'MOP with nItem > 1 is unimplemented yet' r.solution = 'for MOP see r.solutions instead of r.solution' #tmp_c, tmp_v = r.solutions.coords, r.solutions.values if len(r.solutions): S = [] for s in r.solutions: tmp = [((i, int(s[x[i]])) if requireCount else i) for i in range(n) if s[x[i]] >= 1] if 'name' in items[0]: tmp = [ (items[i]['name'], k) for i, k in tmp ] if requireCount else [items[i]['name'] for i in tmp] S.append(dict(tmp) if requireCount else tmp) Vals = dict([(ff[0].name, r.solutions.values[:, i]) for i, ff in enumerate(FF)]) Dicts = [s.copy() for s in S] for v in usedValues: if v != 'nItems': for i, d in enumerate(Dicts): d[v] = Vals[v][i] r.solutions = MOPsolutions(Dicts) r.solutions.coords = S r.solutions.values = Vals else: tmp = [((i, int(r.xf[x[i]])) if requireCount else i) for i in range(n) if r.xf[x[i]] >= 1] if 'name' in items[0]: tmp = [(items[i]['name'], k) for i, k in tmp ] if requireCount else [items[i]['name'] for i in tmp] r.xf = dict(tmp) if requireCount else tmp return r
def solve(self, *args, **kw): import FuncDesigner as fd, openopt as oo 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) KW = self.__init_kwargs.copy() KW.update(kw) items = self.items n = len(items) 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] solverName = solver if type(solver) == str else solver.__name__ is_interalg = solverName == 'interalg' is_glp = False#solverName == 'sa' if is_glp: assert nCriteria == 1, 'you cannot solve multiobjective KSP 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 x = fd.oovars(n, domain=bool) requireCount = False for i, obj in enumerate(items): if 'n' in obj: x[i].domain = np.arange(obj['n']+1) if is_interalg else int x[i].ub = obj['n'] x[i].lb = 0 requireCount = True #cr_values = dict([(obj[0], []) for obj in objective]) constraints = [] 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])) cr_values = {} for val in usedValues: if val == 'nItems': cr_values[val] = 1 else: cr_values[val] = [obj[val] for obj in items] # MainCr = mainCr if type(mainCr) in (str, np.str_) else list(usedValues)[0] # # isMainCrMin = objective[0][2] in ('min', 'minimum') # handling objective(s) FF = [] for optCrName in usedValues: F = fd.sum(x * cr_values[optCrName]) Funcs[optCrName] = F for obj in objective: FF.append((Funcs[obj[0]](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]*n} p = P(FF if isMOP else FF[0][0], startPoint, constraints = constraints)#, fixedVars = fixedVars) if not isMOP: p.goal=self.goal r = p.solve(solver, **KW) if P != oo.MOP: r.ff = p.ff if isMOP: #assert not requireCount, 'MOP with nItem > 1 is unimplemented yet' r.solution = 'for MOP see r.solutions instead of r.solution' #tmp_c, tmp_v = r.solutions.coords, r.solutions.values if len(r.solutions): S = [] for s in r.solutions: tmp = [((i, int(s[x[i]])) if requireCount else i) for i in range(n) if s[x[i]]>=1] if 'name' in items[0]: tmp = [(items[i]['name'], k) for i, k in tmp] if requireCount else [items[i]['name'] for i in tmp] S.append(dict(tmp) if requireCount else tmp) Vals = dict([(ff[0].name, r.solutions.values[:, i]) for i, ff in enumerate(FF)]) Dicts = [s.copy() for s in S] for v in usedValues: if v != 'nItems': for i, d in enumerate(Dicts): d[v] = Vals[v][i] r.solutions = MOPsolutions(Dicts) r.solutions.coords = S r.solutions.values = Vals else: tmp = [((i, int(r.xf[x[i]])) if requireCount else i) for i in range(n) if r.xf[x[i]]>=1] if 'name' in items[0]: tmp = [(items[i]['name'], k) for i, k in tmp] if requireCount else [items[i]['name'] for i in tmp] r.xf = dict(tmp) if requireCount else tmp return r