示例#1
0
    def _general_circle_elimination(self, model: grb.Model):
        # Calculate the adjacency matrix for the solution
        # ToDo: ^ this
        edges_solution = model.cbGetSolution(self.edges)
        ad_matrix = np.zeros(self.abstract_graph.ad_matrix.shape)
        for u, v in edges_solution:
            ad_matrix[u, v] = edges_solution[(u, v)]
        if max(np.triu(ad_matrix)) == 0 or max(np.tril(ad_matrix)) == 0:
            ad_matrix = ad_matrix + ad_matrix.T
        to_calc = {0}

        processed = {}
        while to_calc:
            i = to_calc.pop()
            non_zero = ad_matrix[i].nonzero()
            for j in non_zero:
                if j in to_calc or j in processed:
                    # Found a circle: ELIMINATE
                    # ToDo: implement elimination constraint
                    pass
                to_calc.add(j)
        if len(processed) < len(self.abstract_graph.vertices):
            # The processed vertices itself are a subtour/circle
            pass

        pass  #ToDo: circle elimination
    def _subtour_elimination(self, model: gurobipy.Model):
        #nodecnt = model.cbGet(gurobipy.GRB.Callback.MIPSOL_NODCNT)
        #obj = model.cbGet(gurobipy.GRB.Callback.MIPSOL_OBJ)
        #solcnt = model.cbGet(gurobipy.GRB.Callback.MIPSOL_SOLCNT)
        #solution = model.cbGetSolution(self.edges)
        # for every subsolution, try to find shortcuts
        for base_vertex_index, edges in self.edges.items():
            edge_solution = model.cbGetSolution(edges)
            used_edges = {
                key: edge_solution[key]
                for key in edge_solution if edge_solution[key] > 0.1
            }
            ad_vert = {key[1]: key for key in used_edges}
            visited = set()
            all_ad_vert = {key[1]: key for key in edge_solution}
            vertices_amount = len(all_ad_vert)

            while len(visited) < vertices_amount:
                current_vertices = []
                vertex, edge_key = self._get_start_vertex(used_edges, visited)
                while vertex not in visited:
                    visited.add(vertex)
                    current_vertices.append(vertex)
                    vertex = edge_key[2]
                    try:
                        edge_key = ad_vert[vertex]
                    except KeyError:
                        # Should only happen if we get to an end of a path
                        # Therefore, just add them to also mark them as visited
                        visited.add(vertex)
                        current_vertices.append(vertex)
                # Found a subtour, need to eliminate it
                if len(current_vertices) < vertices_amount:
                    not_current_vertices = [
                        i for i in all_ad_vert if i not in current_vertices
                    ]
                    model.cbLazy(
                        edges.sum(base_vertex_index, current_vertices,
                                  not_current_vertices) +
                        edges.sum(base_vertex_index, not_current_vertices,
                                  current_vertices) >= 1)
                    print("Subtour found for point", base_vertex_index,
                          "with vertices", current_vertices)
示例#3
0
    def _general_circle_elimination(self, model: grb.Model):
        edges_solution = model.cbGetSolution(self.edges)
        used_edges = grb.tupledict({key: edges_solution[key] for key in edges_solution if not math.isclose(0, edges_solution[key], abs_tol=10**-5)})
        for edge in used_edges:
            if used_edges[edge] < 0.7:
                print("Found an edge with value less than 0.7")
        
        self._check_for_cycle(used_edges, model)
        return
        # Turn used_edges into a dependency graph
        dep_graph = self._get_dep_graph(used_edges)

        try:
            calculate_order(dep_graph, calculate_circle_dep=True)
        except CircularDependencyException as dep_exception:
            self._add_cycle_constr(dep_exception.circle_nodes, model)
        # For now we try to ignore this disconnected graphs
        except DisconnectedDependencyGraphException as disc_exception:
            cycle = calculate_cycle(disc_exception.disconnected_nodes)
            self._add_cycle_constr(cycle, model)