Пример #1
0
def __find_mst(graph):
    graph = -1 * graph
    graph = np.transpose(graph)

    G = nx.DiGraph(graph)
    try:
        MSA = nx.minimum_spanning_arborescence(G)
    except nx.exception.NetworkXException:
        # If a node with no head exists, hack it into a node with uniform dist:
        ng = np.array(graph - 0.0001)
        MSA = nx.minimum_spanning_arborescence(nx.DiGraph(ng))

    return nx.adjacency_matrix(MSA).todense().transpose() * (-1)
Пример #2
0
def __find_mst(graph):
    graph = -1*graph
    graph = np.transpose(graph)

    G = nx.DiGraph(graph)
    try:
        MSA = nx.minimum_spanning_arborescence(G)
    except nx.exception.NetworkXException:
        # If a node with no head exists, hack it into a node with uniform dist:
        ng = np.array(graph - 0.0001)
        MSA = nx.minimum_spanning_arborescence(nx.DiGraph(ng))
        
    return nx.adjacency_matrix(MSA).todense().transpose()*(-1)
Пример #3
0
def draw_mst(user_id, source=()):
    if user_id not in graphs:
        return "У вас еще нет графа"
    if not weighted[user_id]:
        return "У вас невзвешенный граф"
    if isinstance(graphs[user_id], nx.DiGraph):
        if len(source) != 1:
            return "Вы ввели некорректные данные. Обратитесь к команде help"
        source = source[0]
        graphs[user_id].add_node('Extra_node_for_algo')
        graphs[user_id].add_edge('Extra_node_for_algo', source, weight=-1)
        t = nx.minimum_spanning_arborescence(graphs[user_id], attr='weight')
        t.remove_node('Extra_node_for_algo')
        graphs[user_id].remove_node('Extra_node_for_algo')
    else:
        t = nx.minimum_spanning_tree(graphs[user_id])
    edges = ""
    for edge in t.edges:
        edges += "{} {} {}\n".format(edge[0], edge[1],
                                     t[edge[0]][edge[1]]['weight'])
    pos = nx.spring_layout(t)
    nx.draw(t, pos)
    nx.draw_networkx_labels(t, pos)
    weights = nx.get_edge_attributes(t, 'weight')
    nx.draw_networkx_edge_labels(t, pos, edge_labels=weights)
    plt.savefig('temp.png', dpi=300)
    plt.close()
    return "OK"
Пример #4
0
    def treeConverter(self):

        # getting root
        root = [
            n for n in self.Graph.nodes()
            if len(list(self.Graph.predecessors(n))) == 0
        ][0]

        self.root = root

        is_treee = nx.is_tree(self.Graph)
        is_arb = nx.is_arborescence(self.Graph)

        if not is_arb:
            logging.info(
                "Arborescence is not possible due to in-bound and out-bound edges. Therefore converting to tree using BFS."
            )
            self.DAG2Tree()
        else:
            logging.info("Converting dag to tree")
            arb_graph = nx.minimum_spanning_arborescence(self.Graph)
            if nx.is_tree(arb_graph):
                logging.info(
                    "Converted to tree! But some information is lost...")
                nx.write_edgelist(arb_graph, self.edgelist_file)
                self.removeParantheses(self.edgelist_file)
                nx.write_graphml(arb_graph, self.gml_file)
                self.Graph = arb_graph
Пример #5
0
def vecMat2tree(word_mat,
                indKeys,
                treeType='TRmsa',
                treeThresh=20,
                simType='cos',
                focusRank=3):
    '''
        description:
            - given embeddings matrix, treeType and simType, builds and returns networkx tree object
        params: 
            - word_mat: embeddings matrix (VOCABxNDIMS)
            - indKeys: index to word mapping (dict)
            - treeType:
                - 'msa': maximum spanning arboroscence
                - 'Rmsa': rank minimum spanning arboroscence
                - 'TRmsa': transpose rank minimum spanning arboroscence
                - 'FRmsa': flipped rank minimum spanning arboroscence (see flipMatrix() for more info)
            - treeThresh: (relevant) edge weight threshold for adjacency matrix
            - simType:
                - 'cos': cosine similarity
                - 'xor': xor similarity (weights must be discretized)
            focusRank: pivot for flipped Rmsa (only applicable if treeType == 'FRmsa')
        returns:
            - tree: networkx graph object
    '''
    argMax = False
    sim_mat, temp_mat = None, None

    if simType == 'cos':
        sim_mat = cos_similarity(word_mat)
    elif simType == 'xor':
        sim_mat = xor_similarity(word_mat)
    elif simType == 'kl':
        sim_mat = kl_similarity(word_mat)

    if treeType == 'msa':
        argMax = True  # maximize similarity edge weight in arboroscence
        temp_mat = sim_mat.copy()
    elif treeType == 'Rmsa':
        rank_mat = rankMatrix(sim_mat)
        temp_mat = rank_mat.copy()
    elif treeType == 'TRmsa':
        rank_mat = rankMatrix(sim_mat)
        temp_mat = rank_mat.T.copy()
    elif treeType == 'FRmsa':
        rank_mat = rankMatrix(sim_mat)
        flipped_rank_mat = flipMatrix(rank_mat, focusRank=focusRank)
        temp_mat = flipped_rank_mat.copy()

    adj_mat = buildAdjMat(temp_mat,
                          thresh=20,
                          mode='abs',
                          reverse=(not argMax))
    g = nx.convert_matrix.from_numpy_array(adj_mat, create_using=nx.DiGraph)
    tree = nx.minimum_spanning_arborescence(g)
    tree = nx.relabel_nodes(tree, indKeys)

    return tree
