Example #1
0
def would_cause_cycle(e, u, v, reverse=False):
    """
	Test if adding the edge u -> v to the BayesNet
	object would create a DIRECTED (i.e. illegal) cycle.
	"""
    G = nx.DiGraph(e)
    if reverse:
        G.remove_edge(v, u)
    G.add_edge(u, v)
    try:
        nx.find_cycle(G, source=u)
        return True
    except:
        return False
Example #2
0
    def test_prev_explored(self):
        # https://github.com/networkx/networkx/issues/2323

        G = nx.DiGraph()
        G.add_edges_from([(1,0), (2,0), (1,2), (2,1)])
        assert_raises(nx.exception.NetworkXNoCycle,
                      find_cycle, G, source=0)
        x = list(nx.find_cycle(G, 1))
        x_ = [(1, 2), (2, 1)]
        assert_equal(x, x_)

        x = list(nx.find_cycle(G, 2))
        x_ = [(2, 1), (1, 2)]
        assert_equal(x, x_)
Example #3
0
def build_clusters(objects, relations, styles_by_type):
    """
    Return a graph whose vertices are names of objects mapping to clusters,
    edges represent direct containment of clusters
    and every cluster is directly contained in at most one parent cluster.

    Raises `GraphError` if such a graph cannot be built.
    """
    result = nx.DiGraph()
    for o in objects:
        if o.type in styles_by_type.get('cluster-type', set()):
            result.add_node(o.name, {'type': o.type, 'attrs': o.attrs.asDict()})
    result.add_edges_from(
        (r.lhs, r.rhs) for r in relations
        if r.rel in styles_by_type.get('containment', set())
        and r.lhs in result and r.rhs in result)
    try:
        cycle = nx.find_cycle(result)
    except nx.exception.NetworkXNoCycle:
        pass
    else:
        raise GraphError('Circular containment: %s in %s'
                         % (cycle[0][0], ' in '.join(v for u, v in cycle)))

    transitive_reduce(result)

    for v in result:
        out_edges = result.out_edges(v)
        if len(out_edges) > 1:
            raise GraphError('Cluster %s in more than one parent: %s'
                % (v, ', '.join(v for _, v in out_edges)))

    return result
Example #4
0
 def _insert_after(self, graph, route, other):
     try:
         route_successors = graph.successors(route.name)
     except nx.NetworkXError:
         route_successors = []
     if other in route_successors:
         graph.add_edge(other, route.name)
         raise DependencyLoop(nx.find_cycle(graph, route.name))
     try:
         other_successors = graph.successors(other)[:]
     except nx.NetworkXError:
         other_successors = []
     for other_successor in other_successors:
         if self.routes[other_successor].urltpl < route.urltpl:
             try:
                 self._insert_after(graph, route, other_successor)
                 break
             except DependencyLoop:
                 pass
     else:
         graph.add_edge(other, route.name)
         for other_successor in graph.successors(other)[:]:
             if route.urltpl < self.routes[other_successor].urltpl:
                 try:
                     graph.remove_edge(other, other_successor)
                 except nx.NetworkXError:
                     pass
                 else:
                     graph.add_edge(route.name, other_successor)
Example #5
0
 def sorted_routes(self):
     graph = nx.DiGraph()
     constrained = set(r for r in self.routes.values()
                       if r.before or r.after)
     unconstrained = set(self.routes.values()) - constrained
     for r1, r2 in permutations(unconstrained, 2):
         if r1.urltpl.equals(r2.urltpl):
             continue
         if r1.urltpl < r2.urltpl:
             graph.add_edge(r1.name, r2.name)
         else:
             graph.add_edge(r2.name, r1.name)
     for route in constrained:
         self._insert_constrained(graph, route)
     for route in unconstrained:
         if not graph.has_node(route.name):
             # quite improbable case, but this scenario does exist (all
             # routes unconstrained and equal, for example)
             graph.add_edge(None, route.name)
     try:
         loop = nx.find_cycle(graph)
         raise DependencyLoop(loop)
     except nx.NetworkXNoCycle:
         pass
     return list(self.routes[n]
                 for n in nx.topological_sort(graph)
                 if n is not None)
Example #6
0
def concave_hull(polydata):
    """extract the concave hull of a vtk polydata object"""
    # setup the extraction pipeline
    extract = tvtk.FeatureEdges()
    # we're only interested in the boundaries
    extract.feature_edges = False
    extract.boundary_edges = True
    extract.manifold_edges = False
    extract.non_manifold_edges = False
    configure_input(extract, polydata)
    # compute edges
    extract.update()
    # extract the points
    points = extract.output.points.to_array()

    # slice every 2nd and 3rd point
    line_ids = np.c_[
        extract.output.lines.to_array()[1::3],
        extract.output.lines.to_array()[2::3]
    ]
    # 1st points should all be 2
    assert (extract.output.lines.to_array()[0::3] == 2).all(), "expected only lines"

    # construct a directed graph
    D = networkx.DiGraph(data=line_ids.tolist())
    # find the first cycle
    first_cycle = networkx.find_cycle(D)
    # create the index to lookup points, including last point
    cycle = [x[0] for x in first_cycle] + [first_cycle[0][0]]
    # fill in index and return first 2 coordinates
    return points[cycle, :2]
 def analyse_cyclic_dependencies(graph):
     try:
         cycle = networkx.find_cycle(graph)
         dependency_string = ' => '.join("[%s is referenced by %s]" % tup for tup in cycle)
         raise CyclicDependencyException("Found cyclic dependency between stacks: {0}".format(dependency_string))
     except NetworkXNoCycle:
         pass
    def orient_undecided_edges(self):

        vertices = self.states_df.columns
        nx_graph = self.new_filled_nx_graph()
        undecided_edges = []
        for vtx in vertices:
            nbor_set = set(self.vtx_to_nbors[vtx]) - \
                       set(nx.all_neighbors(nx_graph, vtx))
            for nbor in nbor_set:
                undecided_edges.append((vtx, nbor))
        
        for beg_vtx, end_vtx in undecided_edges:
            # add dir_edge to nx_graph in one direction
            # and see if it causes cycle
            # If it doesn't, then
            # add dir edge to vtx_to_parents in same direction
            # and if it does add to vtx_to_parents in opposite direction
            nx_graph.add_edge(beg_vtx, end_vtx)
            try:
                cycle_edge_list = nx.find_cycle(nx_graph, source=beg_vtx)
            except nx.exception.NetworkXNoCycle:
                cycle_edge_list = []  
            if len(cycle_edge_list) == 0:
                self.vtx_to_parents[end_vtx].append(beg_vtx)
            else:
                self.vtx_to_parents[beg_vtx].append(end_vtx)
            # restore nx_graph to original state
            nx_graph.remove_edge(beg_vtx, end_vtx)
 def get_cycles(self):
     """Returns a list of cycles in the dependency graph, if they are present."""
     cycles = None
     try:
         cycles = nx.find_cycle(self._dependency_graph)
     except Exception:
         pass
     return cycles
Example #10
0
 def add_edge(self, u, v, t):
     # add an edge. if it creates a cycle, remove the oldest edge in the cycle
     super(TimelyForest, self).add_edge(u=u, v=v, t=t)
     try:
         cycle = nx.find_cycle(self, orientation='ignore')
     except NetworkXNoCycle:
         cycle = None
     if cycle:
         # go through costly remove only if necessary.
         return self.remove_oldest_edge(t, cycle)
     return None
