Пример #1
0
    def sort_dependencies(items):
        """Topologically sort the dependency tree"""

        g = DiGraph()
        log("Sorting dependencies")

        for key, item in items:
            log("key: ", key, "item:", item, pretty=True, lvl=debug)
            dependencies = item.get("dependencies", [])
            if isinstance(dependencies, str):
                dependencies = [dependencies]

            if key not in g:
                g.add_node(key)

            for link in dependencies:
                g.add_edge(key, link)

        if not is_directed_acyclic_graph(g):
            log("Cycles in provisioning dependency graph detected!", lvl=error)
            log("Involved provisions:", list(simple_cycles(g)), lvl=error)

        topology = list(topological_sort(g))
        topology.reverse()
        topology = list(set(topology).difference(installed))

        # log(topology, pretty=True)

        return topology
def get_stations_on_trips_in_order(trip_list):
    # This could easily live on the Line object
    dg = networkx.DiGraph()
    for t in trip_list:
        for s in t.get_segments():
            s.add_as_digraph_edge(dg, ignore_lines=True)

    return topological_sort(dg)
Пример #3
0
def _ancestors_in_topological_sort_order(module_name):
    ancestral_module_names = ancestors(_dependency_graph, module_name)
    subgraph = _dependency_graph.subgraph(ancestral_module_names)
    try:
        sorted_nodes = topological_sort(subgraph)
    except nx.NetworkXUnfeasible as ex:
        try:
            cycle = find_cycle(subgraph)
        except Exception as ex:
            log_error(f'find_cycle: error: {ex.__class__.__name__}({ex})')
        else:
            log_error(f'cycle: {cycle}')
        finally:
            raise
    else:
        return list(reversed(list(sorted_nodes)))
Пример #4
0
def order_dps(name2dp, connections):
    """ Returns a total order consistent with the partial order """
    names = set(name2dp)

    # List the ones that have no functions or no resources

    # a >= 10 g (no functions)
    # b <= 10 s (no resources)

    # #     no_functions = set()
    # #     no_resources = set()
    # #
    # #     for name, ndp in name2dp.items():
    # #         if not ndp.get_fnames():
    # #             no_functions.add(name)
    # #         if not ndp.get_rnames():
    # #             no_resources.add(name)
    #
    #     print('no_functions: %s' % no_functions)
    #     print('no_resources: %s' % no_resources)

    G = get_connection_graph(names, connections)
    # I should probably think more about this
    #     for nf in no_functions:
    #         for nr in no_resources:
    #             G.add_edge(nr, nf)

    Gu = G.to_undirected()
    if not is_connected(Gu):
        msg = 'The graph is not weakly connected. (missing constraints?)'
        msg += '\nNames: %s' % names
        msg += '\nconnections: %s' % connections
        raise DPSemanticError(msg)
    l = list(topological_sort(G))
    if not (set(l) == names):
        msg = 'names = %s\n returned = %s\n connections: %s' % (names, l,
                                                                connections)
        msg += '\n graph: %s %s' % (list(Gu.nodes()), list(Gu.edges()))
        raise DPInternalError(msg)
    return l
Пример #5
0
def order_dps(name2dp, connections):
    """ Returns a total order consistent with the partial order """
    names = set(name2dp)

    # List the ones that have no functions or no resources

    # a >= 10 g (no functions)
    # b <= 10 s (no resources)

# #     no_functions = set()
# #     no_resources = set()
# #
# #     for name, ndp in name2dp.items():
# #         if not ndp.get_fnames():
# #             no_functions.add(name)
# #         if not ndp.get_rnames():
# #             no_resources.add(name)
#
#     print('no_functions: %s' % no_functions)
#     print('no_resources: %s' % no_resources)

    G = get_connection_graph(names, connections)
    # I should probably think more about this
#     for nf in no_functions:
#         for nr in no_resources:
#             G.add_edge(nr, nf)

    Gu = G.to_undirected()
    if not is_connected(Gu):
        msg = 'The graph is not weakly connected. (missing constraints?)'
        msg += '\nNames: %s' % names
        msg += '\nconnections: %s' % connections
        raise DPSemanticError(msg)
    l = topological_sort(G)
    if not (set(l) == names):
        msg = 'names = %s\n returned = %s\n connections: %s' % (names, l, connections)
        msg += '\n graph: %s %s' % (list(Gu.nodes()), list(Gu.edges()))
        raise DPInternalError(msg)
    return l
Пример #6
0
def nearest_drop_map(
    map_width,
    factory_loc,
    dropoff_locs,
    halite_map,
    halite_scale=100.0,
    avoidance_map=None,
    build_return_trees=False,
    ship_ind_arr=None,
):
    """For each tile, provide number of turns to nearest drop + halite cost / halite_scale.

    The Halite cost is to be used to distinguish between routes that are equally long.

    Use BFS.
    """
    locs = [factory_loc] + dropoff_locs
    locs_copy = copy(locs)
    out_arr = np.full_like(halite_map, np.inf)
    locq = deque()
    if build_return_trees:
        import networkx

        # edges go from depos (root to leaf)
        digraph = networkx.DiGraph()
    for loc in locs:
        out_arr[loc[0], loc[1]] = 0
        locq.append(((loc[0], loc[1]), None))
        if build_return_trees:
            digraph.add_node((loc[0], loc[1]))
    del locs
    while locq:
        (loc, parent) = locq.popleft()
        if parent is not None:
            val = (
                out_arr[parent[0], parent[1]]
                + 1
                + int(halite_map[loc[0], loc[1]] / 10) / halite_scale
            )
        if parent is None or (val < out_arr[loc[0], loc[1]]):
            if (
                (avoidance_map is not None)
                and avoidance_map[loc[0], loc[1]]
                and ((loc[0], loc[1]) not in locs_copy)
            ):
                pass
            else:
                for d in [(0, 1), (1, 0), (-1, 0), (0, -1)]:
                    new_loc = ((loc[0] + d[0]) % map_width, (loc[1] + d[1]) % map_width)
                    locq.append((new_loc, loc))
        if parent is not None:
            curr_val = out_arr[loc[0], loc[1]]
            if val < curr_val:
                out_arr[loc[0], loc[1]] = val
                if build_return_trees:
                    digraph.add_edge((parent[0], parent[1]), (loc[0], loc[1]))
            else:
                out_arr[loc[0], loc[1]] = curr_val
    if not build_return_trees:
        return out_arr
    else:
        return_turn_arr = np.full_like(halite_map, hlt.constants.MAX_TURNS)
        depo_nodes = (n for n in digraph.nodes() if digraph.in_degree(n) == 0)
        depo_adj_nodes = []
        for node in depo_nodes:
            successors = digraph.successors(node)
            for successor in successors:
                depo_adj_nodes.append(successor)
        from networkx.algorithms.traversal.depth_first_search import dfs_tree
        from networkx.algorithms import topological_sort

        for node in depo_adj_nodes:
            subtree = dfs_tree(digraph, node)
            root_out = list(topological_sort(subtree))
            i = 0
            for node in reversed(root_out):
                return_turn = hlt.constants.MAX_TURNS - i
                return_turn_arr[node[0], node[1]] = return_turn
                if ship_ind_arr[node[0], node[1]]:
                    i += 1
        return out_arr, return_turn_arr