Пример #6
0
def MinimumArborescence(G):
    B = nx.minimum_spanning_arborescence(G, attr="inv_lcprob")
    for edge in B.edges():
        if edge in G.edges():
            for key in G.edges()[edge]:
                B.edges()[edge][key] = G.edges()[edge][key]
    for node in B.nodes():
        if node in G.nodes():
            for key in G.nodes()[node]:
                B.nodes()[node][key] = G.nodes()[node][key]
    return B
Пример #7
0
    def compute_k_edge_disjoint_aborescenes(self, k, bridge_dict):

        k_ada = []

        mdg = nx.MultiDiGraph(self.network_configuration.graph)

        for node_id in self.network_configuration.graph:
            node_type = self.network_configuration.get_node_type(node_id)

            # Remove all host nodes
            if node_type == "host":
                mdg.remove_node(node_id)

        dst_br_preds = list(mdg.predecessors(bridge_dict["bridge_name"]))
        dst_br_succs = list(mdg.successors(bridge_dict["bridge_name"]))

        # Remove the predecessor edges to dst_br, to make it the "root"
        for pred in dst_br_preds:
            mdg.remove_edge(pred, bridge_dict["bridge_name"])

        # Initially, remove all successors edges of dst_br as well
        for succ in dst_br_succs:
            mdg.remove_edge(bridge_dict["bridge_name"], succ)

        for i in range(k):

            # Assume there are always k edges as the successor of the dst_br, kill all but one
            for j in range(k):
                if i == j:
                    mdg.add_edge(bridge_dict["bridge_name"], dst_br_succs[j])
                else:
                    if mdg.has_edge(bridge_dict["bridge_name"],
                                    dst_br_succs[j]):
                        mdg.remove_edge(bridge_dict["bridge_name"],
                                        dst_br_succs[j])

            # Compute and store one
            msa = nx.minimum_spanning_arborescence(mdg)
            k_ada.append(msa)

            # If there are predecessors of dst_br now, we could not find k msa, so break
            if len(list(msa.predecessors(bridge_dict["bridge_name"]))) > 0:
                print "Could not find k msa."
                break

            # Remove its arcs from mdg
            for arc in msa.edges():
                mdg.remove_edge(arc[0], arc[1])

        return k_ada
Пример #8
0
def graph_minimum_spanning_arborescence(output_directory, is_trial, graphs,
                                        adjacency_matrices, widget,
                                        properties_dict):
    output_directory = os.path.join(output_directory,
                                    'MaximumSpanningArborescence')
    if not os.path.exists(output_directory):
        os.makedirs(output_directory)

    log_file = os.path.join(output_directory,
                            'MaximumSpanningArborescence.txt')

    msa_list = []
    for window, graph in enumerate(graphs):
        msa_graph = nx.minimum_spanning_arborescence(graph)

        msa_list.append(msa_graph.edges())

        count = 0
        weight = 0

        for edge in msa_graph.edges():
            node_index_1 = 0
            node_index_2 = 0

            for key in list(CHANNELS_DICT.keys()):
                if CHANNELS_DICT[key] == edge[0]:
                    node_index_1 = key
                    break

            for key in list(CHANNELS_DICT.keys()):
                if CHANNELS_DICT[key] == edge[1]:
                    node_index_2 = key
                    break

            weight += adjacency_matrices[window][node_index_1][node_index_2]
            count += 1

        if not is_trial:
            log(f'Window {window}', file=log_file)
        log(f'\t Weight: {weight}', file=log_file)
        log(f'\t Weight average: {weight / (count * 1.0)}', file=log_file)

        if not is_trial:
            properties_dict[window][MSA_WEIGHT] = weight
        else:
            properties_dict[MSA_WEIGHT] = weight

    with open(os.path.join(output_directory, 'MSAList.bin'), 'wb+') as f:
        pickle.dump(msa_list, f)