Example #11
0
    def orient_undecided_edges(self):
        """
        When this function is called in learn_str(), the vtx_to_parents that
        has been learned so far may not include all of the edges implied by
        vtx_to_nbors. Hence, there might still be some undirected edges.
        This function uses a reasonable but not rigorous heuristic to orient
        those undecided edges.

        Returns
        -------
        None

        """
        if self.verbose:
            print('\nbegin orient_undecided_edges')

        vertices = self.states_df.columns
        nx_graph = self.new_filled_nx_graph()
        undecided_edges = []
        for vtx in vertices:
            nbor_set = set(self.vtx_to_nbors[vtx]) - \
                       set(nx.all_neighbors(nx_graph, vtx))
            for nbor in nbor_set:
                if (nbor, vtx) not in undecided_edges:
                    undecided_edges.append((vtx, nbor))
        
        for beg_vtx, end_vtx in undecided_edges:
            # add dir_edge to nx_graph in one direction
            # and see if it causes cycle
            # If it doesn't, then
            # add dir edge to vtx_to_parents in same direction
            # and if it does add to vtx_to_parents in opposite direction
            nx_graph.add_edge(beg_vtx, end_vtx)
            try:
                cycle_edge_list = nx.find_cycle(nx_graph, source=beg_vtx)
            except nx.exception.NetworkXNoCycle:
                cycle_edge_list = []  
            if len(cycle_edge_list) == 0:
                self.vtx_to_parents[end_vtx].append(beg_vtx)
            else:
                self.vtx_to_parents[beg_vtx].append(end_vtx)
            # restore nx_graph to original state
            nx_graph.remove_edge(beg_vtx, end_vtx)

        if self.verbose:
            print('undecided edges=', undecided_edges)
            print('vtx_to_parents=')
            pp.pprint(self.vtx_to_parents, width=1)
            print('end orient_undecided_edges')
Example #12
0
def main():

	verbose = False

	db     = connect_to_mysql(Config.mysql_conf_file)
	cursor = db.cursor()

	switch_to_db(cursor, 'icgc')

	# are there children with multiple parents? Yes. So I need some kind of
	# directed graph, rather tha a tree.
	qry = "select child, count(distinct parent) as ct from reactome_hierarchy "
	qry += "group by child having ct>1"
	ret = search_db(cursor, qry)
	print("number of children with multiple parents:", len(ret))

	# feed the parent/child pairs as edges into graph
	ret = hard_landing_search(cursor, 'select parent, child from reactome_hierarchy')
	graph = nx.DiGraph(ret) # directed graph
	print("graph is directed: ", graph.is_directed())
	print("number of edges:", len(graph.edges))
	print("graph is multigraph:", graph.is_multigraph())
	try:
		edges = nx.find_cycle(graph)
	except:
		print("hooray, no cycles found")

	# graph.in_degree is a list of pairs, rather than a method

	# candidate roots
	zero_in_degee_nodes = [name for name, indegree in graph.in_degree if indegree==0]

	node_id_string = ",".join([quotify(z) for z in zero_in_degee_nodes])
	qry_template = "select * from reactome_pathways where reactome_pathway_id in (%s)"
	root_names =  hard_landing_search(cursor, qry_template% node_id_string)
	gene_groups = {}
	for pthwy_id, name in root_names:
		if "disease" in name.lower(): continue
		if verbose: print(pthwy_id, name)
		characterize_subtree(cursor, graph, pthwy_id,  gene_groups,  1, verbose=verbose)
	cursor.close()
	db.close()

	# print("\n===========================")
	# for group, genes in gene_groups.items():
	# 	print (group, len(genes))
	hist_plot(gene_groups)
def order_build(graph):
    '''
    Assumes that packages are in graph.
    Builds a temporary graph of relevant nodes and returns it topological sort.

    Relevant nodes selected in a breadth first traversal sourced at each pkg
    in packages.
    '''
    reorder_cyclical_test_dependencies(graph)
    try:
        order = list(nx.topological_sort(graph))
        order.reverse()
    except nx.exception.NetworkXUnfeasible:
        raise ValueError("Cycles detected in graph: %s", nx.find_cycle(graph,
                                                                       orientation='reverse'))

    return order
Example #14
0
def cycle_check(parents, ik_map):

    g = make_graph(parents)
    test = nx.DiGraph()
    test.add_nodes_from([i for i in range(len(ik_map))])

    parents = [ik_map[i[0]][0] for i in g.tolist()]
    children = [ik_map[i[1]][0] for i in g.tolist()]

    for i in range(len(parents)):
        test.add_edge(parents[i], children[i])

    try:
        cycle = list(nx.find_cycle(test, orientation='original'))
    except:
        cycle = []

    return cycle
Example #15
0
    def cycles(self) -> Optional[List[int]]:
        """Returns cycles in neuron if any.

        See also
        --------
        networkx.find_cycles()
                    Function used to find cycles.

        """
        try:
            c = nx.find_cycle(
                self.graph,
                source=self.nodes[self.nodes.type == 'end'].node_id.values)
            return c
        except nx.exception.NetworkXNoCycle:
            return None
        except BaseException:
            raise
Example #16
0
 def is_stratified(self):
     '''
     Checks if the logic program can be stratified.
     :return: bool: True if the program can be stratified. False if not.
     '''
     G = self.graph
     try:
         cycle = nx.find_cycle(G)
         for edge in cycle:
             source = edge[0]
             target = edge[1]
             data = G.get_edge_data(source, target)
             negated = data[0]['negated']
             if negated:
                 return False
     except nx.NetworkXNoCycle:
         pass
     return True
Example #17
0
def check_loops(gltf: GLTF):
    n = DiGraph()
    all_nodes = list(range(len(gltf.model.nodes)))
    for i in all_nodes:
        n.add_node(i)

    for node_index, node in enumerate(gltf.model.nodes):
        if node.children:
            for c in node.children:
                n.add_edge(node_index, c)

    try:
        c = find_cycle(n)
    except NetworkXNoCycle:
        pass
    else:
        logger.info(c=c)
        raise ZValueError("cycle found", c=c)
Example #18
0
def get_all_cycles(breakpoint_graph):
    visited = set()
    cycles = []
    for vertex in breakpoint_graph.nodes():
        if vertex in visited:
            continue
        try:
            cycle = nx.find_cycle(breakpoint_graph.bg, vertex)
            new = False
            for v1, v2, dir in cycle:
                if v1 not in visited:
                    new = True
                visited.add(v1)
            if new:
                cycles.append(cycle)
        except:
            pass
    return cycles
Example #19
0
def print_cycle_info_and_break_cycles(table_graph: Any) -> None:
    """Change given graph by breaking cycles."""
    simple_cycles = list(nx.simple_cycles(table_graph))
    if len(simple_cycles) > 0:
        print("\n%s self-references and simple cycles found:" %
              (len(simple_cycles), ))
        print(simple_cycles)

    # Break simple cycles and self-references to help find bigger cycles
    copy_of_graph = table_graph.copy()
    db_graph.break_cycles(copy_of_graph)

    try:
        cycle = nx.find_cycle(copy_of_graph)
        print("\nAnother cycle was detected:")
        print(cycle)
    except nx.exception.NetworkXNoCycle:
        pass
