def add_edge(self, *args, **kwargs): '''Adds an edge between `source` and `dest`. `shared_variables` represents a list of variables, how `source` depends on `dest`. Returns edge object. :param shared_variables: A list of variables. :return: An :class:`Edge` instance. ''' edge = None if len(args) == 1: edge = args[0] if not isinstance(edge, Edge): raise TypeError() else: edge = Edge(*args, **kwargs) nx.DiGraph.add_edge(self, edge.get_source().get_name(), edge.get_dest().get_name(), edge) logging.debug("Add edge between %s and %s with %d shared variable(s)", edge.get_source().get_name(), edge.get_dest().get_name(), edge.get_num_shared_variables()) for node in (self.node[edge.get_source().get_name()], self.node[edge.get_dest().get_name()]): node['shared_variables'] |= edge.get_shared_variables() node['local_variables'] = ( set(node['model'].get_columns_names()) - set(node['shared_variables'])) return edge
def check_params(self, params): if not isinstance(params, dict): raise TypeError() if params['num_blocks'] and max(params['num_constraints']) < max(params['num_blocks']): logging.debug('Number of constraints cannot be less that number of blocks: %d < %d' \ % (max(params['num_constraints']), max(params['num_blocks']))) return False return True
def _process_decomposition_tree(self, tree): # TODO(d2rk): merge nodes if necessary. for node in tree.get_nodes(): if node.get_num_shared_variables() > self._driver_params.max_num_shared_variables: logging.debug('Node %s has too many shared variables: %d > %d', node.get_name(), node.get_num_shared_variables(), self._driver_params.max_num_shared_variables) return False return True
def execute(self, sql, *args): '''Replaces :func:`execute` with a logging variant.''' if args: parameters = [] for arg in args: if isinstance(arg, buffer): parameters.append('<blob>') else: parameters.append(repr(arg)) logging.debug('SQL Execute: %s - \n %s', sql, '\n '.join(str(param) for param in parameters)) else: logging.debug(sql) return super(SQLiteCursorWrapper, self).execute(sql, *args)
def build_from_scratch(cls, objective_coefficients, constraints_coefficients, constraints_senses, constraints_rhs, constraints_names=[], variables_lower_bounds=[], variables_upper_bounds=[], variables_names=[]): """Builds model from a scratch. The following code snippet shows how to define two models from scratch, where the first model needs to be maximized and the second one -- minimized:: MPModelBuilder.build_from_scratch([1, 1, 2], [[1, 2, 3], ['L', 'L'], [1, 1]]) MPModelBuilder.build_from_scratch(([1, 1, 2], False), [[1, 2, 3], ['L', 'L'], [1, 1]]) :param objective_coefficients: This parameter can be represented either a list of objective function variable coefficients, or a tuple, where the first element is a list of coefficients and the second one is ``True`` or ``False``, that defines objective function maximization or minimization. By default does maximization (see :func:`set_objective`). :param constraints_coefficients: Left-hand side or constraint matrix. :param constraints_senses: A list of senses of the constraints. :param constraints_rhs: A list of rhs bounds. :param constraints_names: A list of constraints names. :param variables_lower_bounds: A list of variables lower bounds. :param variables_upper_bounds: A list of variables upper bounds. :param variables_names: A list of variables names, where each name represented by a string. :returns: A :class:`MPModel` instance. :raises: :exc:`TypeError` """ logging.debug('Build new model from scratch') if not bool(len(variables_names)): variables_names = [] for i in range(1, len(objective_coefficients) + 1): variables_names.append(cls.VARIABLE_NAME_FORMAT.format(index=i)) if not bool(len(variables_lower_bounds)): variables_lower_bounds = [0.0] * len(objective_coefficients) if not bool(len(variables_upper_bounds)): variables_upper_bounds = [1.0] * len(objective_coefficients) if not bool(len(constraints_names)): constraints_names = [] for i in range(1, len(constraints_senses) + 1): constraints_names.append(cls.CONSTRAINT_NAME_FORMAT.format(index=i)) return (mp_model.MPModel() .set_columns(variables_lower_bounds, variables_upper_bounds, variables_names) .set_objective(objective_coefficients) .set_rows(constraints_coefficients, constraints_senses, constraints_rhs, constraints_names))
def decompose(self): self._decomposition_tree = decomposition_tree.DecompositionTree(self._model) igraph = interaction_graph.InteractionGraph(self.get_model()) cliques = list(map(set, networkx.find_cliques(igraph))) logging.debug("%d clique(s) were found." % len(cliques)) submodels_cache = [] for i, clique in enumerate(cliques): submodel = self._build_submodel(clique) self._decomposition_tree.add_node(submodel) submodels_cache.append(submodel) for j, other_clique in enumerate(cliques[:i]): other_submodel = submodels_cache[j] shared_cols_scope = clique & other_clique if shared_cols_scope: self._decomposition_tree.add_edge(submodel, other_submodel, shared_cols_scope) self._decomposition_tree.set_root(submodels_cache[-1])
def execute(self, request): model = request.get_model() logging.debug('Solve model %s that has %d row(s) and %d column(s)' ' with solver %s', model.get_name(), model.get_num_rows(), model.get_num_columns(), request.get_solver_id()) solver = backend_solvers.get_instance_of(request.get_solver_id()) if not solver: raise Error("Cannot instantiate backend solver by id: %d" % request.get_solver_id()) try: solver.load_model(model) solver.solve() except Error, e: # TODO: send back a report. logging.exception("Cannot execute given request: cannot solve the model.") return None
def set_root(self, root): logging.debug("Set %s as root node." % root.get_name()) self._root = root
def _remove_node(self, node): logging.debug('Remove node %s', node.get_name()) nodes = self._dtree_traversal.mark_node_as_visited(node) for node in nodes: self._add_node(node)
def _add_node(self, node): logging.debug('Add node %s', node.get_name()) enumerator = shared_variables_enumerator.SharedVariablesEnumerator( node.get_model(), node.get_shared_variables(), node.get_local_variables()) self._enumerators[node] = enumerator self._unsolved_models_counter[node] = 0
def process_response(self, response): cxt = self._frozen_contexts.pop(response.get_id()) solution = response.get_solution() logging.debug("Process %s solution produced by %d with status %d", response.get_id(), cxt.solver_id_stack[0], solution.get_status()) cxt.solver_id_stack.pop(0) # Check F3: whether optimal solution has been found. if (not solution.get_status() is mp_solution.MPSolution.NOT_SOLVED and not solution.get_variables_values() is None): if ((sum(solution.get_variables_values().tolist()) % 1.0) == 0 and solution.is_optimal()): objective_value = solution.get_objective_value() # Check F2: do we need to continue? # NOTE: the best objective value will be checked inside of # set_best_objective_value(). if cxt.set_best_objective_value(objective_value): logging.debug('Model %s has a new best objective value: %f', response.get_id(), objective_value) cxt.partial_solution.update_variables_values(solution) cxt.partial_solution.set_objective_value(objective_value) logging.debug('Write %s solution to the table.', response.get_id()) self._solution_table.write_solution(cxt.submodel, cxt.partial_solution) else: logging.debug("Solution is rejected: not the best objective value" ": %f <= %f", objective_value, cxt.best_objective_value) else: logging.debug("Solution is rejected: " "not optimal or fractional solution.") else: logging.debug("Solution is rejected: model wasn't solved.") if len(cxt.solver_id_stack) == 0: self._search_tree.mark_model_as_solved(cxt.candidate_model) else: self._active_contexts[cxt.candidate_model.get_name()] = cxt
def executescript(self, sql): '''Replaces :func:`executescript` with a logging variant.''' logging.debug('SQL ExecuteScript: %s', sql) return super(SQLiteCursorWrapper, self).executescript(sql)
def executemany(self, sql, seq_parameters): '''Replaces executemany() with a logging variant.''' seq_params_list = list(seq_parameters) logging.debug('SQL ExecuteMany: %s - \n %s', sql, '\n '.join(str(param) for param in seq_params_list)) return super(SQLiteCursorWrapper, self).executemany(sql, seq_params_list)