Пример #9
0
    def compute_k_edge_disjoint_aborescenes(self, dst_sw):

        k_eda = []

        mdg = self.get_mdg()

        dst_sw_preds = sorted(list(mdg.predecessors(dst_sw.node_id)))
        dst_sw_succs = sorted(list(mdg.successors(dst_sw.node_id)))

        # Remove the predecessor edges to dst_sw, to make it the "root"
        for pred in dst_sw_preds:
            mdg.remove_edge(pred, dst_sw.node_id)

        # Initially, remove all successors edges of dst_sw as well
        for succ in dst_sw_succs:
            mdg.remove_edge(dst_sw.node_id, succ)

        for i in range(self.params["k"]):

            # Assume there are always k edges as the successor of the dst_sw
            for j in range(self.params["k"]):
                if i == j:
                    mdg.add_edge(dst_sw.node_id, dst_sw_succs[j], weight=1)
                else:
                    if mdg.has_edge(dst_sw.node_id, dst_sw_succs[j]):
                        mdg.remove_edge(dst_sw.node_id, dst_sw_succs[j])

            # Compute and store one
            msa = nx.minimum_spanning_arborescence(mdg)
            k_eda.append(msa)

            # If there are predecessors of dst_sw now, we could not find k msa, so break
            if len(list(msa.predecessors(dst_sw.node_id))) > 0:
                print "Could not find k msa."
                break

            # Remove its arcs from mdg to ensure that these arcs are not part of any future msa
            for arc in msa.edges():
                mdg.remove_edge(arc[0], arc[1])

                if arc[0] != dst_sw.node_id and arc[1] != dst_sw.node_id:
                    if mdg.has_edge(arc[1], arc[0]):
                        prev_weight = mdg[arc[1]][arc[0]][0]['weight']
                        mdg.remove_edge(arc[1], arc[0])
                        mdg.add_edge(arc[1], arc[0], weight=prev_weight+100)

        return k_eda
def steiner_tree_region_mst(g,
                            root,
                            infection_times,
                            source,
                            terminals,
                            return_closure=False,
                            debug=False):
    regions = connect_adjacent_infections(g, terminals, infection_times)

    gc, eweight, orginal_edge_info = build_region_closure(
        g, root, regions, infection_times, terminals)

    root = gc.num_vertices() - 1  # last node is root
    gx = gt2nx(gc,
               root,
               list(map(int, gc.vertices())),
               edge_attrs={'weight': eweight})
    try:
        nx_tree = nx.minimum_spanning_arborescence(gx, 'weight')
    except nx.NetworkXException:
        # cannot find any MST
        return None

    # now we reconstruct the super node tree to the original tree
    orig_edges = []
    for i, j in nx_tree.edges():
        einfo = orginal_edge_info[(i, j)]
        u, v = einfo['original_edge']
        pred = einfo['pred']
        c = u
        while c != v and pred[c] != -1:
            orig_edges.append((c, pred[c]))
            c = pred[c]

    efilt = g.new_edge_property('bool')
    efilt.a = False

    all_edges = [e for r in regions.values() for e in r['edges']]
    all_edges += orig_edges

    steiner_tree = edges2graph(g, all_edges)
    ret = steiner_tree
    if return_closure:
        region_graph = edges2graph(
            g, [e for r in regions.values() for e in r['edges']])
        ret = (ret, gc, region_graph)
    return ret
Пример #11
0
    def compute_k_edge_disjoint_aborescenes(self, k, dst_sw):

        k_eda = []

        mdg = self.network_graph.get_mdg()

        dst_sw_preds = list(mdg.predecessors(dst_sw.node_id))
        dst_sw_succs = list(mdg.successors(dst_sw.node_id))

        # Remove the predecessor edges to dst_sw, to make it the "root"
        for pred in dst_sw_preds:
            mdg.remove_edge(pred, dst_sw.node_id)

        # Initially, remove all successors edges of dst_sw as well
        for succ in dst_sw_succs:
            mdg.remove_edge(dst_sw.node_id, succ)

        for i in range(k):

            # Assume there are always k edges as the successor of the dst_sw, kill all but one
            for j in range(k):
                if i == j:
                    mdg.add_edge(dst_sw.node_id, dst_sw_succs[j])
                else:
                    if mdg.has_edge(dst_sw.node_id, dst_sw_succs[j]):
                        mdg.remove_edge(dst_sw.node_id, dst_sw_succs[j])

            # Compute and store one
            msa = nx.minimum_spanning_arborescence(mdg)
            k_eda.append(msa)

            # If there are predecessors of dst_sw now, we could not find k msa, so break
            if len(list(msa.predecessors(dst_sw.node_id))) > 0:
                print "Could not find k msa."
                break

            # Remove its arcs from mdg
            for arc in msa.edges():
                mdg.remove_edge(arc[0], arc[1])

        return k_eda