Example #20
0
    def get_substructures(Gn):
        subs = set()
        for G in Gn:
            degrees = list(dict(G.degree()).values())
            if any(i == 2 for i in degrees):
                subs.add('linear')
            if np.amax(degrees) >= 3:
                subs.add('non linear')
            if 'linear' in subs and 'non linear' in subs:
                break

        if is_directed(Gn):
            for G in Gn:
                if len(list(nx.find_cycle(G))) > 0:
                    subs.add('cyclic')
                    break

        return subs
Example #21
0
def min_cycle_ratio(G: nx.Graph, dist):
    """[summary] todo: parameterize cost and time

    Arguments:
        G ([type]): [description]

    Returns:
        [type]: [description]
    """
    mu = 'cost'
    sigma = 'time'
    set_default(G, mu, 1)
    set_default(G, sigma, 1)
    T = type(dist[next(iter(G))])

    def calc_weight(r, e):
        """[summary]

        Arguments:
            r ([type]): [description]
            e ([type]): [description]

        Returns:
            [type]: [description]
        """
        u, v = e
        return G[u][v]['cost'] - r * G[u][v]['time']

    def calc_ratio(C):
        """Calculate the ratio of the cycle

        Arguments:
            C {list}: cycle list

        Returns:
            cycle ratio
        """
        total_cost = sum(G[u][v]['cost'] for (u, v) in C)
        total_time = sum(G[u][v]['time'] for (u, v) in C)
        return T(total_cost) / total_time

    C0 = nx.find_cycle(G)
    r0 = calc_ratio(C0)
    return max_parametric(G, r0, C0, calc_weight, calc_ratio, dist)
Example #22
0
def random_algorithm(input_graph):
	G = input_graph.copy()
	cycle_list = []
	pre_penalty = 0
	while G.nodes():
		try:
			edge_cycle = nx.find_cycle(G)
			vertex_cycle = []
			for edge in edge_cycle:
				vertex_cycle.append(edge[0])
				pre_penalty += G.node[edge[0]]['penalty']
				G.remove_node(edge[0])
			cycle_list.append(vertex_cycle)
		except:
			print("No cycle found")
			break	
	penalty = find_total_penalty(input_graph) - pre_penalty
	formatted_cycle_list = format_output_cycles(cycle_list)
	return [formatted_cycle_list, penalty]
Example #23
0
def Hv_rule4(G, Hv, N2, k, solution, permanent):
    try:
        cycle = nx.find_cycle(Hv, source=None, orientation='ignore')
        if len(cycle) % 2 == 0:
            #print("rule4")
            cycle_nodes = set()
            for edge in cycle:
                cycle_nodes.add(edge[0])
                cycle_nodes.add(edge[1])
            N2_cycle = list(cycle_nodes & set(N2))
            #print(N2_cycle)
            G1 = copy.deepcopy(G)
            G1.remove_nodes_from(N2_cycle)
            return branching(G1, k - len(N2_cycle), solution + N2_cycle,
                             permanent)
        else:
            return False
    except:
        return False
Example #24
0
def has_cycle(graph: networkx.DiGraph) -> bool:
    """
    Checks that a graph does not contain a cycle.
    :param graph: The graph to check
    :return: A boolean true if there is a cycle.
    """
    sources = find_source_nodes(graph)
    if not sources:
        return True

    for source in sources:
        try:
            cycle = networkx.find_cycle(graph, source)
            if cycle:
                print(cycle)
                return True
        except networkx.NetworkXNoCycle:
            return False
    return False
Example #25
0
def random_algorithm(input_graph):
    G = input_graph.copy()
    cycle_list = []
    pre_penalty = 0
    while G.nodes():
        try:
            edge_cycle = nx.find_cycle(G)
            vertex_cycle = []
            for edge in edge_cycle:
                vertex_cycle.append(edge[0])
                pre_penalty += G.node[edge[0]]['penalty']
                G.remove_node(edge[0])
            cycle_list.append(vertex_cycle)
        except:
            print("No cycle found")
            break
    penalty = find_total_penalty(input_graph) - pre_penalty
    formatted_cycle_list = format_output_cycles(cycle_list)
    return [formatted_cycle_list, penalty]
Example #26
0
def maximum_tree(G, root=0, step=0):
    """
    :param G: graph of type networkx Graph
    :param root: the root node
    :param step: this function being recursive, the step tells us how deep we are with the recursion.
    :return: a maximum spanning tree of the graph G, of type network Graph.
    """
    G = prepare(G, root)
    P = greedy(G, root)
    if nx.is_arborescence(P):
        return P
    else:  # there is a cycle
        C = nx.find_cycle(P, orientation='ignore')
        G, dictionary_cleanup = cleanup(G, root)
        G_contracted, dictionary = contract(G, C, root=root, step=step)
        T_contracted = maximum_tree(G_contracted, root=root, step=step + 1)
        T_expanded = expand(T_contracted, C, dictionary, root=root, step=step)
        T_expanded = uncleanup(T_expanded, dictionary_cleanup, root=root)
        return T_expanded
def exchange_shifts(workers: List[Worker]):

    while workers:
        G = nx.DiGraph()
        G = build_graph(workers)
        # find the cycle in the graph
        changes = list(nx.find_cycle(G, orientation='ignore'))
        # [(3, 'c', 'forward')]
        for change in changes:

            if (type(change[0]) == str):
                currentShift = find_shift(workers, change[0])
                print(
                    str(change[0]) + " moves from shift " + str(currentShift) +
                    " to Shift " + str(change[1]))
                #remove worker
                workers = update_workers(workers, change[0])
                #remove this shift from al preferances
                update_preferances(workers, change[1])
def add_edges_in_order(edge_to_win_ratio, vote_set):
    """Adds edges in order of weight, never adding edges that would create a cycle."""
    win_graph = nx.DiGraph()
    ordered_votes = sorted(vote_set,
                           key=lambda e: edge_to_win_ratio[(e[0], e[1])],
                           reverse=True)

    for c1, c2, result in ordered_votes:
        try:
            win_graph.add_edge(c1, c2)
            cycles = nx.find_cycle(win_graph)
            # If we hit this line, a NoCycle exception was not thrown, therefore there is a cycle and we have to
            # remove an edge from it
            win_graph.remove_edge(c1, c2)
        except nx.NetworkXNoCycle:
            continue

    assert nx.is_directed_acyclic_graph(win_graph)
    return win_graph
def augmenting_path(G, demand_nodes, assignments):
    reduced_elements = 0
    while 1:
        try:
            cycle = nx.find_cycle(
                G)  #Done arbitrarily. Maybe better to select one specifically?
            reduced_elements += adjust_graph(G, cycle, demand_nodes,
                                             assignments)
            print("Cycle: " + str(cycle))
        except nx.NetworkXNoCycle:
            break
    for i in G.nodes():  # Done arbitrarily. Maybe select one specifically?
        if G.degree(i) == 1:
            path = list(nx.dfs_edges(G, source=i))
            print("Path " + str(path))
            reduced_elements += adjust_graph(G, path, demand_nodes,
                                             assignments)
            break
    return reduced_elements
Example #30
0
    def requestLockOrder(self, order):
        'verify that the requested lock order wont cause deadlocks'
        if len(order) == 1:
            return True
        links = []
        for od in self.orders:
            links.extend(list(zip(od, od[1:])))

        links.extend(list(zip(order, order[1:])))

        graph = nx.DiGraph(links)
        try:
            loops = nx.find_cycle(graph)
        except:
            loops = []
        if len(loops) > 0:
            return False
        self.orders.append(order)
        return True
