コード例 #1
0
    def __repair_incomplete_sections(self) -> nx.DiGraph:
        """
        Try to repair incomplete sections. A section can be under specified either:

        * departure time is not specified or
        * calender is not set

        In this method at least the departure time is calculated from the construction
        begins using a BFS search in the section graph from these.

        :return: basic section graph (see Train.basis_section_graph)
        """
        construction_begins = list(
            filter(RouteSection.is_complete, self.sections))
        sg = self.basic_section_graph()
        for cb in construction_begins:
            for pred, successors in nx.bfs_successors(sg, cb):
                succ: RouteSection
                for succ in successors:
                    succ.complete_from_predecessor(pred)
        sg_reversed = sg.reverse()
        for cb in construction_begins:
            for pred, successors in nx.bfs_successors(sg_reversed, cb):
                succ: RouteSection
                for succ in successors:
                    succ.complete_from_successor(pred)
        return sg
コード例 #2
0
    def generate_path(self, topo, flow, link_caps):
        path = []
        count = 0
        self.log.debug("Flow%d: %d --> %d: %s" %
                       (flow.flow_id, flow.src, flow.dst, str(flow.vol)))
        while len(path) == 0 and count < self.attempts - 3:
            try:
                from_srcs = defaultdict()
                bfs_src = nx.bfs_successors(topo.graph, flow.src)
                self.get_node_with_distance(bfs_src, flow.src, 0, 2, deque([]),
                                            from_srcs, False)

                to_dsts = defaultdict()
                bfs_dst = nx.bfs_successors(topo.graph, flow.dst)
                self.get_node_with_distance(bfs_dst, flow.dst, 0, 2, deque([]),
                                            to_dsts, True)
            except nx.exception.NetworkXNoPath:
                count += 1
                continue

            if not self.create_with_middlebox(topo, flow, from_srcs, to_dsts,
                                              link_caps):
                if not self.create_with_shortest_path(topo, flow, from_srcs,
                                                      to_dsts, link_caps):
                    count += 1
                    continue
            return True
        if count == self.attempts - 3:
            self.log.debug("Fail hard")
            return False
        return path
コード例 #3
0
	def limitedInfection(self, graph, infectedNodes):
		steps = 0
		color = []
		inNodes = infectedNodes

		for x in inNodes:
			try:
				
				listOfParentNodes = nx.bfs_successors(G,x).keys()
				listOfSubNodes =  nx.bfs_successors(G,x).values()
				del listOfSubNodes[0]
				del listOfSubNodes[0]
				del listOfSubNodes[0]
				del listOfSubNodes[0]
				
			except:
				continue

			print "Processing graph, please wait..."
			for subList in range(0, len(listOfSubNodes)):
				for item in listOfSubNodes[subList]:
					if item not in inNodes:
						inNodes.append(item)	
			
				name= 'Limited_Infected'
				color = Infection.colors(self, graph, inNodes)
				Infection.printGraph(self, graph, inNodes, steps, color, name)
				
				steps = steps + 1

				print "Nodes infected: " + str(color.count('r'))
				print "Nodes left: " + str(len(nx.nodes(graph)))
			
			if color.count('r') == len(nx.nodes(graph)):
					break
コード例 #4
0
ファイル: structurer.py プロジェクト: helios-ops/helios-angr
    def _find_loop_nodes_and_successors(self):

        graph = self._region.graph
        head = self._region.head

        # find latching nodes

        latching_nodes = set()

        queue = [head]
        traversed = set()
        while queue:
            node = queue.pop()
            successors = graph.successors(node)
            traversed.add(node)

            for dst in successors:
                if dst in traversed:
                    latching_nodes.add(node)
                else:
                    queue.append(dst)

        # find loop nodes and successors
        loop_subgraph = RegionIdentifier.slice_graph(graph,
                                                     head,
                                                     latching_nodes,
                                                     include_frontier=True)
        loop_node_addrs = set(node.addr for node in loop_subgraph)

        # Case A: The loop successor is inside the current region (does it happen at all?)
        loop_successors = set()

        for node, successors in networkx.bfs_successors(graph, head):
            if node.addr in loop_node_addrs:
                for suc in successors:
                    if suc not in loop_subgraph:
                        loop_successors.add(suc)

        # Case B: The loop successor is the successor to this region in the parent graph
        if not loop_successors:
            current_region = self._region
            parent_region = self._parent_map.get(current_region, None)
            while parent_region and not loop_successors:
                parent_graph = parent_region.graph
                for node, successors in networkx.bfs_successors(
                        parent_graph, current_region):
                    if node.addr == current_region.addr:
                        for suc in successors:
                            if suc not in loop_subgraph:
                                loop_successors.add(suc)
                current_region = parent_region
                parent_region = self._parent_map.get(current_region, None)

        return loop_subgraph, loop_successors
コード例 #5
0
 def test_limited_bfs_successor(self):
     assert dict(nx.bfs_successors(self.G, source=1, depth_limit=3)) == {
         1: [0, 2],
         2: [3, 7],
         3: [4],
         7: [8],
     }
     result = {
         n: sorted(s)
         for n, s in nx.bfs_successors(self.D, source=7, depth_limit=2)
     }
     assert result == {8: [9], 2: [3], 7: [2, 8]}
コード例 #6
0
 def bfs_test_successor(self):
     assert_equal(dict(nx.bfs_successors(self.G, source=1, depth_limit=3)),
                  {
                      1: [0, 2],
                      2: [3, 7],
                      3: [4],
                      7: [8]
                  })
     result = dict(
         (n, sorted(s))
         for n, s in nx.bfs_successors(self.D, source=7, depth_limit=2))
     assert_equal(result, {8: [9], 2: [3], 7: [2, 8]})
コード例 #7
0
    def __init__(self, graph, miss_deadline_penalty=1):
        """
        G: a networkx direct Graph, each edge is associated with a cost and a time.
        miss_deadline_penalty: the penalty incurred if the deadline is violated. 
        """
        assert isinstance(graph, nx.DiGraph)
        assert len(graph.edges()) > 0
        self.graph = deepcopy(graph)
        self.set_cost_time_radius()
        self.miss_deadline_penalty = miss_deadline_penalty
        self.current_node = None
        self.destination = None
        self.remaining_time = None
        self.last_action = None
        self.last_reward = None
        self.num_step = 0
        # Cumulative reward earned this episode
        self.episode_total_reward = None

        # the action_space is state-dependent and thus we implement a
        # get_action_space as a lambda function to get the list of next nodes
        self.get_action_space = \
            lambda node: DelayConstrainedNetworkActionSpace([(node, next_node) for next_node \
                         in list(nx.bfs_successors(self.graph, node, depth_limit=1))[0][1]])

        self.observation_space = DelayConstrainedNetworkObservationSpace(
            self.graph)
        self.seed()
        self.reset()