Пример #12
0
def _minimum_rooted_branching(D, root):
    """Computes minimum rooted branching (aka rooted arborescence)

    Before the branching can be computed, the directed graph must be rooted by
    removing the predecessors of root.

    A branching / arborescence of rooted graph G is a subgraph that contains a
    directed path from the root to every other vertex. It is the directed
    analog of the minimum spanning tree problem.

    References
    ----------
    [1] Khuller, Samir (2002) Advanced Algorithms Lecture 24 Notes.
    https://www.cs.umd.edu/class/spring2011/cmsc651/lec07.pdf
    """
    rooted = D.copy()
    # root the graph by removing all predecessors to `root`.
    rooted.remove_edges_from([(u, root) for u in D.predecessors(root)])
    # Then compute the branching / arborescence.
    A = nx.minimum_spanning_arborescence(rooted)
    return A
Пример #13
0
def mst(user_id, source=()):
    if user_id not in graphs:
        return "У вас еще нет графа"
    if not weighted[user_id]:
        return "У вас невзвешенный граф"
    if isinstance(graphs[user_id], nx.DiGraph):
        if len(source) != 1:
            return "Вы ввели некорректные данные. Обратитесь к команде help"
        source = source[0]
        graphs[user_id].add_node('Extra_node_for_algo')
        graphs[user_id].add_edge('Extra_node_for_algo', source, weight=-1)
        t = nx.minimum_spanning_arborescence(graphs[user_id], attr='weight')
        t.remove_node('Extra_node_for_algo')
        graphs[user_id].remove_node('Extra_node_for_algo')
    else:
        t = nx.minimum_spanning_tree(graphs[user_id])
    edges = ""
    for edge in t.edges:
        edges += "{} {} {}\n".format(edge[0], edge[1],
                                     t[edge[0]][edge[1]]['weight'])
    return edges
Пример #14
0
def _minimum_rooted_branching(D, root):
    """Helper function to compute a minimum rooted branching (aka rooted
    arborescence)

    Before the branching can be computed, the directed graph must be rooted by
    removing the predecessors of root.

    A branching / arborescence of rooted graph G is a subgraph that contains a
    directed path from the root to every other vertex. It is the directed
    analog of the minimum spanning tree problem.

    References
    ----------
    [1] Khuller, Samir (2002) Advanced Algorithms Lecture 24 Notes.
    https://www.cs.umd.edu/class/spring2011/cmsc651/lec07.pdf
    """
    rooted = D.copy()
    # root the graph by removing all predecessors to `root`.
    rooted.remove_edges_from([(u, root) for u in D.predecessors(root)])
    # Then compute the branching / arborescence.
    A = nx.minimum_spanning_arborescence(rooted)
    return A
def steiner_tree_region_mst(g, root, infection_times, source, terminals, return_closure=False, debug=False):
    regions = connect_adjacent_infections(g, terminals, infection_times)

    gc, eweight, orginal_edge_info = build_region_closure(
        g, root, regions,
        infection_times, terminals)
    
    root = gc.num_vertices() - 1  # last node is root
    gx = gt2nx(gc, root, list(map(int, gc.vertices())), edge_attrs={'weight': eweight})
    try:
        nx_tree = nx.minimum_spanning_arborescence(gx, 'weight')
    except nx.NetworkXException:
        # cannot find any MST
        return None

    # now we reconstruct the super node tree to the original tree
    orig_edges = []
    for i, j in nx_tree.edges():
        einfo = orginal_edge_info[(i, j)]
        u, v = einfo['original_edge']
        pred = einfo['pred']
        c = u
        while c != v and pred[c] != -1:
            orig_edges.append((c, pred[c]))
            c = pred[c]

    efilt = g.new_edge_property('bool')
    efilt.a = False
    
    all_edges = [e for r in regions.values() for e in r['edges']]
    all_edges += orig_edges

    steiner_tree = edges2graph(g, all_edges)
    ret = steiner_tree
    if return_closure:
        region_graph = edges2graph(g, [e for r in regions.values() for e in r['edges']])
        ret = (ret, gc, region_graph)
    return ret