Example #31
0
def approximate_steiner(graph, terminals):
    steiner_tree = nx.Graph()
    num_terminals = len(terminals)
    all_terminal_paths = list()
    for i in range(0, num_terminals):
        for j in range(i + 1, num_terminals):
            paths = get_paths(graph, terminals[i], terminals[j])
            least_cost_path, least_cost = get_least_cost_path(graph, paths)
            path = dict()
            path['cost'] = least_cost
            path['path'] = least_cost_path
            print "Path" + str(path['path'])
            all_terminal_paths.append(path)

    all_terminal_paths.sort(key=lambda x: x['cost'])
    for t_path in all_terminal_paths:
        steiner_tree.add_path(t_path['path'])
        if check_terminals_connected(steiner_tree, terminals):
            break
    conn_components = list(comp.connected_components(steiner_tree))
    while len(conn_components) > 1:
        comp1 = conn_components[0]
        comp2 = conn_components[1]
        for j in range(0, len(comp1)):
            for k in range(0, len(comp2)):
                if graph.has_edge(comp1[j], comp2[k]):
                    steiner_tree.add_edge(comp1[j], comp2[k])
                    break
        conn_components = list(comp.connected_components(steiner_tree))

    while True:
        try:
            cycle = nx.find_cycle(steiner_tree)
            print('Cycle found')
            edge = cycle[0]
            steiner_tree.remove_edge(edge[0], edge[1])
        except:
            break
    weights = nx.get_node_attributes(graph, 'weight')
    steiner_cost = 0
    for node in list(steiner_tree.nodes):
        steiner_cost = steiner_cost + weights[node]
    return steiner_tree, steiner_cost
Example #32
0
def optimize_cycle_remover(solver, tree, cycle_killer_fn, orig_cost):
    if not orig_cost:
        orig_cost = average_pairwise_distance(tree)
    tree_set = set(tree.nodes)
    candidates = [
        (v, list(set(solver.neighbors(v)) & tree_set)) for v in solver.G
        if solver.is_optional(v) and len(set(solver.neighbors(v))
                                         & tree_set) > 2
    ]
    # Candidates contains all vertices with >2 neighbors in tree and list of all those neighboring vertices
    min_cost = orig_cost
    for pair in candidates:
        v = pair[0]
        edges = [(v, x) for x in pair[1]
                 if weight(solver.G, (v, x)) < solver.max_T_edge_weight]
        if len(edges) < 2:
            continue
        edges.sort(key=lambda x: weight(solver.G, x))

        # Try adding a vertex and two edges to tree to make a cycle and delete min edge
        added_edge = False
        min_edge = edges[0]
        solver.add_edge(min_edge)
        for j in range(1, len(edges)):
            solver.add_edge(edges[j])

            cycle: list = find_cycle(tree, v)
            replaced_edge, new_cost = cycle_killer_fn(solver,
                                                      cycle,
                                                      orig_cost=min_cost)
            if replaced_edge:
                added_edge = True
                # print("Added vertex", v, "and edges:", min_edge, edges[j])
                # print("Prev cost:", min_cost)
                # print("New cost:", new_cost)
                min_cost = new_cost
                solver.remove_edge(replaced_edge)
            else:
                solver.remove_edge(edges[j])
        if not added_edge:
            solver.remove_edge(min_edge)
    return min_cost
Example #33
0
    def __init__(self, structure: StructureModel):
        """
        Create a ``BayesianNetwork`` with a DAG defined by ``StructureModel``.

        Args:
            structure: a graph representing a causal relationship between variables.
                       In the structure
                           - cycles are not allowed;
                           - multiple (parallel) edges are not allowed;
                           - isolated nodes and multiple components are not allowed.

        Raises:
            ValueError: If the structure is not a connected DAG.
        """
        n_components = nx.number_weakly_connected_components(structure)

        if n_components > 1:
            raise ValueError(
                "The given structure has {n_components} separated graph components. "
                "Please make sure it has only one.".format(n_components=n_components)
            )

        if not nx.is_directed_acyclic_graph(structure):
            cycle = nx.find_cycle(structure)
            raise ValueError(
                "The given structure is not acyclic. Please review the following cycle: {cycle}".format(
                    cycle=cycle
                )
            )

        # _node_states is a Dict in the form `dict: {node: dict: {state: index}}`.
        # Underlying libraries expect all states to be integers from zero, and
        # thus this dict is used to convert from state -> idx, and then back from idx -> state as required
        self._node_states = None  # type: Dict[str: Dict[Hashable, int]]
        self._structure = structure

        # _model is a pgmpy Bayesian Model.
        # It is used for:
        #                - probability fitting
        #                - predictions
        self._model = BayesianModel()
        self._model.add_edges_from(structure.edges)
    def _acyclics_subgraphs(self, G):
        """ Divide a graph into connected components subgraphs
        Divide a graph into connected components subgraphs and remove its
        cycles removing the edge with higher weight inside the cycle. Also
        prune the graphs by number of nodes in case the graph has not enought
        nodes.

        Args:
            G (nx.Graph): Graph

        Returns:
            list(nx.Graph): Returns a list of graphs which are subgraphs of G
                with cycles removed.
        """
        if not isinstance(G, nx.Graph):
            raise TypeError('G must be a nx.Graph instance')
        S = []  # List of subgraphs of G

        for c in nx.connected_components(G):
            g = G.subgraph(c).copy()

            # Remove all cycles that we may find
            has_cycles = True
            while has_cycles:
                try:
                    cycle = nx.find_cycle(g)
                    weights = np.asarray([G[u][v]['weight'] for u, v in cycle])
                    idx = weights.argmax()
                    # Remove the edge with highest weight at cycle
                    g.remove_edge(*cycle[idx])
                except nx.NetworkXNoCycle:
                    has_cycles = False

            if len(g) < self.min_nb_nodes:
                # Prune small subgraphs
                logging.verbose(
                    'Remove a small line with {} nodes'.format(len(g)), 1)
                continue

            S.append(g)

        return S
Example #35
0
    def would_create_cycle(self, move):
        """
        This function performs the move 'move' on self.nx_graph and then
        tests to see if the new graph has cycles. It communicates the result
        of the tests in the bool output. It restores nx_graph to its
        original state after the testing for cycles is concluded.

        Parameters
        ----------
        move : tuple[str, str, str]

        Returns
        -------
        bool

        """

        (beg_vtx, end_vtx, action) = move

        if action == 'del':
            return False

        if action == 'add':
            self.nx_graph.add_edge(beg_vtx, end_vtx)
        elif action == 'rev':
            self.nx_graph.remove_edge(beg_vtx, end_vtx)
            self.nx_graph.add_edge(end_vtx, beg_vtx)
        else:
            assert False

        try:
            cycle_edge_list = nx.find_cycle(self.nx_graph, source=beg_vtx)
        except nx.exception.NetworkXNoCycle:
            cycle_edge_list = []
        # restore self.nx_graph to original state
        if action == 'add':
            self.nx_graph.remove_edge(beg_vtx, end_vtx)
        elif action == 'rev':
            self.nx_graph.add_edge(beg_vtx, end_vtx)
            self.nx_graph.remove_edge(end_vtx, beg_vtx)

        return len(cycle_edge_list) > 0
    def would_create_cycle(self, move):
        """
        This function performs the move 'move' on self.nx_graph and then
        tests to see if the new graph has cycles. It communicates the result
        of the tests in the bool output. It restores nx_graph to its
        original state after the testing for cycles is concluded.

        Parameters
        ----------
        move : tuple[str, str, str]

        Returns
        -------
        bool

        """

        (beg_vtx, end_vtx, action) = move

        if action == 'del':
            return False

        if action == 'add':
            self.nx_graph.add_edge(beg_vtx, end_vtx)
        elif action == 'rev':
            self.nx_graph.remove_edge(beg_vtx, end_vtx)
            self.nx_graph.add_edge(end_vtx, beg_vtx)
        else:
            assert False

        try:
            cycle_edge_list = nx.find_cycle(self.nx_graph, source=beg_vtx)
        except nx.exception.NetworkXNoCycle:
            cycle_edge_list = []
        # restore self.nx_graph to original state
        if action == 'add':
            self.nx_graph.remove_edge(beg_vtx, end_vtx)
        elif action == 'rev':
            self.nx_graph.add_edge(beg_vtx, end_vtx)
            self.nx_graph.remove_edge(end_vtx, beg_vtx)

        return len(cycle_edge_list) > 0