コード例 #8
0
ファイル: generation.py プロジェクト: rbnbckr/fair_im
def grow_component(H, max_size):
    """Grow one community by taking BFS components until max_size is reached.

    Parameters
    ----------
    H : networkx.DiGraph
        The underlying considered instance.
    max_size : int
        The maximum community size.

    Returns
    -------
    list
        The grown community as a list of nodes.

    """
    community = []
    bfs = []
    while len(community) < max_size:
        if not bfs:
            source = choice(H.nodes())
            community.append(source)
            bfs = list(nx.bfs_successors(H, source))
            H.remove_node(source)
        else:
            if bfs[0][1]:
                new_node = bfs[0][1][0]
                bfs[0] = (bfs[0][0], bfs[0][1][1:])
                community.append(new_node)
                H.remove_node(new_node)
            else:
                bfs = bfs[1:]
    return community
コード例 #9
0
ファイル: extra.py プロジェクト: wlyxpf/STREAM
def bfs_edges_modified(tree, source, preference=None):
    visited, queue = [], [source]
    bfs_tree = nx.bfs_tree(tree, source=source)
    predecessors = dict(nx.bfs_predecessors(bfs_tree, source))
    edges = []
    while queue:
        vertex = queue.pop()
        if vertex not in visited:
            visited.append(vertex)
            if (vertex in predecessors.keys()):
                edges.append((predecessors[vertex], vertex))
            unvisited = set(tree[vertex]) - set(visited)
            if (preference != None):
                weights = list()
                for x in unvisited:
                    successors = dict(nx.bfs_successors(bfs_tree, source=x))
                    successors_nodes = list(
                        itertools.chain.from_iterable(successors.values()))
                    weights.append(
                        min([
                            preference.index(s)
                            if s in preference else len(preference)
                            for s in successors_nodes + [x]
                        ]))
                unvisited = [
                    x for _, x in sorted(zip(weights, unvisited),
                                         reverse=True,
                                         key=lambda x: x[0])
                ]
            queue.extend(unvisited)
    return edges
コード例 #10
0
def gen_split_obj(
    target_data_path: Path,
    graph,
    model_shape: np.ndarray,
    rot_mat: np.ndarray = None,
):
    edge_vertices = []

    print(graph.nodes)
    for node, successors in nx.bfs_successors(graph, "0"):
        for succ in successors:
            for curr in [node, succ]:
                n = graph.nodes[curr]
                x, y, z = n["x"], n["y"], n["z"]
                edge_vertices.append(np.array([x, y, z]))
    print(edge_vertices)

    edge_vertices = normalize(edge_vertices,
                              reference_shape=model_shape,
                              rot_mat=rot_mat)

    with open(target_data_path, "w") as file:
        file.write("# Vertices\n")
        file.write("# Edge Vertices\n")
        for x, y, z in edge_vertices:
            file.write(f"v {x:.3f} {y:.3f} {z:.3f}\n")
        file.write("\n# Faces\n")

        file.write("# Edge lines\n")
        for i in range(0, len(edge_vertices), 2):
            j = i + 1
            file.write(f"l {j} {j + 1}\n")
コード例 #11
0
ファイル: dep_graph.py プロジェクト: gabrielfarah/OpenHub
 def __reachable_sets(self):
     s_vs = {}
     for n in self.G.nodes_iter():
         successors = nx.bfs_successors(self.G, n)
         s_vs[n] = {rchbl for src in successors for rchbl in successors[src]}
         s_vs[n].add(n)
     return s_vs
コード例 #12
0
def bfs(graph, start, end):
    """
    graphを幅優先探索する

    :param graph: グラフ
    :param start: 始点ノード
    :param end: 終点ノード
    :return: 訪れたノード列
    """
    graph_successors = nx.bfs_successors(graph, start)

    queue = [start]
    visited = []

    while len(queue) > 0:
        v = queue.pop(0)

        if v == end:
            visited.append(v)
            return visited

        if v not in visited:
            visited.append(v)
            queue += [
                x for x in graph_successors.get(v, []) if x not in visited
            ]

    return visited
コード例 #13
0
ファイル: Discovery.py プロジェクト: LucBanda/icfp17_Punters
    def explore(self, timeout: float):
        start = time.time()
        nextList = [self.head]
        i = 0

        for successors in nx.bfs_successors(self, self.head):
            if not successors.explored:
                nextList.append(successors)

        while len(nextList) > 0 and (time.time() - start < timeout):
            currentNode = nextList.pop(0)
            if currentNode.explored:
                pass
            for source in currentNode.endpoints:
                for target in currentNode.fullGraph.neighbors(source):
                    # create a new node by exploring it
                    newGraph = self.evolve_from(currentNode, source, target)
                    i += 1
                    if newGraph:
                        nextList.append(newGraph)
            currentNode.explored = True

        if len(nextList) != 0:
            print_err("timeout, made " + str(i))
        else:
            print_err("to the end of " + str(i))
コード例 #14
0
ファイル: interp_playbooks.py プロジェクト: bjorncole/pyMBE
def random_generator_playbook_phase_2_rollup(
    scg: nx.DiGraph,
    instances_dict: InstanceDictType,
):
    """
    Build up set of sequences for classifiers by taking the union of sequences
    already generated for the classifier subclasses.

    :param lpg: Active SysML graph
    :param scg: Subclassing Graph projection from the LPG
    :param instances_dict: Working dictionary of interpreted sequences for the model
    :return: None - side effect is addition of new instances to the instances dictionary
    """
    roots = [node for node in scg.nodes if scg.in_degree(node) == 0]

    for root in roots:
        bfs_dict = dict(nx.bfs_successors(scg, root))
        bfs_list = list(bfs_dict.keys())
        bfs_list.reverse()

        for gen in bfs_list:
            new_superset = []
            for subset_node in bfs_dict[gen]:
                new_superset.extend(instances_dict[subset_node])

            instances_dict[gen] = new_superset