def steiner_tree_mst(g, root, infection_times, source, terminals,
                     closure_builder=build_closure,
                     strictly_smaller=True,
                     return_closure=False,
                     k=-1,
                     debug=False,
                     verbose=True):
    gc, eweight, r2pred = closure_builder(g, root, terminals,
                                          infection_times,
                                          strictly_smaller=strictly_smaller,
                                          k=k,
                                          debug=debug,
                                          verbose=verbose)

    # get the minimum spanning arborescence
    # graph_tool does not provide minimum_spanning_arborescence
    if verbose:
        print('getting mst')
    gx = gt2nx(gc, root, terminals, edge_attrs={'weight': eweight})
    try:
        nx_tree = nx.minimum_spanning_arborescence(gx, 'weight')
    except nx.exception.NetworkXException:
        if debug:
            print('fail to find mst')
        if return_closure:
            return None, gc, None
        else:
            return None

    if verbose:
        print('returning tree')

    mst_tree = Graph(directed=True)
    for _ in range(g.num_vertices()):
        mst_tree.add_vertex()

    for u, v in nx_tree.edges():
        mst_tree.add_edge(u, v)

    if verbose:
        print('extract edges from original graph')

    # extract the edges from the original graph

    # sort observations by time
    # and also topological order
    topological_index = {}
    for i, e in enumerate(bfs_iterator(mst_tree, source=root)):
        topological_index[int(e.target())] = i
    sorted_obs = sorted(
        set(terminals) - {root},
        key=lambda o: (infection_times[o], topological_index[o]))

    tree_nodes = {root}
    tree_edges = set()
    # print('root', root)
    for u in sorted_obs:
        if u in tree_nodes:
            if debug:
                print('{} covered already'.format(u))
            continue
        # print(u)
        v, u = map(int, next(mst_tree.vertex(u).in_edges()))  # v is ancestor
        tree_nodes.add(v)

        late_nodes = [n for n in terminals if infection_times[n] > infection_times[u]]
        vis = init_visitor(g, u)
        # from child to any tree node, including v

        cpbfs_search(g, source=u, terminals=list(tree_nodes),
                     forbidden_nodes=late_nodes,
                     visitor=vis,
                     count_threshold=1)
        # dist, pred = shortest_distance(g, source=u, pred_map=True)
        node_set = {v for v, d in vis.dist.items() if d > 0}
        reachable_tree_nodes = node_set.intersection(tree_nodes)
        ancestor = min(reachable_tree_nodes, key=vis.dist.__getitem__)

        edges = extract_edges_from_pred(g, u, ancestor, vis.pred)
        edges = {(j, i) for i, j in edges}  # need to reverse it
        if debug:
            print('tree_nodes', tree_nodes)
            print('connecting {} to {}'.format(v, u))
            print('using ancestor {}'.format(ancestor))
            print('adding edges {}'.format(edges))
        tree_nodes |= {u for e in edges for u in e}

        tree_edges |= edges

    t = Graph(directed=True)
    for _ in range(g.num_vertices()):
        t.add_vertex()

    for u, v in tree_edges:
        t.add_edge(t.vertex(u), t.vertex(v))

    tree_nodes = {u for e in tree_edges for u in e}
    vfilt = t.new_vertex_property('bool')
    vfilt.a = False
    for v in tree_nodes:
        vfilt[t.vertex(v)] = True

    t.set_vertex_filter(vfilt)

    if return_closure:
        return t, gc, mst_tree
    else:
        return t
Пример #17
0
    def _asymmetric(dist, weight, **params):
        def get_shortcut(dist, weight, cutoff=20):
            if dist.shape[0] < 3000:
                cutoff = 1
            elif dist.shape[0] < 10000:
                cutoff = 5
            elif dist.shape[0] < 30000:
                cutoff = 10
            link = np.array(np.where(dist < (cutoff + 1)))
            link = link.T[weight[link[0]] < weight[link[1]]].T
            link = np.vstack(
                [link, dist[tuple(link.tolist())] + weight[link[0]]])
            link = link.T[np.lexsort(link)]
            return link[np.unique(link.T[1], return_index=True)[1]].astype(int)

        try:
            presence = np.arange(weight.shape[0])
            shortcuts = get_shortcut(dist, weight)
            for (s, t, d) in shortcuts:
                dist[s, dist[s] > dist[t]] = dist[t, dist[s] > dist[t]]
            presence[shortcuts.T[1]] = -1
            dist = dist.T[presence >= 0].T[presence >= 0]
            presence = presence[presence >= 0]
            weight2 = weight[presence]
            dist = np.round(dist, 0) + weight2.reshape([weight2.size, -1])
            np.fill_diagonal(dist, 0.0)

            dist_file = params['tempfix'] + '.dist.list'
            with open(dist_file, 'w') as fout:
                for d in dist:
                    fout.write('{0}\n'.format('\t'.join([
                        '{0:.5f}'.format(dd) for dd in (d + (1. - 0.000005))
                    ])))
            del dist, d
            mstree = Popen([params['edmonds_' + platform.system()], dist_file],
                           stdout=PIPE).communicate()[0]
            os.unlink(dist_file)
            if isinstance(mstree, bytes):
                mstree = mstree.decode('utf8')
            mstree = np.array(
                [br.strip().split() for br in mstree.strip().split('\n')],
                dtype=float).astype(int)
            assert mstree.size > 0
            mstree.T[2] -= 1
            mstree.T[:2] = presence[mstree.T[:2]]
            return mstree.tolist() + shortcuts.tolist()
        except:
            try:
                os.unlink(dist_file)
            except:
                pass
            dist = np.load(params['dist_file'])
            dist = np.round(dist, 0) + weight.reshape([weight.size, -1])
            np.fill_diagonal(dist, 0.0)

            presence = np.arange(weight.shape[0])
            shortcuts = get_shortcut(dist, weight)
            for (s, t, d) in shortcuts:
                dist[s, dist[s] > dist[t]] = dist[t, dist[s] > dist[t]]
                presence[t] = -1
            dist = dist.T[presence >= 0].T[presence >= 0]
            presence = presence[presence >= 0]

            g = nx.DiGraph(dist)
            ms = nx.minimum_spanning_arborescence(g)
            return [[presence[d[0]], presence[d[1]],
                     int(d[2]['weight'])]
                    for d in ms.edges(data=True)] + shortcuts.tolist()