Example #37
0
    def __init__(self, workflow):
        log.info(f'Building workflow graph for {workflow}...')
        self.workflow = workflow
        self.G = nx.DiGraph()
        self.nodes = self.G.nodes
        self.edges = self.G.edges

        for name, task in workflow.tasks.items():
            self.G.add_node(name)

        for name, task in workflow.tasks.items():
            try:
                self._make_edges(task)
            except ValueError as e:
                err = f'While adding edges for: {task}\n{e}'
                raise ValueError(err) from None

        if not nx.is_directed_acyclic_graph(self.G):
            cycles = nx.find_cycle(self.G)
            raise ValueError(f'Not a DAG! Possible causes:{list(cycles)}')
Example #38
0
    def find_watercycles(self, n):

        cycles_ = [
            self.waternet.subgraph(cycle)
            for cycle in nx.cycle_basis(self.waternet) if len(cycle) == n
        ]
        waterdict = {
            node[0]: node[1]
            for node in self.waternet.nodes(data=True)
        }

        watercycles = []
        for cycle_ in cycles_:
            edges = [(node1, node2, self.waternet.get_edge_data(node1, node2))
                     for node1, node2 in nx.find_cycle(cycle_)]
            watercycle = Cycle(edges=edges, nodes=waterdict)
            # nx.set_node_attributes(watercycle, waterdict)
            watercycles.append(watercycle)

        return watercycles
Example #39
0
    def is_cyclic(self):
        """
        Checks for combinational loops in circuit

        Returns
        -------
        Bool
                Existence of cycle

        """
        g = self.graph.copy()
        g.remove_edges_from(
            (e, s) for s in self.startpoints() for e in self.endpoints()
        )
        try:
            if nx.find_cycle(g):
                return True
        except NetworkXNoCycle:
            pass
        return False
Example #40
0
def break_cycles(edges):
    '''Break any graph cycles present in the list of edges'''
    dig = networkx.digraph.DiGraph()
    for src, dest in edges:
        dig.add_edge(src, dest)

    while True:
        try:
            cycle = networkx.find_cycle(dig)
        except networkx.NetworkXNoCycle:
            break

        src, dest = cycle[-1]
        logger.warning('Found cycles in port graph: %s; breaking at %s->%s',
                       cycle, src, dest)

        dig.remove_edge(src, dest)
        edges.remove((src, dest))

    return edges
Example #41
0
    def check_for_cycles(self):
        """check for cycles

        Raise:
            ConfigurationError if cycles found

        """
        cycles = None
        try:
            cycles = nx.find_cycle(self.G2)
            logging.info("cycles:" + str(cycles))
        except nx.exception.NetworkXNoCycle as e:
            # it throws an error if there are no cycles, the opposite of what we want
            if str(e) != "No cycle found.":
                raise e  # pragma: no cover
            else:
                logging.info("OK: no cycles found")
        # to get here, we must have cycles!
        if cycles:
            raise ConfigurationError("Cycle(s) found: %s" % str(cycles))
Example #42
0
def cycle_subtourelim(model, where):
    '''
    Find the components of the graph
    Select the smallest components (number of vertices)
    Force the model to have at least one edge connecting the
        component to its complement
    '''
    if where == GRB.Callback.MIPSOL:
        G = nx.Graph()
        edges = [
            edge.vertices for edge in model._edges
            if model.cbGetSolution(model._edgevar[edge.vertices])
        ]
        G.add_edges_from(edges)

        cycle = nx.find_cycle(G)
        lhs = quicksum(model._edgevar[vertex1.incident[vertex2].vertices]
                       for vertex1, vertex2 in cycle)
        rhs = len(cycle) - 1
        model.cbLazy(lhs <= rhs)
    def removeCycles(cls, inGraph):

        diGraph = inGraph.copy()

        while not nx.is_directed_acyclic_graph(diGraph):

            cycle = nx.find_cycle(diGraph)

            weakestLink = sys.float_info.max
            weakestEdge = None

            for edge in cycle:
                weight = diGraph[edge[0]][edge[1]]['covweight']

                if weight < weakestLink:
                    weakestEdge = edge
                    weakestLink = weight

            diGraph.remove_edge(weakestEdge[0], weakestEdge[1])

        return diGraph
Example #44
0
def DMP(g):
        v = g.number_of_nodes()
        e = g.number_of_edges()
        h = networkx.Graph()
	h.add_edges_from(networkx.find_cycle(g))
	b = []
	b.append((h.copy()))
	b.append((h.copy()))
        
	#Handles trivial cases
	if (v < 5):
                planar()
        if (3 * v - 6 < e):
                nonplanar()
        if (h is None):
                planar()
	
	#Upper bound determined by Euler's Formula f = e - v + 2
	for r in range(0, e - v):
		add_face(g, h, b)
	planar()
Example #45
0
def find_small_component(graph, graph_name):
    """
        graph에서 작은 component를 찾고 node / edge와 cycle이 있는지 찾는다.
    """
    S = [
        graph.subgraph(c).copy()
        for c in sorted(nx.connected_components(graph), key=len, reverse=True)
    ]
    for i, subG in enumerate(S):
        try:
            print("Subgraph of {0} : node : {1}, edge : {2}, has cycle : {3}".
                  format(
                      graph_name, nx.number_of_nodes(subG),
                      nx.number_of_edges(subG), True
                      if len(nx.find_cycle(subG, orientation="original")) > 0
                      else False))

        except Exception as e:
            print("Subgraph of {0} : node : {1}, edge : {2}, has cycle : {3}".
                  format(graph_name, nx.number_of_nodes(subG),
                         nx.number_of_edges(subG), False))
def pop_cycle_segments(graph):
    """
    Find all cycles in the given nx.Graph (each cycle becomes a 'segment'),
    and remove the cycle nodes from the graph after they are found.
    """
    segments = []
    try:
        while True:
            cycle_edges = nx.find_cycle(graph)
            graph.remove_edges_from(cycle_edges)
            cycle_nodes = [node[0] for node in cycle_edges]
            cycle_nodes.append(cycle_edges[-1][1])

            # Drop nodes without neighbors
            for node in cycle_nodes[:-1]:
                if not graph.neighbors(node):
                    graph.remove_node(node)
            segments.append(cycle_nodes)
    except nx.NetworkXNoCycle:
        pass

    return segments