コード例 #15
0
ファイル: makeGraph.py プロジェクト: maaaaaster/MalwareAI
def checkG(newg, normal):
    domainMap = {}
    index = 0
    for line in open('dga.txt').readlines():
        index += 1
        for data in line.strip().split(' '):
            if data in domainMap:
                print(data)
            else:
                domainMap[data] = index
    for node in newg.nodes:
        if node not in normal:
            continue
        groupSet = set()
        domainSet = set()
        cnt = 3
        for k, v in nx.bfs_successors(newg, node):
            cnt -= 1
            for node2 in v:
                if node2 in domainMap:
                    domainSet.add(node2)
                    groupSet.add(domainMap[node2])
            if cnt == 0:
                break
        print(node, domainSet)
        input()
コード例 #16
0
def multiplePartion(mutiplelist, infectionG, rumorSourceList):

    # 构建关于这个社区的传播子图
    tempGraph1 = nx.Graph()
    for edge in infectionG.edges:
        # if infectG.adj[edge[0]][edge[1]]['Infection']==2:      #作为保留项。
        if edge[0] in mutiplelist[0] and edge[1] in mutiplelist[0]:
            tempGraph1.add_edges_from([edge], weight=1)
    print('这个感染区域的传播子图边个数')
    print(tempGraph1.number_of_edges())
    print(tempGraph1.number_of_nodes())
    nodelist=list(tempGraph1.nodes)
    resultSource = []
    #
    tree = Tree()
    #初始化这些值。
    for  nodetemp in (tempGraph1.nodes):
        tempGraph1.add_node(nodetemp, T=0)
        tempGraph1.add_node(nodetemp, P=0)

    peripheryList=nx.periphery(tempGraph1)
    print ('边界节点'+str(peripheryList))

    randomnode= random.choice(nodelist)
    print ('node是多少'+str(randomnode))
    dict_Temp=dict(nx.bfs_successors(tempGraph1, source=randomnode))
    print (dict_Temp)
    for nodeTemps  in nodelist:
        if nodeTemps in peripheryList:
            tempGraph1.add_node(nodeTemps,T=1)
            tempGraph1.add_node(nodeTemps,P=1)
        else:
            if nodeTemps ==randomnode:
コード例 #17
0
def get_bfs(source):
    edge_local = dict()
    for i in g.edges:
        edge_local[tuple(sorted(i))] = 0
    bfs_output = nx.Graph(nx.bfs_tree(g, source))
    leaf_nodes_list = get_leaf_nodes(bfs_output, source)
    parent_nodes_list = list(nx.bfs_predecessors(bfs_output, source))
    children_nodes_list = list(nx.bfs_successors(bfs_output, source))
    # Initializing the queue with the leaf nodes
    queue = list(leaf_nodes_list)
    while len(queue) > 0:
        current_node = queue.pop(0)
        if current_node in leaf_nodes_list:
            parents = get_parent_nodes(parent_nodes_list, current_node)
            #leaf nodes will have only one parent
            temp = (current_node, parents[0])
            edge_local[tuple(sorted(temp))] = 1
        else:
            parents = get_parent_nodes(parent_nodes_list, current_node)
            children = get_child_nodes(children_nodes_list, current_node)
            forward_val = 1

            for c in children:
                temp = (current_node, c)
                forward_val = forward_val + edge_local[tuple(sorted(temp))]

            if len(parents) > 0:
                temp = (current_node, parents[0])
                edge_local[tuple(sorted(temp))] = forward_val

        if len(parents) > 0 and parents[0] not in queue:
            queue.append(parents[0])

    return edge_local
コード例 #18
0
def nx_tree_to_dd_tree(T):
    # build dict from string label to dendropy node

    T.add_node('my_root')

    random_node = next(iter(T.nodes()))
    near = next(iter(T.neighbors(random_node)))

    T.remove_edge(random_node, near)
    T.add_edge(random_node, 'my_root')
    T.add_edge(near, 'my_root')

    label_node = dict()
    for v in T.nodes():
        dd_node = dd.Node(label=v)
        label_node[v] = dd_node

    # root tree at random node
    # root = next(iter(T.nodes()))
    dd_tree = dd.Tree()
    dd_tree.seed_node = label_node['my_root']
    # print(root)

    # add the edges in the tree
    for v, successors in nx.bfs_successors(T, 'my_root'):
        dd_node = label_node[v]
        for s in successors:
            dd_child = label_node[s]
            dd_node.add_child(dd_child)

    # nx.draw(T, with_labels = True)
    # plt.show()
    return dd_tree
コード例 #19
0
def breadthFirstPathS(G, startNode, endNode):
    global numExpanded
    numExpanded = 0

    pathsDict = {startNode: [startNode]}
    isFound = False

    if endNode == startNode:
        isFound = True

    iter = nx.bfs_successors(G, startNode)
    current = next(iter)
    numExpanded += 1

    # iterate through the graph, remembering the path to get to each node
    while (not isFound):
        for node in current[1]:
            pathsDict[node] = pathsDict[current[0]] + [node]
            numExpanded += 1

        if endNode in current[1]:
            isFound = True
        else:
            current = next(iter)

    return pathsDict[endNode], numExpanded
コード例 #20
0
ファイル: main.py プロジェクト: btciavol/TechEngine
def do_layout(sys):
    #--------------------------------------
    # Generate the product's networkx graph
    #--------------------------------------
    tic = time.time()
    graph = sys.make_positioning_graph()
    print 'Graph contains {0} nodes'.format(len(graph.nodes()))

    root = sys.artifacts_dict['external source']
    tree = nx.bfs_successors(graph,root)
    for k,v in tree.items():
        k.visited = True




    #--------------------------------------
    # Use networkx to develop a graph layout
    #--------------------------------------
#
    positions = nx.graphviz_layout(graph,
                                   prog='dot',
                                   root='external source')

    pos_list = [pos for pos in positions.values()]
    max_pos = max(list(chain.from_iterable(pos_list)))
    scale = 1
#    scale = abs(canvas_size/max_pos)

    for element in graph.nodes_iter():
        element.position = (positions[element][0]*scale,positions[element][1]*scale)

    print 'Graph loaded in {}s'.format(time.time()-tic)