Пример #18
0
    # msa = nx.relabel_nodes(msa,ind_keys)
    # dot = to_pydot(msa)
    # write_dot(msa,"Tmsa.dot")

    # print(rank_mat)

    # TRMSA or RMSA
    # temp_mat = rank_mat.copy()  # RMSA
    temp_mat = np.transpose(rank_mat.copy())  # TRMSA
    # 'seed' is the MAXIMUM edge rank allowed in the msa
    adj_mat = am.build(temp_mat, seed=20, mode='absolute',
                       reverse=True)  # Remove transpose for Rmsa
    g = nx.convert_matrix.from_numpy_array(adj_mat, create_using=nx.DiGraph)
    print("Graph made")

    Rmsa = nx.minimum_spanning_arborescence(g)
    Rmsa = nx.relabel_nodes(Rmsa, ind_keys)
    dot = to_pydot(Rmsa)
    write_dot(Rmsa, "TRmsa_nouns.dot")

    # The CSV Bit
    # import csv  # Saving the edgelist as csv ; For Poincare implementation
    # csv_columns = ['id1','id2','weight']
    # dict_data = list()
    # for u in Rmsa:
    #     for v in Rmsa[u]:
    #         dict_data.append({'id1':u, 'id2':v, 'weight':1})
    # csv_file = "TRmsa_nouns.csv"
    # try:
    #     with open(csv_file, 'w') as csvfile:
    #         writer = csv.DictWriter(csvfile, fieldnames=csv_columns)
Пример #19
0
def demo_TRmsa(fpath='/home/kvaditya/GitHubRepos/wiki-news-300d-nouns.txt',
               pipeline='short'):
    '''
        description:
            - demo function to generate TRmsa tree from given embedding file
        params: 
            - fapth: path to embedding file
            - pipeline:
                - 'short': implement using prebuilt main functions
                - 'long': implement using utility functions
                *NOTE: both methods furnish same results
        returns:
            None
    '''
    if pipeline == 'short':  # using prebuilt main functions

        print('building demo TRmsa using short pipeline')
        vecMat, indKeys, wordKeys = vecFile2vecMat(fpath,
                                                   norm=True,
                                                   disc=False)
        tree = vecMat2tree(vecMat,
                           indKeys,
                           treeType='TRmsa',
                           treeThresh=20,
                           simType='cos')
        saveTreeDot(tree, fpath='demo_TRmsa.dot')
        dot2png(dotPath='demo_TRmsa.dot')

        print('process complete')

    elif pipeline == 'long':  # using utility functions

        print('building demo TRmsa using long pipeline')

        if not path.exists(embFile):
            print('error: path does not exist')
            return None
        if not path.isfile(embFile):
            print('error: path not a file')
            return None
        else:

            # step_1) loading embeddings and generating embedding matrix & index-word mappings for the matrix
            emb = load_embedding(embFile, VOCAB=100, typ='w2v')
            indKeys, wordKeys, word_mat = buildWordMat(emb)
            word_mat = normalize(word_mat, axis=0)
            # word_mat = discretize(word_mat, axis=0)  # uncomment to enable discretization

            #step_2) building similarity matrix
            sim_mat = cos_similarity(word_mat)

            #step_3) building rank similarity matrix
            renk_mat = rankMatrix(sim_mat)

            # step_4) building the adjacency matrix, followed by generating the graph
            temp_mat = np.transpose(rank_mat)  # TRmsa
            adj_mat = buildAdjMat(temp_mat,
                                  thresh=20,
                                  mode='abs',
                                  reverse=True)
            g = nx.convert_matrix.from_numpy_array(adj_mat,
                                                   create_using=nx.DiGraph)

            # step_5) generating the minimum spanning arboroscence of the graph
            tree = nx.minimum_spanning_arborescence(g)
            tree = nx.relabel_nodes(tree, indKeys)

            # step_6) saving tree to dot file
            dot = to_pydot(tree)
            dotPath = 'TRmsa.dot'
            write_dot(tree, 'TRmsa.dot')

            # step_7) converting dot file to png
            cmd = 'dot -Tpng ' + dotPath
            process = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE)
            output, error = process.communicate()
            pngPath = dotPath.rstrip('.dot') + '.png'
            with open(pngPath, 'wb') as outfile:
                outfile.write(output)
                outfile.close()
            print('file saved as', pngPath)

            print('process complete')
Пример #20
0
    def minimum_spanning_arborescence(self, graph, weight="weight", algorithm="prim"):
        """ Compute the minimum spanning arborescence graph """

        return nx.minimum_spanning_arborescence(graph, attr=weight)