Example #47
0
def compute(problem):
    problem.set_edges_and_vertices()
    net_graph = nx.DiGraph()
    net_graph.add_edges_from(problem.edges)

    temp = list()

    while True:
        try:
            this = []
            cycle = nx.find_cycle(net_graph)
            for pair in cycle:
                if pair[0] not in this:
                    this.append(pair[0])
                if pair[1] not in this:
                    this.append(pair[1])
            net_graph.remove_nodes_from(this)
            if len(cycle) < 5:
                temp.append(this)

        except Exception, e:
            new_copy = []
            for donor_cycle in temp:
                new_temp = [str(i) for i in donor_cycle]
                new_copy.append(new_temp)
                    
            final_copy = ""

            for donor_cycle in new_copy:
                donor_string = " ".join(donor_cycle)
                new_string = donor_string.rstrip()
                new_string += "; "

                final_copy += new_string

            problem.solution = final_copy

            return
def constrained_birkhoff_von_neumann_iterator(H, X):
  (G, p) = H.pop(0)
  #remove edges with integer weights
  #extracts all edges satisfy the weight threshold:
  eligible_edges = [(from_node,to_node,edge_attributes) for from_node,to_node,edge_attributes in G.edges(data=True) if all(i < edge_attributes['weight'] or edge_attributes['weight'] < i for i in range(0,int(math.floor(sum(sum(X)))+1)))]
  if not eligible_edges:
    return(H)
  else:
    K = nx.DiGraph()
    K.add_edges_from(eligible_edges)
  #find a cycle and compute the push_forward and push_reverse probabilities and graphs
  cycle = nx.find_cycle(K, orientation='ignore')
  forward_weights = [(d['weight'],d['min_capacity'],d['max_capacity']) for (u,v,d) in K.edges(data=True) if (u,v,'forward') in cycle]
  reverse_weights = [(d['weight'],d['min_capacity'],d['max_capacity']) for (u,v,d) in K.edges(data=True) if (u,v,'reverse') in cycle]
  push_forward = min([x[2] - x[0] for x in forward_weights])
  push_reverse = min([x[2] - x[0] for x in reverse_weights])
  pull_forward = min([x[0] - x[1] for x in forward_weights])
  pull_reverse = min([x[0] - x[1] for x in reverse_weights])
  push_forward_pull_reverse = min(push_forward,pull_reverse)
  push_reverse_pull_forward = min(pull_forward,push_reverse)
  #Construct the push_forward_pull_reverse graph
  G1 = copy.deepcopy(G)
  for (u,v,d) in G1.edges(data=True):
    if (u,v,'forward') in cycle:
      d['weight']+=push_forward_pull_reverse
    if (u,v,'reverse') in cycle:
      d['weight']+=-push_forward_pull_reverse
  #Construct the push_reverse_pull_forward graph
  G2 = copy.deepcopy(G)
  for (u,v,d) in G2.edges(data=True):
    if (u,v,'reverse') in cycle:
      d['weight']+=push_reverse_pull_forward
    if (u,v,'forward') in cycle:
      d['weight']+=-push_reverse_pull_forward
  gamma = min([1,max([0,push_reverse_pull_forward/(push_forward_pull_reverse + push_reverse_pull_forward)])])
  return([(G1,p*gamma), (G2,p*(1-gamma))])
Example #49
0
    def update_jamstarts(self):
        concert = self.video.concert

        relevant_edges_query = Q(confidence__gt=settings.CONFIDENCE_THRESHOLD) & Q(video1__concert_id=concert.id) & Q(video2__concert_id=concert.id)
        acyclic_edges_query = Q(video1__is_cycle=False) & Q(video2__is_cycle=False)
        acyclic_relevant_edges = Edge.objects.filter(relevant_edges_query & acyclic_edges_query)

        # unique the resulting edges and make all edges positive
        digraph_edges = []
        seen_video_ids = set()
        for edge in acyclic_relevant_edges:
            video_ids = (edge.video1_id, edge.video2_id)

            if video_ids in seen_video_ids or video_ids[0] == video_ids[1]:
                continue
            else:
                seen_video_ids.add(video_ids)

            # if the edge is negative, flip it! We only want positive edges
            if edge.offset < 0:
                edge.offset *= -1
                edge.video1_id, edge.video2_id = edge.video2_id, edge.video1_id

            edge_data = (int(edge.video2_id), int(edge.video1_id), edge.offset)
            digraph_edges.append(edge_data)

        if len(digraph_edges) == 0:
            # if there are no edges, then we just have to create a jamjar w/ one video (this one) in it
            new_start_id = self.video.id

        else:
            # build a graph from the resulting edges
            digraph = nx.DiGraph()
            video_id = int(self.video.id)
            digraph.add_node(video_id)
            digraph.add_weighted_edges_from(digraph_edges)

            # find all videos in the subgraph
            undirected_graph = digraph.to_undirected()

            video_ids_in_subgraph = nx.node_connected_component(undirected_graph, video_id)

            # check if a cycle exists -- if so: f**k this video
            # if not: continue as normal
            try:
                cycle = nx.find_cycle(digraph)
                # if we get here, a cycle exists, so f**k this video
                new_start_id = self.video.id

                # mark this jamstart as being in a cycle
                self.video.is_cycle = True

            except nx.NetworkXNoCycle:
                # sort the directed graph such that if A has an edge to B, A will come before B in the resulting list
                temporally_sorted_videos = nx.topological_sort(digraph)

                # the first video id in the list is the jamstart for this subgraph
                new_start_id = temporally_sorted_videos[0]

                # update start_id for all videos in the resulting subgraph
                JamJarMap.objects.filter(video_id__in=video_ids_in_subgraph).update(start_id=new_start_id)

        # And add this one
        JamJarMap.objects.create(video=self.video, start_id=new_start_id)
Example #50
0
def group_substructures(mols, patterns=None,
                        mol_instantiator=unsanitized_mol_from_smiles,
                        pattern_instantiator=mol_from_smarts,
                        matcher=has_query_query_match,
                        reduce=True):

    import networkx as nx

    # Instantiate mols and their "pattern" representation
    # Must document that, when already provided Chem.Mol objects, instantiators usually are no-ops
    if pattern_instantiator is not None:
        patterns = list(to_rdkit_mols(mols, pattern_instantiator))
    if mol_instantiator is not None:
        mols = list(to_rdkit_mols(mols, mol_instantiator))

    if patterns is None:
        patterns = mols

    # Sort substructures by decreasing number of atoms
    num_atoms = [mol.GetNumAtoms() for mol in mols]
    descending_number_of_atoms_order = np.argsort(num_atoms)[::-1]

    representative = [None] * len(mols)  # For duplicates
    graph = nx.DiGraph()                 # Directed graph, if (p1, p2) on it,

    # Nasty stuff that would not happen if cheminformatics were logical
    # noinspection PyUnusedLocal
    has_equal_nonequal = has_cycles = False

    for p1, p2 in combinations(descending_number_of_atoms_order, 2):
        p2_in_p1, p1_in_p2 = matcher(mols[p1], patterns[p2]), matcher(mols[p2], patterns[p1])
        representative[p1] = representative[p1] or p1
        representative[p2] = representative[p2] or p2
        if p2_in_p1 and p1_in_p2:
            representative[p2] = representative[p1]
        elif p2_in_p1:
            if num_atoms[p1] == num_atoms[p2] and not has_equal_nonequal:
                has_equal_nonequal = True
                info('mindblowingly, with equal number of atoms, one contains the other but not viceversa')
            graph.add_edge(representative[p1], representative[p2])
        elif p1_in_p2:
            if num_atoms[p1] == num_atoms[p2] and not has_equal_nonequal:
                has_equal_nonequal = True
                info('mindblowingly, with equal number of atoms, one contains the other but not viceversa')
            graph.add_edge(representative[p2], representative[p1])
        else:
            graph.add_node(representative[p1])
            graph.add_node(representative[p2])

    # Cycles?
    try:
        nx.find_cycle(graph)
        has_cycles = True
        info('containment graph has cycles')
    except nx.NetworkXNoCycle:
        has_cycles = False

    if reduce:
        graph = nx.transitive_reduction(graph)

    groups = list(nx.weakly_connected_components(graph))
    # noinspection PyCallingNonCallable
    roots = [node for node, degree in graph.in_degree() if 0 == degree]
    # noinspection PyCallingNonCallable
    leaves = [node for node, degree in graph.out_degree() if 0 == degree]

    return graph, groups, representative, roots, leaves, num_atoms, has_cycles, has_equal_nonequal