コード例 #21
0
def find_ptm_atoms(molecule):
    """
    Finds all atoms in molecule that have the node attribute ``PTM_atom`` set
    to a value that evaluates to ``True``. ``molecule`` will be traversed
    starting at these atoms untill all marked atoms are visited such that they
    are identified per "branch", and for every branch the anchor node is known.
    The anchor node is the node(s) which are not PTM atoms and share an edge
    with the traversed branch.

    Parameters
    ----------
    molecule : networkx.Graph

    Returns
    -------
    list[tuple[set, set]]
        ``[({ptm atom indices}, {anchor indices}), ...]``. Ptm atom indices are
        connected, and are connected to the rest of molecule via anchor
        indices.
    """

    # Atomnames have already been fixed, and missing atoms have been added.
    # In addition, unrecognized atoms have been labeled with the PTM attribute.
    extra_atoms = set(n_idx for n_idx in molecule
                      if molecule.nodes[n_idx].get('PTM_atom', False))
    ptms = []
    while extra_atoms:
        # First PTM atom we'll look at
        first = next(iter(extra_atoms))
        anchors = set()
        # PTM atoms we've found
        atoms = set()
        # Atoms we still need to see this traversal
        to_see = set([first])
        # Traverse in molecule.
        for orig, succ in nx.bfs_successors(molecule, first):
            # We've seen orig, so remove it
            if orig in to_see:
                to_see.remove(orig)
            if orig in extra_atoms:
                # If this is a PTM atom, we want to see it's neighbours as
                # well.
                to_see.update(succ)
                atoms.add(orig)
            else:
                # Else, it's an attachment point for the this PTM
                anchors.add(orig)
            if not to_see:
                # We've traversed the interesting bit of the tree
                break
        # Although we know how far our tree spans we may still have work to do
        # for terminal nodes. There has to be a more elegant solution though.
        for node in to_see:
            if node in extra_atoms:
                atoms.add(node)
            else:
                anchors.add(node)
        extra_atoms -= atoms
        ptms.append((atoms, anchors))
    return ptms
コード例 #22
0
def merge_close_nodes(graph):
    """Merges nodes when they are really close to each other"""
    has_successors = dict(nx.bfs_successors(graph, "0"))
    nodes_to_be_removed = []
    edges_to_be_merged = []
    cant_be_removed = {"0"}
    for predecessor, node in nx.bfs_edges(graph, "0"):
        if node not in cant_be_removed:
            curr = graph[predecessor][node]
            nums = list(map(int, curr["group_sizes"].split()))
            weight = curr["weight"]
            diameter = calc_diameter(sum(nums) / len(nums))
            if weight < diameter * DIAMETER_TO_WEIGHT_RATIO:
                if node in has_successors:
                    for successor in has_successors[node]:
                        cant_be_removed.add(successor)
                        edges_to_be_merged.append(
                            (graph, predecessor, node, successor))
                nodes_to_be_removed.append(node)
                print(
                    f"Merging: weight: {weight:.2f}, average: {diameter:.2f}",
                    end=" -> ")
                print(curr)
    for edge_merge in edges_to_be_merged:
        merge_edges(*edge_merge)
    remove_nodes(graph, nodes_to_be_removed)
コード例 #23
0
def calculate_shift_distance(adata,root='S0',percentile=95, factor=2.0, preference=None):
    flat_tree = adata.uns['flat_tree']
    dict_label_node = {value: key for key,value in nx.get_node_attributes(flat_tree,'label').items()}  
    root_node = dict_label_node[root]
    ##shift distance for each branch
    dict_edge_shift_dist = dict()
    max_dist = np.percentile(adata.obs['branch_dist'],percentile) ## maximum distance from cells to branch
    leaves = [k for k,v in flat_tree.degree() if v==1]
    n_nonroot_leaves = len(list(set(leaves) - set([root_node])))
    dict_bfs_pre = dict(nx.bfs_predecessors(flat_tree,root_node))
    dict_bfs_suc = dict(nx.bfs_successors(flat_tree,root_node))
    #depth first search
    if(preference != None):
        preference_nodes = [dict_label_node[x] for x in preference]
    else:
        preference_nodes = None
    dfs_nodes = dfs_nodes_modified(flat_tree,root_node,preference=preference_nodes)
    dfs_nodes_copy = deepcopy(dfs_nodes)
    id_leaf = 0
    while(len(dfs_nodes_copy)>1):
        node = dfs_nodes_copy.pop()
        pre_node = dict_bfs_pre[node]
        if(node in leaves):
            dict_edge_shift_dist[(pre_node,node)] = factor*max_dist*(id_leaf-(n_nonroot_leaves/2.0))
            id_leaf = id_leaf+1
        else:
            suc_nodes = dict_bfs_suc[node]
            dict_edge_shift_dist[(pre_node,node)] = (sum([dict_edge_shift_dist[(node,sn)] for sn in suc_nodes]))/float(len(suc_nodes))            
    return dict_edge_shift_dist
コード例 #24
0
def main():
    output_path, tree, classification_config = get_inputs()
    successors = dict(nx.bfs_successors(tree, '0'))
    add_defaults_to_classification_config(classification_config)
    add_default_split_classification_id_to_tree(tree)
    add_deep_descendants_to_classification_config(classification_config)
    add_cost_by_level_in_tree(tree, successors)
    print('\n'.join(map(str, classification_config.items())))
    all_trees = classify_tree(tree, successors, classification_config)
    print(f"All trees: {len(all_trees)}")
    all_trees.sort(key=lambda x: x[0])
    validated_trees = []
    for cost, curr_tree in all_trees:
        if is_valid_tree(curr_tree, classification_config, successors):
            validated_trees.append((cost, curr_tree))
    print(f"Valid trees: {len(validated_trees)}")
    for curr_cost, curr_tree in validated_trees:
        all_classifications = get_all_classifications_in_tree(curr_tree, successors)
        print(f"Cost={curr_cost:.2f}, {'B1+2 is in tree' if 'LB1+2' in all_classifications else ''}")
    # print('\n'.join(map(lambda a: f"{a[0]}: {a[1]}", validated_trees_with_cost)))

    classified_tree = validated_trees[0][1]
    add_colors_in_tree(classified_tree, classification_config)
    # try:
    # except IndexError:
    #     classified_tree = all_trees[0][1]
    show_classification_vectors(classified_tree, successors)
    nx.write_graphml(classified_tree, output_path)
コード例 #25
0
def update_successors(root_scheme, G_scheme, dict_Sure, dict_StillSure,
                      RESOLUTION, G_stationPair, heap):
    """ 如果一个目的车站的到达时间没有发生改变,则其子树的所有车站的到达时间都不会有变化,直接更新他们的出行方案
        root_scheme: 到达时间没有改变的根节点 (出行方案已经更新过)
        G_scheme: 树
    """
    root = root_scheme[-1]['arrive_station']
    set_successors = set()  ## 以root为根的所有子节点
    dict_successors = dict(nx.bfs_successors(G_scheme, source=root))
    for name in dict_successors:
        set_successors.add(name)
        for successor in dict_successors[name]:
            set_successors.add(successor)

    set_successors = set_successors - set(dict_Sure.keys()) - set(
        dict_StillSure.keys())
    for name in set_successors:
        if 'scheme' not in G_scheme.node[name]:
            #print(name)
            continue
        dict_StillSure[name] = _update_scheme(root_scheme,
                                              G_scheme.node[name]['scheme'],
                                              RESOLUTION)
        heapq.heappush(heap, (dict_StillSure[name][-1]['total_travelT'],
                              name))  # 加入堆 ###############