Пример #21
0
    def create_mbs(self, body_dict=None, joint_dict=None):
        self.__bodies = {0: bodymodels.create(0, 'zero')}
        self.__joints = {}
        self.__msa = None  #Minimum spanning arborescence
        self.__predecessors = {0: None}
        self.__successors = {0: []}
        self.__ancestors = {0: []}
        self.__descendants = {0: []}

        #Add all bodies
        if body_dict is not None:
            for key, val in body_dict.items():
                geom, geom_par = val.popitem()  #geom_par is a dict
                abody = bodymodels.create(key, geom, **geom_par)
                self.__bodies[key] = abody

            self.__num_bodies = len(self.__bodies) - 1
            for k in self.bid_iter():
                self.__successors[k] = []
                self.__ancestors[k] = []
                self.__descendants[k] = []

        #Add all joints
        if joint_dict is not None:
            #Add pf and sf for root joint. Also ensure that there is exactly
            #one root joint.
            nrj = 0
            for joint in joint_dict.values():
                if joint['joint_type'] == 'root':
                    joint['pf'] = 0
                    joint['sf'] = 1
                    nrj += 1
#           assert nrj == 1

#Construct the model digraph
            model_digraph = nx.DiGraph()
            for key, val in joint_dict.items():
                model_digraph.add_edge(val['pf'], val['sf'],
                                       {'key_in_joint_dict': key})
            self.__num_joints = model_digraph.number_of_edges()

            #Construct the minimum spanning arborescence
            if nx.is_arborescence(model_digraph):
                self.__msa = model_digraph.copy()
            else:
                self.__msa = nx.minimum_spanning_arborescence(model_digraph)
            self.__num_tree_joints = self.__msa.number_of_edges()
            if self.__draw_graph:
                self.export_digraph(model_digraph, 'model_digraph.eps')
                self.export_digraph(self.__msa, 'msa.eps')

            for edge in self.__msa.edges_iter():
                u, v = edge
                #Copy the joint attributes from model_digraph to self.__msa
                self.__msa[u][v]['key_in_joint_dict'] = model_digraph[u][v][
                    'key_in_joint_dict']
                self.__predecessors[v] = u
                self.__successors[u].append(v)

            #Fill in the ancestors and descendants lists
            for k in self.bid_iter():
                predecessor = self.__predecessors[k]
                self.__ancestors[k].append(predecessor)
                self.__ancestors[k].extend(self.__ancestors[predecessor])
                while predecessor is not None:
                    self.__descendants[predecessor].append(k)
                    predecessor = self.__predecessors[predecessor]

            for k in self.bid_iter():
                pk = self.__predecessors[k]
                key_in_joint_dict = self.__msa[pk][k]['key_in_joint_dict']
                joint_par = joint_dict[key_in_joint_dict]
                joint_type = joint_par.pop('joint_type')
                joint_par['category'] = 'tree'
                joint_par['pf'] = weakref.proxy(self.__bodies[pk])
                joint_par['sf'] = weakref.proxy(self.__bodies[k])
                self.__joints[k] = jointmodels.create(joint_type, **joint_par)

            #Remove the msa edges from model_digraph
            model_digraph.remove_edges_from(self.__msa.edges())
            self.__num_loop_joints = model_digraph.number_of_edges()

            #Create the loop joints after renumbering
            ljid = self.__num_tree_joints
            for edge in model_digraph.edges_iter():
                ljid += 1
                u, v = edge
                key_in_joint_dict = model_digraph[u][v]['key_in_joint_dict']
                joint_par = joint_dict[key_in_joint_dict]
                joint_type = joint_par.pop('joint_type')
                joint_par['category'] = 'loop'
                joint_par['pf'] = weakref.proxy(self.__bodies[u])
                joint_par['sf'] = weakref.proxy(self.__bodies[v])
                self.__joints[ljid] = jointmodels.create(
                    joint_type, **joint_par)

        assert len(self.__bodies) == self.__num_tree_joints + 1

        #Loop over the tree joints to find the total number of generalized
        #coordinates and generalized speeds.
        self.__num_gencoord = 0
        self.__num_genspeed = 0
        self.__gsloc = {}
        for jid in self.tree_jid_iter():
            joint = self.__joints[jid]
            ngc = joint.num_gencoord
            ngs = joint.num_genspeed
            if ngs != 0:
                self.__gsloc[jid] = (self.__num_genspeed,
                                     self.__num_genspeed + ngs)
                self.__num_gencoord += ngc
                self.__num_genspeed += ngs
        self.__gencoord = np.zeros((self.__num_gencoord, ))
        self.__gencoord_dot = np.zeros((self.__num_gencoord, ))
        self.__genspeed = np.zeros((self.__num_genspeed, ))

        #Allocate space for the partial matrix
        self.__partial_mat = np.zeros(
            (6 * self.__num_bodies, self.__num_genspeed))

        #Loop over the loop joints to find the total number of constraints.
        self.__num_constraints = 0
        self.__cloc = {}
        for jid in self.loop_jid_iter():
            joint = self.__joints[jid]
            nc = joint.num_constraints
            self.__cloc[jid] = (self.__num_constraints,
                                self.__num_constraints + nc)
            self.__num_constraints += nc

        #Allocate space for the constraint matrix
        self.__constraint_mat = np.zeros(
            (self.__num_constraints, self.__num_genspeed))

        #Allocate space for the evaluated constraints
        self.__plc = np.zeros((self.__num_constraints, ))  #Position level
        self.__vlc = np.zeros((self.__num_constraints, ))  #Velocity level
        #       Print statements for debugging
        #       print(self.__predecessors)
        #       print(self.__successors)
        #       print(self.__ancestors)
        #       print(self.__descendants)
        #       for jid in self.jid_iter():
        #           joint = self.__joints[jid]
        #           print(jid, joint.connects)
        #       print('num_constraints', self.__num_constraints)
        #
        #       Root joint state
        if self.__rooted:
            self.__pullback = False
        else:
            self.__joints[1].uproot()