Example #51
0
def find_topological_order(directory, target=None):
  graph = nx.DiGraph()

  # First, walk the installers and find real providers
  for root, _, files in os.walk(directory):
    if INSTALLER in files:
      name = os.path.basename(root)
      graph.add_node(name, transitive=False)

  # Second, find all dependees and dependers
  for root, _, files in os.walk(directory):
    if INSTALLER in files:
      name = os.path.basename(root)
      dependencies, satisfies = read_dependencies(os.path.join(root, INSTALLER))

      for dependence in dependencies:
        # If by now the dependence does not have a node it does not have a real
        # provider, so we assume it is transitive, i.d. provided by something
        # with different name
        if not graph.has_node(dependence):
          graph.add_node(dependence, transitive=True)

      # Set edge from dependee to its provider
      add_edge = functools.partial(lambda a,b: graph.add_edge(b,a), name)
      map(add_edge, dependencies)

      for sat in satisfies:
        # If there is something that tries to satisfy already satisfied
        # dependency we consider this an error
        if graph.has_node(sat) and len(list(graph.predecessors(sat))):
          print("{} tries to satisfy already existing installer {}".format(name, sat))
          return False, None
        graph.add_node(sat, transitive=True)

      # Set edge from transitive provider to its real provider
      add_edge = functools.partial(lambda a,b: graph.add_edge(a,b), name)
      map(add_edge, satisfies)

  # print graph.edges()
  # sys.exit(0)

  # Not all dependencies are provided by installers of the same name. By
  # collapsing the graph on these 'satisfying' dependencies we point a dependee
  # to a right installer.
  for node, transitive in graph.nodes(data='transitive'):
    if not transitive:
      continue

    dependees = list(graph.successors(node))
    providers = list(graph.predecessors(node))
    assert len(providers) == 1, 'Must be exactly one provider'

    # Remove transitive node with all its edges
    graph.remove_node(node)

    # Reconnect the graph
    add_edge = functools.partial(graph.add_edge, providers[0])
    map(add_edge, dependees)

  if not nx.is_directed_acyclic_graph(graph):
    print("Found dependency cycle: {}".format(nx.find_cycle(graph)))
    return False, None

  if target:
    closure = set([target])
    while True:
      new = closure | set(sum(map(list, map(graph.predecessors, closure)), []))
      if closure == new:
        break
      closure = new
    return True, list(nx.topological_sort(graph.subgraph(closure)))

  return True, list(nx.topological_sort(graph))
    def build_graph(self):

        """
        - 迭代添加句子,构建有向连通词图,词语添加顺序:

        1. 没有候选结点或者具有明确的候选结点或者在一个句子中出现多次的非停用词

        2. 具有多个候选结点的非停用词

        3. 停用词

        4. 标点

        对于2、3、4,如果具有多个候选结点,则选择上下文和词图中的邻接结点覆盖度最大的结点。

        - 为词图添加边

        词图中的每个结点是一个元组('word/POS', id),同时附加一个info信息,info为一个列表,
        其中存储每个包含该词的句子sentence_id和在句子中的位置position_in_sentence

        """

        # 逐个添加句子
        for i in range(self.length):

            # 计算句子的长度(包含的词数)
            sentence_len = len(self.sentence[i])

            # 标记,用0初始化
            mapping = [0] * sentence_len

            # -------------------------------------------------------------------
            # 1. 没有候选结点或者具有明确的候选结点或者在一个句子中出现多次的非停用词
            # -------------------------------------------------------------------
            for j in range(sentence_len):

                token, pos, weight = self.sentence[i][j]

                # 如果是停用词或者标点,则跳过
                if token in self.stopwords or re.search('(?u)^\W$', token):
                    continue

                # 结点标识:word/-/pos
                node = token.lower() + self.sep + pos

                # 计算图中可能的候选结点的个数
                k = self.ambiguous_nodes(node)

                # 如果图中没有结点,则新建一个结点,id为0
                if k == 0:

                    # 添加一个id为0的结点,i为句子编号,j为当前词在句子中的编号
                    self.graph.add_node((node, 0), info=[(i, j)], label=token.lower())

                    # Mark the word as mapped to k
                    mapping[j] = (node, 0)

                # 只有一个匹配的结点(即id为0的结点)
                elif k == 1:

                    # 获取包含当前结点的句子ID
                    ids = []
                    for sid, pos_s in self.graph.node[(node, 0)]['info']:
                        # sid为node所在句子id, pos_s为该词在句子中的位置
                        ids.append(sid)

                    # 如果该结点之前没有记录,则更新该结点(更新info的值)
                    if i not in ids:
                        self.graph.node[(node, 0)]['info'].append((i, j))
                        mapping[j] = (node, 0)

                    # 否则为当前冗余的词创建一个新的结点
                    else:
                        self.graph.add_node((node, 1), info=[(i, j)], label=token.lower())
                        mapping[j] = (node, 1)

            # -------------------------------------------------------------------
            # 2. 具有多个候选结点的非停用词
            # -------------------------------------------------------------------
            for j in range(sentence_len):

                token, pos, weight = self.sentence[i][j]

                # 如果是停用词或者标点,则跳过
                if token in self.stopwords or re.search('(?u)^\W$', token):
                    continue

                # 处理步骤1中未处理的词
                if mapping[j] == 0:

                    # 结点标识:word/-/pos
                    node = token.lower() + self.sep + pos

                    # 创建邻接结点的标识
                    prev_token, prev_pos, prev_weight = self.sentence[i][j-1]  # 前一个词的word和pos
                    next_token, next_pos, next_weight = self.sentence[i][j+1]  # 后一个词的word和pos
                    prev_node = prev_token.lower() + self.sep + prev_pos
                    next_node = next_token.lower() + self.sep + next_pos

                    # 计算图中可能的候选结点的个数
                    k = self.ambiguous_nodes(node)

                    # 寻找候选结点中具有最大上下文覆盖度或最大频度的结点
                    ambinode_overlap = []
                    ambinode_frequency = []

                    # 依次处理每个候选结点
                    for l in range(k):

                        # 获取结点的上文
                        l_context = self.get_directed_context(node, l, 'left')

                        # 获取结点的下文
                        r_context = self.get_directed_context(node, l, 'right')

                        # 计算对应node在相应上下文中出现的总次数
                        val = l_context.count(prev_node)
                        val += r_context.count(next_node)

                        # 保存每个候选结点的上下文覆盖度
                        ambinode_overlap.append(val)

                        # 保存每个候选结点的频度
                        ambinode_frequency.append(len(self.graph.node[(node, l)]['info']))

                    # 寻找最佳候选结点(避免环路)
                    found = False
                    selected = 0
                    while not found:

                        # 覆盖度最大的结点下标
                        selected = self.max_index(ambinode_overlap)

                        # 如果覆盖度不能区分,则用最大的频度
                        if ambinode_overlap[selected] == 0:
                            selected = self.max_index(ambinode_frequency)

                        # 获取句子对应的ID
                        ids = []
                        for sid, p in self.graph.node[(node, selected)]['info']:
                            ids.append(sid)

                        # 避免环路
                        if i not in ids:
                            found = True
                            break

                        # Remove the candidate from the lists
                        else:
                            del ambinode_overlap[selected]
                            del ambinode_frequency[selected]

                        # Avoid endless loops
                        if len(ambinode_overlap) == 0:
                            break

                    # 找到不为当前句子的最佳候选结点
                    if found:
                        self.graph.node[(node, selected)]['info'].append((i, j))
                        mapping[j] = (node, selected)

                    # 否则,创建一个新的结点
                    else:
                        self.graph.add_node((node, k), info=[(i, j)], label=token.lower())
                        mapping[j] = (node, k)

            # -------------------------------------------------------------------
            # 3. 处理停用词
            # -------------------------------------------------------------------
            for j in range(sentence_len):

                token, pos, weight = self.sentence[i][j]

                # 如果不是停用词,则跳过
                if token not in self.stopwords:
                    continue

                # 结点标识:word/-/pos
                node = token.lower() + self.sep + pos

                # 获取候选结点的数目
                k = self.ambiguous_nodes(node)

                # If there is no node in the graph, create one with id = 0
                if k == 0:

                    # Add the node in the graph
                    self.graph.add_node((node, 0), info=[(i, j)], label=token.lower())

                    # Mark the word as mapped to k
                    mapping[j] = (node, 0)

                # Else find the node with overlap in context or create one
                else:

                    # Create the neighboring nodes identifiers
                    prev_token, prev_pos, prev_weight = self.sentence[i][j-1]
                    next_token, next_pos, next_weight = self.sentence[i][j+1]
                    prev_node = prev_token.lower() + self.sep + prev_pos
                    next_node = next_token.lower() + self.sep + next_pos

                    ambinode_overlap = []

                    # For each ambiguous node
                    for l in range(k):

                        # Get the immediate context words of the nodes, the
                        # boolean indicates to consider only non stopwords
                        l_context = self.get_directed_context(node, l, 'left', True)
                        r_context = self.get_directed_context(node, l, 'right', True)

                        # Compute the (directed) context sum
                        val = l_context.count(prev_node)
                        val += r_context.count(next_node)

                        # Add the count of the overlapping words
                        ambinode_overlap.append(val)

                    # Get best overlap candidate
                    selected = self.max_index(ambinode_overlap)

                    # Get the sentences id of the best candidate node
                    ids = []
                    for sid, pos_s in self.graph.node[(node, selected)]['info']:
                        ids.append(sid)

                    # Update the node in the graph if not same sentence and
                    # there is at least one overlap in context
                    if i not in ids and ambinode_overlap[selected] > 0:

                        # Update the node in the graph
                        self.graph.node[(node, selected)]['info'].append((i, j))

                        # Mark the word as mapped to k
                        mapping[j] = (node, selected)

                    # Else create a new node
                    else:
                        # Add the node in the graph
                        self.graph.add_node((node, k), info=[(i, j)], label=token.lower())

                        # Mark the word as mapped to k
                        mapping[j] = (node, k)

            # -------------------------------------------------------------------
            # 4. 处理标点
            # -------------------------------------------------------------------
            for j in range(sentence_len):

                token, pos, weight = self.sentence[i][j]

                # 如果不是标点,则跳过
                if not re.search('(?u)^\W$', token):
                    continue

                # 结点标识:word/-/pos
                node = token.lower() + self.sep + pos

                # 计算相似结点的数目
                k = self.ambiguous_nodes(node)

                # If there is no node in the graph, create one with id = 0
                if k == 0:

                    # Add the node in the graph
                    self.graph.add_node((node, 0), info=[(i, j)], label=token.lower())

                    # Mark the word as mapped to k
                    mapping[j] = (node, 0)

                # Else find the node with overlap in context or create one
                else:

                    # Create the neighboring nodes identifiers
                    prev_token, prev_pos, prev_weight = self.sentence[i][j-1]
                    next_token, next_pos, next_weight = self.sentence[i][j+1]
                    prev_node = prev_token.lower() + self.sep + prev_pos
                    next_node = next_token.lower() + self.sep + next_pos

                    ambinode_overlap = []

                    # For each ambiguous node
                    for l in range(k):

                        # Get the immediate context words of the nodes
                        l_context = self.get_directed_context(node, l, 'left')
                        r_context = self.get_directed_context(node, l, 'right')

                        # Compute the (directed) context sum
                        val = l_context.count(prev_node)
                        val += r_context.count(next_node)

                        # Add the count of the overlapping words
                        ambinode_overlap.append(val)

                    # Get best overlap candidate
                    selected = self.max_index(ambinode_overlap)

                    # Get the sentences id of the best candidate node
                    ids = []
                    for sid, pos_s in self.graph.node[(node, selected)]['info']:
                        ids.append(sid)

                    # Update the node in the graph if not same sentence and
                    # there is at least one overlap in context
                    if i not in ids and ambinode_overlap[selected] > 1:

                        # Update the node in the graph
                        self.graph.node[(node, selected)]['info'].append((i, j))

                        # Mark the word as mapped to k
                        mapping[j] = (node, selected)

                    # Else create a new node
                    else:
                        # Add the node in the graph
                        self.graph.add_node((node, k), info=[(i, j)], label=token.lower())

                        # Mark the word as mapped to k
                        mapping[j] = (node, k)

            # -------------------------------------------------------------------
            # 5. 添加边,通过为当前结点与其所有后继结点加边来解决边的稀疏性问题,确保无环
            # -------------------------------------------------------------------
            for pre in range(0, len(mapping) - 1):

                for pos in range(pre + 1, len(mapping)):

                    self.graph.add_edge(mapping[pre], mapping[pos])

                    # 判定是否有环
                    try:
                        # find_cycle在无环的情况下会抛出异常
                        nx.find_cycle(self.graph, source=mapping[pre], orientation='original')

                        # 没有异常,说明有环,移出刚刚添加的边
                        self.graph.remove_edge(mapping[pre], mapping[pos])

                    except:
                        # 无环
                        pass

        # 计算每条边对应的权值
        for node1, node2 in self.graph.edges_iter():
            self.graph.add_edge(node1, node2, weight=self.cal_edge_weight(node1, node2))
Example #53
0
#rosalind_pcov

import networkx as nx


# create de Bruijn graph
G = nx.DiGraph()
for l in open('rosalind_pcov.txt'):
    u = l.rstrip()
    G.add_edge(u[:-1], u[1:], label=u)

result = ''
for edge in nx.find_cycle(G):
    result += edge[0][0]

print(result)
open('rosalind_pcov_sub.txt', 'wt').write(result)

Example #54
0
def is_acyclic(g: Graph) -> bool:
    try:
        cycle = find_cycle(g)
    except NetworkXNoCycle:
        return True
    return False