コード例 #26
0
    def get_observed_graph(self):
        """randomly pick a connected subgraph using BFS."""
        train_edge_number = int(self.graph.number_of_edges() *
                                self.train_edge_ratio)
        added_node = set()
        added_edges_number = 0

        _node = list(self.graph.nodes)
        start_node = random.choice(_node)
        added_node.add(start_node)
        logging.debug("random choose start node {}".format(start_node))

        for p, child in nx.bfs_successors(self.graph, start_node):
            for n in child:
                neighbor_n = set(self.graph.neighbors(n))
                added_edges_number += len(neighbor_n & added_node)
                added_node.add(n)
                if added_edges_number >= train_edge_number:
                    h = self.graph.subgraph(added_node)
                    logging.info(
                        "random sample subgraph done. %d edges sampled. with %d nodes"
                        % (h.number_of_edges(), h.number_of_nodes()))
                    return h

        raise RuntimeError(
            "can not get {:d} edges starting from node {:d}".format(
                train_edge_number, start_node))
コード例 #27
0
ファイル: rootedtree.py プロジェクト: Leo927/FindCopNum
    def add_long_weight(self, start):
        '''Add weight to nodes in a RootedTree so that longer paths are formed'''

        lowerBound = 1
        upperBound = len(self.tree.nodes())/10
        digraph = nx.dfs_tree(self.tree, start)

        node_visited = dict((key, False) for key in digraph.nodes())
        # create a queue and push the starting node
        to_visit = queue.Queue()
        to_visit.put(start)
        attribute = {}
        attribute[start] = random.randint(lowerBound, upperBound)
        # do the traversal
        while to_visit.empty() == False:
            node = to_visit.get()

            children = dict(nx.bfs_successors(digraph, node, 1))[node]
            if len(children) <= 0:
                continue

            heir = children[random.randint(0, len(children)-1)]

            for cNode in children:
                if node_visited[cNode] == False:
                    node_visited[cNode] = True
                    to_visit.put(cNode)
                    if (cNode == heir):
                        attribute[cNode] = attribute[node]
                    else:
                        attribute[cNode] = random.randint(
                            lowerBound, upperBound)
        nx.set_node_attributes(self.tree, attribute, "weight")
コード例 #28
0
def get_subgraph(g, edge_factors, start):
    graph = nx.Graph()
    graph.add_node(start)

    for node, edges in nx.bfs_successors(g, start):
        for edge in edges:
            if edge_factors == 0:
                break

            graph.add_edge(node, edge)
            edge_factors -= 1

    return graph


# def edge_facts_subgraph(g, edge_number):
#     count = 0
#     res = {}
#     for start_node in g.nodes:
#         res[start_node] = []

#         i = 0
#         subgraph = nx.bfs_tree(g, start_node)
#         for node in subgraph:
#             if edge_number == i:
#                 break

#             res[start_node].append(node)
#             i += 1

#         count += 1
#         print('  Subgraph Knowledge[{} edges] {:.3%}\t\r'.format(edge_number, count/len(g.nodes)), file=stderr, end='')
#     print()
#     return res
コード例 #29
0
ファイル: OOMethods.py プロジェクト: argaman-aloni/Debugger
 def hirarcy(self, c, files_dict):
     edges = []
     interfaces = 'select path, superClass from classes'
     files_Names = [x.split(".")[-1] for x in files_dict]
     pathNames = {}
     for row in c.execute(interfaces):
         nameClass = (row[0]).split(".")[-1]
         pathNames[nameClass] = row[0]
         nameSuper = (row[1]).split(".")[-1]
         if (nameClass in files_Names):
             sup = 'root'
             if (nameSuper in files_Names):
                 sup = nameSuper
             edges.append((sup, nameClass))
     g = networkx.DiGraph()
     g.add_edges_from(edges)
     degs = g.out_degree()
     degsIN = g.in_degree()
     succ = dict(networkx.bfs_successors(g, 'root'))
     for s in succ:
         succ[s] = len(succ[s])
     paths = networkx.single_source_dijkstra_path(g, 'root')
     depth = {}
     for n in g.nodes():
         depth[n] = 2
         if (n in paths):
             depth[n] = len(paths[n])
     self.addFromDict(files_dict, degs, pathNames)
     self.addFromDict(files_dict, degsIN, pathNames)
     self.addFromDict(files_dict, succ, pathNames)
     self.addFromDict(files_dict, depth, pathNames)
     return files_Names,
コード例 #30
0
ファイル: OOMethods.py プロジェクト: amir9979/Debugger
 def hirarcy(self, c, files_dict):
     edges = []
     interfaces = 'select path, superClass from classes'
     files_Names = [x.split(".")[-1] for x in files_dict]
     pathNames = {}
     for row in c.execute(interfaces):
         nameClass = (row[0]).split(".")[-1]
         pathNames[nameClass] = row[0]
         nameSuper = (row[1]).split(".")[-1]
         if (nameClass in files_Names):
             sup = 'root'
             if (nameSuper in files_Names):
                 sup = nameSuper
             edges.append((sup, nameClass))
     g = networkx.DiGraph()
     g.add_node('root')
     g.add_edges_from(edges)
     degs = g.out_degree()
     degsIN = g.in_degree()
     succ = dict(networkx.bfs_successors(g, 'root'))
     for s in succ:
         succ[s] = len(succ[s])
     paths = networkx.single_source_dijkstra_path(g, 'root')
     depth = {}
     for n in g.nodes():
         depth[n] = 2
         if (n in paths):
             depth[n] = len(paths[n])
     self.addFromDict(files_dict,degs,pathNames)
     self.addFromDict(files_dict,degsIN,pathNames)
     self.addFromDict(files_dict,succ,pathNames)
     self.addFromDict(files_dict,depth,pathNames)
     return  files_Names,
コード例 #31
0
    def test_BFS_node(self, G, source_node, depth=3):
        print('source_node', source_node)

        dfs_successor = nx.bfs_successors(G,
                                          source=source_node,
                                          depth_limit=depth)
        print(dfs_successor)
        dfs_successor = dict(dfs_successor)
        # bfs_s
        stack = []
        dfs_result = defaultdict(list)
        depth = 0
        stack.append(source_node)
        while len(stack) > 0:
            node_list = stack
            temp = []
            for i in list(node_list):
                if i in dfs_successor.keys():
                    for neighbour in dfs_successor[i]:
                        temp.append(neighbour)
                        dfs_result[depth].append(neighbour)
            depth += 1
            stack = temp

        print(dfs_result)
        return dfs_result