Пример #22
0
 def minimum_spanning_arborescence(self):
     b = nx.minimum_spanning_arborescence(self.G)
     return nx.to_numpy_matrix(b, nodelist=list(range(len(self.G.nodes()))))
def steiner_tree_mst(g,
                     root,
                     infection_times,
                     source,
                     terminals,
                     closure_builder=build_closure,
                     strictly_smaller=True,
                     return_closure=False,
                     k=-1,
                     debug=False,
                     verbose=True):
    gc, eweight, r2pred = closure_builder(g,
                                          root,
                                          terminals,
                                          infection_times,
                                          strictly_smaller=strictly_smaller,
                                          k=k,
                                          debug=debug,
                                          verbose=verbose)

    # get the minimum spanning arborescence
    # graph_tool does not provide minimum_spanning_arborescence
    if verbose:
        print('getting mst')
    gx = gt2nx(gc, root, terminals, edge_attrs={'weight': eweight})
    try:
        nx_tree = nx.minimum_spanning_arborescence(gx, 'weight')
    except nx.exception.NetworkXException:
        if debug:
            print('fail to find mst')
        if return_closure:
            return None, gc, None
        else:
            return None

    if verbose:
        print('returning tree')

    mst_tree = Graph(directed=True)
    for _ in range(g.num_vertices()):
        mst_tree.add_vertex()

    for u, v in nx_tree.edges():
        mst_tree.add_edge(u, v)

    if verbose:
        print('extract edges from original graph')

    # extract the edges from the original graph

    # sort observations by time
    # and also topological order
    topological_index = {}
    for i, e in enumerate(bfs_iterator(mst_tree, source=root)):
        topological_index[int(e.target())] = i
    sorted_obs = sorted(set(terminals) - {root},
                        key=lambda o:
                        (infection_times[o], topological_index[o]))

    tree_nodes = {root}
    tree_edges = set()
    # print('root', root)
    for u in sorted_obs:
        if u in tree_nodes:
            if debug:
                print('{} covered already'.format(u))
            continue
        # print(u)
        v, u = map(int, next(mst_tree.vertex(u).in_edges()))  # v is ancestor
        tree_nodes.add(v)

        late_nodes = [
            n for n in terminals if infection_times[n] > infection_times[u]
        ]
        vis = init_visitor(g, u)
        # from child to any tree node, including v

        cpbfs_search(g,
                     source=u,
                     terminals=list(tree_nodes),
                     forbidden_nodes=late_nodes,
                     visitor=vis,
                     count_threshold=1)
        # dist, pred = shortest_distance(g, source=u, pred_map=True)
        node_set = {v for v, d in vis.dist.items() if d > 0}
        reachable_tree_nodes = node_set.intersection(tree_nodes)
        ancestor = min(reachable_tree_nodes, key=vis.dist.__getitem__)

        edges = extract_edges_from_pred(g, u, ancestor, vis.pred)
        edges = {(j, i) for i, j in edges}  # need to reverse it
        if debug:
            print('tree_nodes', tree_nodes)
            print('connecting {} to {}'.format(v, u))
            print('using ancestor {}'.format(ancestor))
            print('adding edges {}'.format(edges))
        tree_nodes |= {u for e in edges for u in e}

        tree_edges |= edges

    t = Graph(directed=True)
    for _ in range(g.num_vertices()):
        t.add_vertex()

    for u, v in tree_edges:
        t.add_edge(t.vertex(u), t.vertex(v))

    tree_nodes = {u for e in tree_edges for u in e}
    vfilt = t.new_vertex_property('bool')
    vfilt.a = False
    for v in tree_nodes:
        vfilt[t.vertex(v)] = True

    t.set_vertex_filter(vfilt)

    if return_closure:
        return t, gc, mst_tree
    else:
        return t