コード例 #32
0
def bfs_seq(graph, root):
    """
    Get a BFS transformation of a graph

    :param graph: a networkx graph
    :param root: a node index
    :return: the BFS-ordered node indices
    """

    dictionary = dict(nx.bfs_successors(graph, root))
    to_visit = [root]
    output = [root]
    level_seq = [0]
    level = 1
    while len(to_visit) > 0:
        next_level = []
        while len(to_visit) > 0:
            current = to_visit.pop(0)
            neighbor = dictionary.get(current)
            if neighbor is not None:
                next_level += neighbor
                level_seq += [level] * len(neighbor)
        output += next_level
        to_visit = next_level
        level += 1
    return output
def findAncestors(node):
    Dic = dict(nx.bfs_successors(Dirgraph1, node))
    d = Dic.values()
    c = []
    for e in d:
        c = c + e
    return c
コード例 #34
0
ファイル: structurer.py プロジェクト: AmesianX/angr
    def _find_loop_nodes_and_successors(self):

        graph = self._region.graph
        head = self._region.head

        # find latching nodes

        latching_nodes = set()

        queue = [ head ]
        traversed = set()
        while queue:
            node = queue.pop()
            successors = graph.successors(node)
            traversed.add(node)

            for dst in successors:
                if dst in traversed:
                    latching_nodes.add(node)
                else:
                    queue.append(dst)

        # find loop nodes and successors
        loop_subgraph = RegionIdentifier.slice_graph(graph, head, latching_nodes, include_frontier=True)
        loop_node_addrs = set( node.addr for node in loop_subgraph )

        # Case A: The loop successor is inside the current region (does it happen at all?)
        loop_successors = set()

        for node, successors in networkx.bfs_successors(graph, head):
            if node.addr in loop_node_addrs:
                for suc in successors:
                    if suc not in loop_subgraph:
                        loop_successors.add(suc)

        # Case B: The loop successor is the successor to this region in the parent graph
        if not loop_successors:
            parent_graph = self._parent_region.graph
            for node, successors in networkx.bfs_successors(parent_graph, self._region):
                if node.addr in loop_node_addrs:
                    for suc in successors:
                        if suc not in loop_subgraph:
                            loop_successors.add(suc)

        return loop_subgraph, loop_successors
コード例 #35
0
def networkx_test(filename):
	G = nx.read_gml(filename)
	t1 = datetime.now()
	a = nx.bfs_successors(G, 1)
	t2 = datetime.now()
	timedelta(0, 4, 316543)
	c = t2-t1
	print a
	print "breadth first search using networkx graph on network dataset karate took ", c.microseconds, " microseconds"
コード例 #36
0
ファイル: BayesianModel.py プロジェクト: gargshashank5/pgmpy
 def _is_child_observed(self, node):
     """Returns True if any descendant of the node
     is observed"""
     if node.observed:
         return True
     else:
         child_dict = nx.bfs_successors(G, node)
         for child in child_dict.keys():
             for child_ in child_dict[child]:
                 if child_.observed:
                     return True
         return False
コード例 #37
0
ファイル: net_metrics.py プロジェクト: nddsg/HRG
def bfs_eff_diam(G, NTestNodes, P):
    EffDiam = -1
    FullDiam = -1
    AvgSPL = -1

    DistToCntH = {}

    NodeIdV = nx.nodes(G)
    random.shuffle(NodeIdV)

    for tries in range(0, min(NTestNodes, nx.number_of_nodes(G))):
        NId = NodeIdV[tries]
        b = nx.bfs_successors(G, NId)
        for l, h in hops(b, NId):
            if h is 0:
                continue
            if not l + 1 in DistToCntH:
                DistToCntH[l + 1] = h
            else:
                DistToCntH[l + 1] += h

    DistNbrsPdfV = {}
    SumPathL = 0.0
    PathCnt = 0.0
    for i in DistToCntH.keys():
        DistNbrsPdfV[i] = DistToCntH[i]
        SumPathL += i * DistToCntH[i]
        PathCnt += DistToCntH[i]

    oDistNbrsPdfV = collections.OrderedDict(sorted(DistNbrsPdfV.items()))

    CdfV = oDistNbrsPdfV
    for i in range(1, len(CdfV)):
        if not i + 1 in CdfV:
            CdfV[i + 1] = 0
        CdfV[i + 1] = CdfV[i] + CdfV[i + 1]

    EffPairs = P * CdfV[next(reversed(CdfV))]

    for ValN in CdfV.keys():
        if CdfV[ValN] > EffPairs:
            break

    if ValN >= len(CdfV):
        return next(reversed(CdfV))
    if ValN is 0:
        return 1
    # interpolate
    DeltaNbrs = CdfV[ValN] - CdfV[ValN - 1]
    if DeltaNbrs is 0:
        return ValN
    return ValN - 1 + (EffPairs - CdfV[ValN - 1]) / DeltaNbrs
コード例 #38
0
ファイル: net_metrics.py プロジェクト: nddsg/HRG
def get_graph_hops(graph, num_samples):
    c = Counter()
    for i in range(0, num_samples):
        node = sample(graph.nodes(), 1)[0]
        b = nx.bfs_successors(graph, node)

        for l, h in hops(b, node):
            c[l] += h

    hopper = Counter()
    for l in c:
        hopper[l] = float(c[l]) / float(num_samples)
    return hopper
コード例 #39
0
ファイル: maze_generator.py プロジェクト: ASPP/pelita
def find_dead_ends(graph, start_node, width):
    """Find dead ends in a graph."""

    dead_ends = []
    def collect_dead_ends(node):
        x = node[0]
        # do not consider dead ends on the right side of the maze, as those
        # represents passages to the enemy's side
        if graph.degree(node) == 1 and x < width - 1:
            dead_ends.append(node)

    for node in nx.bfs_successors(graph, start_node):
        collect_dead_ends(node)

    return dead_ends
コード例 #40
0
	def to_bio_tree(self):
		import Bio.Phylo.BaseTree as BT
		successor_dict = _nx.bfs_successors(self.G, SuffixTree.ROOT_NAME)
		
		T = BT.Tree(name=SuffixTree.ROOT_NAME)
		clade_dict = {SuffixTree.ROOT_NAME:T.clade}
	
		next_up = [ SuffixTree.ROOT_NAME]
		while len(next_up) > 0:
			current = next_up.pop(0)
			children = successor_dict.get(current,[])
			for c in children:
				new_clade = BT.Clade(name=c)
				clade_dict[c] = new_clade
				clade_dict[current].clades.append(new_clade)
			next_up.extend(children)

		return T
コード例 #41
0
	def limited_bfs_infection(self, node, target_num):
		original_target = target_num
		if target_num == 0:
			return 0
		self.infect_user(node)
		target_num -= 1
		successors = nx.bfs_successors(self.user_network,node)
		fringe = Queue.Queue()
		fringe.put(node)
		while not fringe.empty():
			self.plot()
			coach = fringe.get()
			if coach in successors and len(successors[coach]) <= target_num:
				for student in successors[coach]:
					self.infect_user(student)
					fringe.put(student)
				target_num -= len(successors[coach])
		return original_target - target_num
コード例 #42
0
ファイル: main.py プロジェクト: Daiver/jff
def main():
    g = nx.Graph()
    g.add_edge(0, 1)
    g.add_edge(0, 2)
    g.add_edge(3, 1)
    g.add_edge(4, 2)

    print("Start search")
    bfs_res = nx.bfs_predecessors(g, 0)
    for x in bfs_res:
        print(x)
    print("Start search")
    bfs_res = nx.bfs_successors(g, 0)
    for x in bfs_res:
        print(x)
    print("Start search")
    bfs_res = nx.bfs_tree(g, 0, depth_limit=1)
    for x in bfs_res:
        print(x)

    nx.draw(g)
    plt.show()
コード例 #43
0
ファイル: dm_graphs.py プロジェクト: BenJamesbabala/dm-graphs
def maxmax_clusters(G):
    """Get clusters based on directed MaxMax graph.
    
    My own twist to the MaxMax algorithm, but still in the MaxMax spirit.
    
    Hope & Keller do this:
    for node in G.nodes():
        if node is marked ROOT:
            mark children of node NOT-ROOT
    
    But this means that with this structure, if we start with B and all nodes are
    marked ROOT, then D is NOT-ROOT. This means that F and G will not be marked
    NOT-ROOT:
    
                 A
               B   C
             D
           F   G
    
    I just return a list containing all maximal QSC subgraphs."""
    
    # Function to create clusters. It takes a node and returns a set containing
    # that node and all its successors.
    cluster    = lambda node: {node} | set(nx.bfs_successors(G,node))
    
    # Get and sort all clusters by size:
    clusters   = sorted([cluster(node) for node in G.nodes()],key=len,reverse=True)
    
    # Create list to output results:
    results    = []
    
    # Loop through the ordered set of clusters, starting with the largest.
    # Add cluster to the results iff it is not a subset of a cluster already in
    # the results.
    for c in clusters:
        if not(True in [c.issubset(s_i) for s_i in results]):
            results.append(c)
    return results
コード例 #44
0
ファイル: pandfunc.py プロジェクト: silky/pandalone
def _all_successors(graph, nodes):
    return [k for node in nodes for k in nx.bfs_successors(graph, node).keys()]
コード例 #45
0
	nodes = map(lambda x:x.lower(), nodes)
        if len(nodes) == 1:###only a single node
            G.add_node(nodes[0])
        else:
            for i in range(len(nodes) - 1):
                node1 = nodes[i]
                node2 = nodes[i+1]
		if (node1, node2) in G.edges():##does not allow reverse propagation
		    continue
                try:
                    G[node2][node1]['weight'] += 1
                except KeyError:
                    G.add_edge(node2, node1, weight=1)
    infile.close()
    return G
    
	    
##############analyze diffusion graph#####################
index = 1
cas_file = os.path.join(cas_dir, str(index) + '.cas')
G = generate_graph(cas_file)
graphs =  nx.weakly_connected_component_subgraphs(G)
sorted_graphs = sorted(graphs, key=lambda x:len(x.nodes()), reverse=True)
convert_graph_to_csv(sorted_graphs[0], 'temp_file')
paths = nx.bfs_successors(G, 'cgseife')
print paths.keys()
print paths['rogerhighfield']
#print paths['berry_k']['trimetilsilyl']

#print paths
コード例 #46
0
ファイル: test_bfs.py プロジェクト: jianantian/networkx
 def bfs_test_successor(self):
     assert_equal(dict(nx.bfs_successors(self.G, source=1, depth_limit=3)),
                  {1: [0, 2], 2: [3, 7], 3: [4], 7: [8]})
     result = {n: sorted(s) for n, s in nx.bfs_successors(self.D, source=7,
                                                          depth_limit=2)}
     assert_equal(result, {8: [9], 2: [3], 7: [2, 8]})
コード例 #47
0
 def test_successor(self):
     assert_equal(nx.bfs_successors(self.G,source=0),
                  {0: [1], 1: [2,3], 2:[4]})
コード例 #48
0
ファイル: bfs.py プロジェクト: sohomghosh/Python-Codes
import networkx as nx
fp1=open("Cit-HepPh.txt",'r')
fp1.readline()
fp1.readline()
fp1.readline()
fp1.readline()
G = nx.DiGraph()
#i=0
while True:
	line=fp1.readline()
	if not line:
		break
	tk=line.split('\t')
	#print i
	#i=i+1
	G.add_edge(int(tk[0]),int(tk[1]))
fp2=open("dfs_outputs.txt",'w')
fp2.write(str(dict(nx.bfs_successors(G,9907233))))
fp1.close()
fp2.close()
コード例 #49
0
ファイル: obj_transform.py プロジェクト: simengy/KDD2015
def obj_transform(dataframe=None, G=None):
    
    dataframe1 = pd.concat([dataframe['enrollment_id'], pd.get_dummies(dataframe['category'])], axis=1)

    if G:
        betweenness = nx.betweenness_centrality(G)
        in_degree = nx.in_degree_centrality(G)
        out_degree = nx.out_degree_centrality(G)
        pagerank = nx.pagerank(G)

        nrow = dataframe.shape[0]

        graph_features = np.zeros((nrow, 7))
        
        for i in xrange(nrow):
            
            graph_features[i,0] = in_degree[dataframe['module_id'][i]] * 5000.0
            graph_features[i,1] = out_degree[dataframe['module_id'][i]] * 5000.0
            graph_features[i,2] = betweenness[dataframe['module_id'][i]] * 5000.0
            graph_features[i,3] = pagerank[dataframe['module_id'][i]] * 5000.0
            
            #pre = nx.bfs_predecessors(G, dataframe['module_id'][i])
            suc = nx.bfs_successors(G, dataframe['module_id'][i])
            graph_features[i,4] = depth(dataframe['module_id'][i], suc) 
            graph_features[i,5] = len( list(nx.ancestors(G, dataframe['module_id'][i]) ))
            graph_features[i,6] = len( list(nx.descendants(G, dataframe['module_id'][i]) ))

        temp = pd.DataFrame(graph_features, index=dataframe.index)
        temp.columns = ['inDgree', 'outDegree', 'betweenness', 'pagerank',
                'depth', 'N_ancestor', 'N_child']
        temp['enrollment_id'] = dataframe['enrollment_id']
        temp.to_csv('debugDir/checkpoint.csv')
    
    # aggregating
    dataframe1 = dataframe1.groupby('enrollment_id').aggregate(np.sum)
    
    temp1 = temp.groupby('enrollment_id').aggregate(np.mean)
    nameList = []
    colName = ['inDgree', 'outDegree', 'betweenness', 'pagerank',
                'depth', 'N_ancestor', 'N_child']
    for name in colName:
        nameList.append(name + '_mean')
    temp1.columns = nameList
    dataframe1 = pd.concat([dataframe1, temp1], axis=1)
    
    temp1 = temp.groupby('enrollment_id').aggregate(np.std) 
    nameList = []
    for name in colName:
        nameList.append(name + '_std')
    temp1.columns = nameList
    dataframe1 = pd.concat([dataframe1, temp1], axis=1)

    temp1 = temp.groupby('enrollment_id').aggregate(np.min)
    nameList = []
    for name in colName:
        nameList.append(name + '_min')
    temp1.columns = nameList
    dataframe1 = pd.concat([dataframe1, temp1], axis=1)
    
    temp1 = temp.groupby('enrollment_id').aggregate(np.max)
    nameList = []
    for name in colName:
        nameList.append(name + '_max')
    temp1.columns = nameList
    dataframe1 = pd.concat([dataframe1, temp1], axis=1)
    
    return dataframe1
コード例 #50
0
                

# inserir o vertice s e t
for i in range(0, vi ):
    l = int(i / colunas)
    c = i % colunas
#    print("i = " + str(i) + "; l = " + str(l) + "; c = " + str(c))
    pixel = image[l][c]
    G.add_edge('s', str(i), capacity=abs(pixel - media_s))
    G.add_edge(str(i), 't', capacity=abs(pixel - media_t))
    
Gf = ford_fulkerson(G, 's', 't', 'capacity')
flow = Gf.graph['flow_value']
flow_dict = Gf.graph['flow_dict']

suc = nx.bfs_successors(Gf, 's')

resultado = np.zeros((64,64), dtype=np.int8)

vertices = suc['s']

for i in range(0, len(vertices)):
    t = int(vertices[i])
    l = int(t / 64)
    c = t % 64
    resultado[l][c] = 1
    
io.imshow(resultado)
    

コード例 #51
0
ファイル: conll.py プロジェクト: hectormartinez/ancora2ud
    def _keep_fused_form(self,posPreferenceDicts):
        # For a span A,B  and external tokens C, such as  A > B > C, we have to
        # Make A the head of the span
        # Attach C-level tokens to A
        #Remove B-level tokens, which are the subtokens of the fused form della: de la

        if self.graph["multi_tokens"] == {}:
            return

        spanheads = []
        spanhead_fused_token_dict = {}
        # This double iteration is overkill, one could skip the spanhead identification
        # but in this way we avoid modifying the tree as we read it
        for fusedform_idx in sorted(self.graph["multi_tokens"]):
            fusedform_start, fusedform_end = self.graph["multi_tokens"][fusedform_idx]["id"]
            fuseform_span = list(range(fusedform_start,fusedform_end+1))
            spanhead = self._choose_spanhead_from_heuristics(fuseform_span,posPreferenceDicts)
            #if not spanhead:
            #    spanhead = self._choose_spanhead_from_heuristics(fuseform_span,posPreferenceDicts)
            spanheads.append(spanhead)
            spanhead_fused_token_dict[spanhead] = fusedform_idx

        bottom_up_order = [x for x in nx.topological_sort(self) if x in spanheads]
        for spanhead in bottom_up_order:
            fusedform_idx = spanhead_fused_token_dict[spanhead]
            fusedform = self.graph["multi_tokens"][fusedform_idx]["form"]
            fusedform_start, fusedform_end = self.graph["multi_tokens"][fusedform_idx]["id"]
            fuseform_span = list(range(fusedform_start,fusedform_end+1))

            if spanhead:
                #Step 1: Replace form of head span (A)  with fusedtoken form  -- in this way we keep the lemma and features if any
                self.node[spanhead]["form"] = fusedform
                # 2-  Reattach C-level (external dependents) to A
                #print(fuseform_span,spanhead)

                internal_dependents = set(fuseform_span) - set([spanhead])
                external_dependents = [nx.bfs_successors(self,x) for x in internal_dependents]
                for depdict in external_dependents:
                    for localhead in depdict:
                        for ext_dep in depdict[localhead]:
                            deprel = self[localhead][ext_dep]["deprel"]
                            self.remove_edge(localhead,ext_dep)
                            self.add_edge(spanhead,ext_dep,deprel=deprel)

                #3- Remove B-level tokens
                for int_dep in internal_dependents:
                    self.remove_edge(self.head_of(int_dep),int_dep)
                    self.remove_node(int_dep)

        #4 reconstruct tree at the very end
        new_index_dict = {}
        for new_node_index, old_node_idex in enumerate(sorted(self.nodes())):
            new_index_dict[old_node_idex] = new_node_index

        T = DependencyTree() # Transfer DiGraph, to replace self

        for n in sorted(self.nodes()):
            T.add_node(new_index_dict[n],self.node[n])

        for h, d in self.edges():
            T.add_edge(new_index_dict[h],new_index_dict[d],deprel=self[h][d]["deprel"])
        #4A Quick removal of edges and nodes
        self.__init__()

        #4B Rewriting the Deptree in Self
        # TODO There must a more elegant way to rewrite self -- self= T for instance?
        for n in sorted(T.nodes()):
            self.add_node(n,T.node[n])

        for h,d in T.edges():
            self.add_edge(h,d,T[h][d])

        # 5. remove all fused forms form the multi_tokens field
        self.graph["multi_tokens"] = {}

        if not nx.is_tree(self):
            print("Not a tree after fused-form heuristics:",self.get_sentence_as_string())