示例#1
0
    def test_is_eulerian(self):
        assert_true(is_eulerian(nx.complete_graph(5)))
        assert_true(is_eulerian(nx.complete_graph(7)))
        assert_true(is_eulerian(nx.hypercube_graph(4)))
        assert_true(is_eulerian(nx.hypercube_graph(6)))

        assert_false(is_eulerian(nx.complete_graph(4)))
        assert_false(is_eulerian(nx.complete_graph(6)))
        assert_false(is_eulerian(nx.hypercube_graph(3)))
        assert_false(is_eulerian(nx.hypercube_graph(5)))

        assert_false(is_eulerian(nx.petersen_graph()))
        assert_false(is_eulerian(nx.path_graph(4)))
示例#2
0
    def test_is_eulerian(self):
        assert nx.is_eulerian(nx.complete_graph(5))
        assert nx.is_eulerian(nx.complete_graph(7))
        assert nx.is_eulerian(nx.hypercube_graph(4))
        assert nx.is_eulerian(nx.hypercube_graph(6))

        assert not nx.is_eulerian(nx.complete_graph(4))
        assert not nx.is_eulerian(nx.complete_graph(6))
        assert not nx.is_eulerian(nx.hypercube_graph(3))
        assert not nx.is_eulerian(nx.hypercube_graph(5))

        assert not nx.is_eulerian(nx.petersen_graph())
        assert not nx.is_eulerian(nx.path_graph(4))
示例#3
0
 def test_is_eulerian2(self):
     # not connected
     G = nx.Graph()
     G.add_nodes_from([1, 2, 3])
     assert not nx.is_eulerian(G)
     # not strongly connected
     G = nx.DiGraph()
     G.add_nodes_from([1, 2, 3])
     assert not nx.is_eulerian(G)
     G = nx.MultiDiGraph()
     G.add_edge(1, 2)
     G.add_edge(2, 3)
     G.add_edge(2, 3)
     G.add_edge(3, 1)
     assert not nx.is_eulerian(G)
示例#4
0
 def test_is_eulerian2(self):
     # not connected
     G = nx.Graph()
     G.add_nodes_from([1,2,3])
     assert_false(is_eulerian(G))
     # not strongly connected
     G = nx.DiGraph()
     G.add_nodes_from([1,2,3])
     assert_false(is_eulerian(G))
     G = nx.MultiDiGraph()
     G.add_edge(1,2)
     G.add_edge(2,3)
     G.add_edge(2,3)
     G.add_edge(3,1)
     assert_false(is_eulerian(G))
示例#5
0
 def is_eulerian(self):
     eulerian = nx.is_eulerian(self.graph)
     print(self.graph)
     if eulerian:
         print("Graph is eulerian")
     else:
         print("Graph is not eulerian")
示例#6
0
def get_eulerian(edict):
    G = nx.DiGraph(edict)
    if (not nx.is_eulerian(G)):
        out_degrees = G.out_degree([node for node in G])
        in_degrees = G.in_degree([node for node in G])
        ds = [out_degrees, in_degrees]
        d = {}
        out_degree_dict = dict(out_degrees)
        for k in out_degree_dict.keys():
            d[k] = tuple(d[k] for d in ds)
        for key in d:
            d[key] = d[key][0] - d[key][1]
        extra_out = [key for (key, value) in d.items() if value == 1][0]
        extra_in = [key for (key, value) in d.items() if value == -1][0]

        G.add_edge(extra_in, extra_out)

        euler = list(nx.eulerian_circuit(G, source=extra_out))
        index = euler.index((extra_in, extra_out))
        blah = euler[index + 1:] + euler[:index]

        path = []
        path = blah[0][0] + sign + blah[0][1]
        for line in blah[1:]:
            path = path + (sign + line[1])
    else:
        eulerian = list(nx.eulerian_circuit(G))
        path = eulerian[0][0] + sign + eulerian[0][1]
        for line in eulerian[1:]:
            path = path + (sign + line[1])

    return path
示例#7
0
    def determine_combinations(self):

        log.info('eulerian=%s, odd_ndoes=%s', nx.is_eulerian(self.g), len(self.odd_nodes))

        odd_node_pairs = self.get_pair_combinations(self.odd_nodes)

        log.info('combinations=%s', len(odd_node_pairs))

        odd_pair_paths = self.get_shortest_path_pairs(self.g, odd_node_pairs)

        # XXX - this part doesn't work well because it doesn't
        # consider the direction of the paths.

        # create another graph off odd pairs.. using negative weights
        # because we want minimum distances but only maximum algorithm
        # exists in networkx.

        self.g_odd_nodes = nx.Graph()

        for k, length in odd_pair_paths.items():
            i,j = k
            attrs = {
                'length': length,
                'weight': -length,
            }

            self.g_odd_nodes.add_edge(i, j, **attrs)
            pass

        log.info('new_nodes=%s, edges=%s, eulerian=%s', self.g_odd_nodes.order(), self.g_odd_nodes.size(), nx.is_eulerian(self.g_odd_nodes))

        log.info('calculating max weight matching - this can also take a while')

        return
示例#8
0
    def augment_graph(self, g, pairs):

        # create a new graph and stuff in the new fake/virtual edges
        # between odd pairs.  Generate the edge metadata to make them
        # look similar to the native edges.

        graph_aug = g.copy()

        log.info('(augmented) eulerian=%s', nx.is_eulerian(graph_aug))

        for i, pair in enumerate(pairs):
            a, b = pair

            length, path = nx.single_source_dijkstra(g, a, b, weight='length')

            log.debug('PAIR[%s] nodes = (%s,%s), length=%s, path=%s', i, a, b, length, path)

            linestring = self.path_to_linestring(graph_aug, path)

            # create a linestring of paths...

            data = {
                'length': length,
                'augmented': True,
                'path': path,
                'geometry': linestring,
                'from': a,
                'to': b,
            }
            log.debug('  creating new edge (%s,%s) - data=%s', a, b, data)

            graph_aug.add_edge(a, b, **data)
            pass

        return graph_aug
示例#9
0
def pair_composition(pair_mers):

    g = nx.DiGraph()

    for kmer in pair_mers:

        k1,k2 = kmer.split('|')

        pre1 = k1[:-1]
        pre2 = k2[:-1]
        suf1 = k1[1:]
        suf2 = k2[1:]

        n1 = '%s,%s' % (pre1,pre2)
        n2 = '%s,%s' % (suf1,suf2)

        if n1 not in g:
            g.add_node(n1)
        if n2 not in g:
            g.add_node(n2)

        g.add_edge(n1, n2, label=kmer)

    for n in g.nodes():
        in_deg = len(g.predecessors(n))
        out_deg = len(g.successors(n))
        print 'node %s: in=%d, out=%d' % (n, in_deg, out_deg)

    print 'Pair composition: is_eulerian=%d' % (nx.is_eulerian(g))

    return g
示例#10
0
    def augment_graph(self, g, pairs):

        graph_aug = g.copy()

        log.info('(augmented) eulerian=%s', nx.is_eulerian(graph_aug))

        for i, pair in enumerate(pairs):
            a, b = pair

            length, path = nx.single_source_dijkstra(g, a, b, weight='length')

            log.debug('PAIR[%s] nodes = (%s,%s), length=%s, path=%s', i, a, b, length, path)

            linestring = self.path_to_linestring(graph_aug, path)

            # create a linestring of paths...

            data = {
                'length': length,
                'augmented': True,
                'path': path,
                'geometry': linestring,
                'from': a,
                'to': b,
            }
            log.debug('  creating new edge (%s,%s) - data=%s', a, b, data)

            graph_aug.add_edge(a, b, **data)
            pass

        return graph_aug
示例#11
0
文件: graph.py 项目: nagyist/bio
def euler_path2(graph: dict) -> list:
    nx_graph = build_di_graph(graph)
    edge = balance_graph(nx_graph)
    if not nx.is_eulerian(nx_graph):
        raise ValueError("Not Eulerian: {0}".format(graph))

    return eulerian_cycle(build_dict_graph(nx_graph), edge[1])
示例#12
0
    def compute_features(self):

        # checking if eulerian
        self.add_feature(
            "eulerian",
            lambda graph: nx.is_eulerian(graph) * 1,
            "A graph is eulerian if it has a eulerian circuit: a closed walk that includes \
            each edges of the graph exactly once",
            InterpretabilityScore(3),
        )

        # checking if semi eulerian
        self.add_feature(
            "semi_eulerian",
            lambda graph: nx.is_semieulerian(graph) * 1,
            "A graph is semi eulerian if it has a eulerian path but no eulerian circuit",
            InterpretabilityScore(3),
        )

        # checking if eulerian path exists
        self.add_feature(
            "semi_eulerian",
            lambda graph: nx.has_eulerian_path(graph) * 1,
            "Whether a eulerian path exists in the network",
            InterpretabilityScore(3),
        )
示例#13
0
def network_links_andEulerian_check():
    '''For Eulerian cycle and path analyses'''
    '''There are two parts to this function'''
    '''Part 1 - Network construction and visualisation'''

    # Network details
    a = input('Give the name for your network : ')
    b = (input('Enter the nodes for your network (separated by commas) : ')
         ).split(',')
    c = int(input('How many links will your network have? '))
    d = "Enter one link connecting two nodes in the following manner: For example, if linking 'A' to 'B', type, 'A' LINK 'B' : "
    e = [list(input(d)) for _ in [0] * c]
    f = []

    # Processing of input data so that it is suitable for nx
    for i in e:
        g = (''.join(i)).replace('LINK'.upper(), ',')
        f.append(g)

    # Final pre-nx processing before transferring to nx for further handling
    G = nx.Graph()
    G.add_nodes_from(b)
    for i in f:
        eval("G.add_edge(" + i + ")")

    nx.draw(G, with_labels=True)
    plt.savefig(a + '.png')
    plt.show()
    '''Part 2 - Eulerian cycle and path analyses of network'''

    # For the logic behind the code for the analyses, see the illustrations at:
    # https://www.geeksforgeeks.org/eulerian-path-and-circuit/
    h = G.degree(b)
    j = []

    for i in h:
        if (i[1]) % 2 != 0: j.append(i[1])

    if nx.is_eulerian(G) == True and len(j) == 0:
        print('The network has a Eulerian cycle.')
    elif nx.is_eulerian(G) == False and len(j) == 2:
        print('The network has a Eulerian path.')
    elif nx.is_eulerian(G) == False and (len(j) != 0 or len(j) != 2):
        print('The network neither has a Eulerian path or Eulerian cycle.')

    print(h)
示例#14
0
文件: graf.py 项目: konx8/Graf-Python
def drow_war():
    if nx.is_eulerian(G) == True:
        warunki = Label(window, text="Warunek Eulera spełniony")
        warunki.grid(row=5, column=4)
        button_Eul.config(state="normal")
    else:
        warunki = Label(window, text="Warunek Eulera niespelniony")
        warunki.grid(row=5, column=4)
示例#15
0
 def __init__(self, scaffold_graph):
     print "Entering PathFinder module:", str(datetime.now())
     self.G = scaffold_graph.copy()
     #Build strandless list of sequences
     sequences = set([n for n in self.G.nodes() if n > 0])
     #Define weakly connected components
     print "1... Defining weakly connected components"
     component_graphs = set([g for g in nx.weakly_connected_component_subgraphs(self.G)])
     single_node_graphs = set([g for g in component_graphs if len(g.nodes()) == 1])
     multi_node_graphs = set([g for g in component_graphs if len(g.nodes()) > 1])
     print "Number of single-node components:", len(single_node_graphs)
     print "Number of multi-node components:", len(multi_node_graphs)
     #Consolidate unscaffolded nodes, discard reverse strand
     print "2... Consolidating single-node components"
     unscaffolded = set([g.nodes()[0] for g in single_node_graphs])
     discard_nodes = set([n for n in unscaffolded if n < 0])
     for g in iter(single_node_graphs.copy()):
         if g.nodes()[0] in discard_nodes:
             single_node_graphs.discard(g)
     print "Number of unscaffolded sequences:", len(single_node_graphs)
     #Classify multi-node graphs
     print "3... Classifying multi-node components"
     DAG = set([])
     Euler = set([])
     for g in multi_node_graphs:
         if nx.is_directed_acyclic_graph(g):
             DAG.add(g)
         elif nx.is_eulerian(g):
             Euler.add(g)
         else:
             sys.exit("FATAL ERROR: Unknown multi-node graph type!")
     print "Number of directed acyclic graphs:",  len(DAG)
     print "Number of Eulerian graphs:", len(Euler)
     #Build scaffolds from DAGs
     print "4... Building scaffolds from directed acyclic graphs"
     self.scaffolds = set([])
     for g in DAG:
         self.build_dag_scaffold(g)
     #Consolidating complementary scaffolds, keep first found
     print "5... Consolidating complementary scaffolds"
     consolidated_scaff = set([])
     for seq in iter(self.scaffolds):
         comp = self.revc(seq)
         if comp in self.scaffolds:
             if comp not in consolidated_scaff:
                 consolidated_scaff.add(seq)
         else:
             print "WARNING: non-complemented scaffold"
     self.scaffolds = consolidated_scaff
     print "Number of scaffolds assembled:", len(self.scaffolds)
     #Build scaffolds from Eulerian graphs
     
     #Add unscaffolded seqs to scaffolds list
     print "6... Adding unscaffolded sequences to output"
     for g in single_node_graphs:
         seq = self.G.node[g.nodes()[0]]['seq']
         self.scaffolds.add(seq)
     print "Leaving PathFinder module:", str(datetime.now())
示例#16
0
文件: graph.py 项目: nagyist/bio
def euler_path(graph: nx.DiGraph, func=genome_path_string) -> list:
    edge = balance_graph(graph)
    if not nx.is_eulerian(graph):
        raise ValueError("Not Eulerian: {0}".format(graph))

    circuit = list(nx.eulerian_circuit(graph, edge[1]))
    #print("asdf {0}".format(circuit))
    #return [ func(x) for x in circuit ]
    return [x[0] for x in circuit] + [ circuit[0][0] ]
示例#17
0
    def planning(self, ):
        """
        """
        print('--------------------------------------------------')
        print('(i) Make initial graph')
        self.G = nx.Graph()
        self.G = self.delaunay_network()
        print('|V|=', self.G.number_of_nodes())
        print('|E|=', self.G.number_of_edges())
        # draw initial graph G
        # nx.draw_networkx(self.G, pos=self.pos, ax=self.ax_G)
        """
    """
        print('--------------------------------------------------')
        print('(ii) Modify to be Eulerian')
        self.Ge = nx.MultiGraph()
        self.Ge, odd_nodes, M = self.chinese_postmap_problem(self.G)
        print('|Ve|=', self.Ge.number_of_nodes())
        print('|Ee|=', self.Ge.number_of_edges())
        # draw odd nodes on G
        nx.draw_networkx_nodes(
            self.G,
            pos=self.pos,
            nodelist=odd_nodes,
            node_color='r',
            ax=self.ax_G,
        )
        # draw Eulerian graph Ge
        # nx.draw_networkx_edges(self.G,
        #                        pos=self.pos,
        #                        edgelist=M,
        #                        edge_color='r',
        #                        ax=self.ax_G,)

        if not nx.is_eulerian(self.Ge):
            print('Not Eulerian')
            sys.exit(-1)

        eularian_circuit = list(nx.eulerian_circuit(self.Ge, 0))
        print('Eularian circuit ==>')
        print(eularian_circuit)
        """
    """
        print('--------------------------------------------------')
        print('(iii) Compute Hamiltonian circuit (way points)')
        way_points = [self.h(e[0], e[1]) for e in eularian_circuit]
        way_points = [[round(p[0], 2), round(p[1], 2)] for p in way_points]
        way_points.append(way_points[0])
        # print(way_points)

        shift_way_points = way_points[1:] + way_points[:1]
        L = 0.0
        for i, j in zip(way_points, shift_way_points):
            # print(i,j)
            L = L + distance.euclidean(i, j)
        print(L)
        return way_points
示例#18
0
def eulerian_path(edge_dict):
    '''Generates an Eulerian cycle from the given edges.'''
    G = nx.DiGraph(edge_dict)
    if not (nx.is_eulerian(G)):
        out_degrees = G.out_degree([node for node in G])
        in_degrees = G.in_degree([node for node in G])
        ds = [out_degrees, in_degrees]
        d = {}
        for k in out_degrees.keys():
            d[k] = tuple(d[k] for d in ds)
        for key in d:
            d[key] = d[key][0] - d[key][1]
        extra_out = [key for (key, value) in d.items() if value == 1][0]
        extra_in = [key for (key, value) in d.items() if value == -1][0]
        edge_dict[extra_in] = extra_out
        current_node = extra_out
    else:
        current_node = next(iter(edge_dict.keys()))
    path = [current_node]

    # Get the initial cycle.
    while True:
        path.append(edge_dict[current_node][0])

        if len(edge_dict[current_node]) == 1:
            del edge_dict[current_node]
        else:
            edge_dict[current_node] = edge_dict[current_node][1:]

        if path[-1] in edge_dict:
            current_node = path[-1]
        else:
            break

    # Continually expand the initial cycle until we're out of edge_dict.
    while len(edge_dict) > 0:
        for i in range(len(path)):
            if path[i] in edge_dict:
                current_node = path[i]
                cycle = [current_node]
                while True:
                    cycle.append(edge_dict[current_node][0])

                    if len(edge_dict[current_node]) == 1:
                        del edge_dict[current_node]
                    else:
                        edge_dict[current_node] = edge_dict[current_node][1:]

                    if cycle[-1] in edge_dict:
                        current_node = cycle[-1]
                    else:
                        break

                path = path[:i] + cycle + path[i + 1:]
                break
    return path
示例#19
0
def check_graph(graph, shape, max_stitch_length):
    if networkx.is_empty(graph) or not networkx.is_eulerian(graph):
        if shape.area < max_stitch_length**2:
            message = "This shape is so small that it cannot be filled with rows of stitches.  " \
                      "It would probably look best as a satin column or running stitch."
            raise InvalidPath(_(message))
        else:
            message = "Cannot parse shape.  " \
                      "This most often happens because your shape is made up of multiple sections that aren't connected."
            raise InvalidPath(_(message))
示例#20
0
def eulerian_path(G, source=None, keys=False):
    """Return an iterator over the edges of an Eulerian path in `G`.

    Parameters
    ----------
    G : NetworkX Graph
        The graph in which to look for an eulerian path.
    source : node or None (default: None)
        The node at which to start the search. None means search over all
        starting nodes.
    keys : Bool (default: False)
        Indicates whether to yield edge 3-tuples (u, v, edge_key).
        The default yields edge 2-tuples

    Yields
    ------
    Edge tuples along the eulerian path.

    Warning: If `source` provided is not the start node of an Euler path
    will raise error even if an Euler Path exists.
    """
    if not has_eulerian_path(G, source):
        raise nx.NetworkXError("Graph has no Eulerian paths.")
    if G.is_directed():
        G = G.reverse()
        if source is None or nx.is_eulerian(G) is False:
            source = _find_path_start(G)
        if G.is_multigraph():
            for u, v, k in _multigraph_eulerian_circuit(G, source):
                if keys:
                    yield u, v, k
                else:
                    yield u, v
        else:
            yield from _simplegraph_eulerian_circuit(G, source)
    else:
        G = G.copy()
        if source is None:
            source = _find_path_start(G)
        if G.is_multigraph():
            if keys:
                yield from reversed([
                    (v, u, k)
                    for u, v, k in _multigraph_eulerian_circuit(G, source)
                ])
            else:
                yield from reversed([
                    (v, u)
                    for u, v, k in _multigraph_eulerian_circuit(G, source)
                ])
        else:
            yield from reversed([
                (v, u) for u, v in _simplegraph_eulerian_circuit(G, source)
            ])
示例#21
0
 def eulerian_Detector(self):
     """
     Для неориентированного графа
     if self._edges_value > 0:
         graph = copy.deepcopy(self._edges) # Буферный граф
         odd = [ vertex for vertex in graph.keys() if len(graph[vertex]) & 1 ]
         keys = []
         for key in graph.keys():
             keys.append(key)
         odd.append(keys[0])
         if len(odd) > 3:
             print("Граф не содержит Эйлерова цикла")
             print("")
             return
         stack = [ odd[0] ]
         path = []
         # Цикл обхода графа
         while stack:
             vertex = stack[-1]
             if graph[vertex]:
                 jertex = graph[vertex][0]
                 stack.append(jertex)
                 del graph[jertex][ graph[jertex].index(vertex) ]
                 del graph[vertex][0]
             else:
                 path.append(stack.pop())
         print("Эйлеров цикл в введенном графе: ")
         print (str(path))
         print("")
         return path      
     else:
         print("Граф пуст")
         print("")
     """
     # Для всех типов графов:
     if self._edges_value > 0:
         G = nx.DiGraph()
         for vertex in self._edges.keys():
             values = self._edges[vertex]
             for value in values:
                 G.add_edge(vertex, value)
         if nx.is_eulerian(G):
             print("Граф содержит Эйлеров цикл")
             print("Эйлеров цикл в введенном графе: ")
             print (str(list(nx.eulerian_circuit(G))))
             print("")
             return list(nx.eulerian_circuit(G))    
         else:
             print("Граф не содержит Эйлеров цикл")
             print("")
     else:
         print("Граф пуст")
         print("")
         
示例#22
0
def find_eulerian_path_same_startend(graph, start):
    ''' Finds an eulerian path in the graph that returns to the starting point'''
    if nx.is_eulerian(graph) == False:
        print 'Graph is not eulerian, aborting'
        return

    eulerian_edge_path = nx.eulerian_circuit(graph, source=start)
    path = []
    for edge in eulerian_edge_path:
        path.append(edge[0])
    path.append(edge[1])
    return path
示例#23
0
def christofides(graph_x, subset_graph):
    t0 = time.clock()
    # ******* PHASE 1 ********
    # Make graph_x complete with shortest path between nodes for missing edges
    graph_comp = make_complete(subset_graph, graph_x)
    new_edges = missing_edges(subset_graph)
    simplified = simplify_complete(graph_comp,new_edges)

    # ******* PHASE 2 *******
    matching_edges = match_components(subset_graph, simplified, graph_x)
    # Add component matching edges to Gr
    subset_plus_comp = subset_graph.copy()
    for edge in matching_edges:
        subset_plus_comp.add_weighted_edges_from([(edge[0],edge[1],
            simplified[edge[0]][edge[1]]['weight'])])

    perfect_matching = call_blossom(subset_plus_comp,graph_x)
    final = nx.MultiGraph(subset_plus_comp)


    for edge in perfect_matching:

        # If edge exists in original graph:
        if graph_x.has_edge(*edge):
            final.add_weighted_edges_from([(edge[0],edge[1], 
                graph_x[edge[0]][edge[1]]['weight'])])
        # Else get shortest path between them and replace
        else:
            final.add_weighted_edges_from(shortest_path_edges(edge[0],edge[1],graph_x))

    if nx.is_eulerian(final):
        tour = list(nx.eulerian_circuit(final))
        t1 = time.clock()
        results = list()
        results.append(tour_cost(tour, graph_comp))
        runtime = t1 - t0
        results.append(runtime)
        results.append(tour_cost(tour, graph_comp))
        results.append(runtime)
        results.append(check_solution(tour,graph_x,subset_graph))
        print(tour)
        print(results)
    else:
	results = list()
	t1 = time.clock()
        results.append(0)
        runtime = t1 - t0
        results.append(runtime)
        results.append(0)
        results.append(runtime)
        results.append(False)
    return results
示例#24
0
def circuito_euleriano(graph):
	G = None
	# print("graph é euleriano? ", nx.is_eulerian(graph))
	if not nx.is_eulerian(graph):
		G = eulerize(graph)

	circuito = list(nx.eulerian_circuit(G))
	nos = []
	for u, v in circuito:
		nos.append(u)

	nos.append(circuito[0][0])
	return nos
def UndirectedGraphFeature(df, dfOrigin, part):
    indexs, files = df.index, dfOrigin.file_id.unique()
    for col in apiSet:
        df[col+'_center_degree'] = 0

    for index, file in zip(indexs, files):
        X = pd.read_csv('./' + part + '/' + str(index) + '.csv')
        api = X.groupby(by='tid').apply(lambda x: ' '.join(x.api))
        api = pd.DataFrame(api)
        api.rename(columns={0: 'api_call'}, inplace=True)

        G = nx.Graph()
        for row in api.index:
            apiCall = (api.loc[row, 'api_call']).split(' ')
            for i in range(len(apiCall) - 1):
                G.add_edge(apiCall[i], apiCall[i + 1])
        if (len(G) <= 1):
            continue
        isConnnected = (nx.is_connected(G) == False)
        if isConnnected:
            df.loc[index, 'avg_length'] = -1
            df.loc[index, 'minimum_edge_cut'] = -1
            df.loc[index, 'degree_assortativity_coefficient'] = -1
            df.loc[index, 'radius'] = -1
            df.loc[index, 'diameter'] = -1
            df.loc[index, 'periphery'] = -1
            df.loc[index, 'is_eulerian'] = -1
            df.loc[index, 'center'] = -1
            df.loc[index, 'order'] = -1
            df.loc[index, 'size'] = -1
            df.loc[index, 'density'] = -1

        else:
            df.loc[index, 'avg_length'] = nx.average_shortest_path_length(G)
            df.loc[index, 'minimum_edge_cut'] =  len(set(nx.minimum_edge_cut(G)))
            df.loc[index, 'degree_assortativity_coefficient'] = nx.degree_assortativity_coefficient(G)
            df.loc[index, 'radius'] = nx.radius(G)
            df.loc[index, 'diameter'] = nx.diameter(G)
            df.loc[index, 'periphery'] = len(set(nx.periphery(G)))
            df.loc[index, 'is_eulerian'] = int(nx.is_eulerian(G))
            df.loc[index, 'center'] =  len(set(nx.center(G)))
            df.loc[index, 'density'] = nx.density(G)
            df.loc[index, 'order'] = G.order()
            df.loc[index, 'size'] = G.size()

        if not isConnnected:
            for x in set(nx.center(G)):
                df.loc[index,x+'_center_degree'] = 1
        print(index)
    return df
示例#26
0
    def determine_combinations(self):

        log.info('eulerian=%s, odd_nodes=%s', nx.is_eulerian(self.g),
                 len(self.odd_nodes))

        odd_node_pairs = self.get_pair_combinations(self.odd_nodes)

        log.info('combinations=%s', len(odd_node_pairs))

        odd_pair_paths = self.get_shortest_path_pairs(self.g, odd_node_pairs)

        # XXX - this part doesn't work well because it doesn't
        # consider the direction of the paths.

        # create a temporary graph of odd pairs.. really we should be
        # doing the combination max calculations here.

        self.g_odd_nodes = nx.Graph()

        for k, length in odd_pair_paths.items():
            i, j = k
            attrs = {
                'length': length,
                'weight': -length,
            }

            self.g_odd_nodes.add_edge(i, j, **attrs)
            pass

        log.info('new_nodes=%s, edges=%s, eulerian=%s',
                 self.g_odd_nodes.order(), self.g_odd_nodes.size(),
                 nx.is_eulerian(self.g_odd_nodes))

        log.info(
            'calculating max weight matching - this can also take a while')

        return
示例#27
0
def main():
    genome = 'ATGGCGTGCA'
    kmers = []
    k = 3
    for i in range(len(genome) - k + 1):
        kmers.append(genome[i:i+k])
    Graph = nx.DiGraph()
    for i in kmers:
        Graph.add_edge(i[0:2], i[1:3])

    nx.draw(Graph)
    plt.show()
    for i in Graph.nodes():
        if Graph.in_degree(i) != Graph.out_degree(i):
            print "Node %s is unbalanced" % i
        if Graph.in_degree(i) - Graph.out_degree(i) == 1:
            end = i
            print "Node %s is the End node" % i
        if Graph.in_degree(i) - Graph.out_degree(i) == -1:
            start = i
            print "Node %s is the Start node" % i
    print "Is this Graph Eulerian ? - %s" % nx.is_eulerian(Graph)
    Graph.add_edge(end, start)
    print "I have made some changes, is this Graph Eulerian now ? - %s" % nx.is_eulerian(Graph)

    MaxOutDegree = -1
    for i in Graph.nodes():
        MaxOutDegree = Graph.out_degree(i) if Graph.out_degree(i) > MaxOutDegree else -1
    paths = []

    while len(paths) < MaxOutDegree:
        temp = []
        TempGraph = Graph.copy()
        path = FindEulerianCycles(TempGraph, start, temp, end)
        if path not in paths and len(path) > 0:
            paths.append(path)
    print paths
示例#28
0
文件: euler.py 项目: eah13/bioalgo
def euler(Graph):
	global start
	global finish
	find_balance(Graph)
	path=[]
	if nx.is_eulerian(Graph):
		circuit=list(nx.eulerian_circuit(Graph, start))
		for edge in circuit:
			current=Graph.edge[edge[0]][edge[1]]['label']
			if current != None:
				path.append(current)
		if unbalanced==0:
			finish=circuit.pop()[1]
		answer=start, path, finish
		print answer
		
	else: 
		none()
示例#29
0
    def determine_circuit(self):

        odd_matching = nx.algorithms.max_weight_matching(self.g_odd_nodes, True)

        log.info('len(odd_matching)=%s', len(odd_matching))
        log.debug('odd_matching=%s', odd_matching)

        log.info('augment original')

        self.g_augmented = self.augment_graph(self.g, odd_matching)

        start_node = self.get_start_node(self.g, self.start)

        log.info('(augmented) eulerian=%s', nx.is_eulerian(self.g_augmented))

        self.euler_circuit = list(nx.eulerian_circuit(self.g_augmented, source=start_node))

        return
def write_graph_info_to_file(G, graph_name=GRAPH_NAME):
    with open("{}_info".format(graph_name), "w") as report_file:
        try:
            report_file.write("Number of nodes: {}\n".format(
                G.number_of_nodes()))
            report_file.write("Number of edges: {}\n".format(
                G.number_of_edges()))
            write_components_info(G, report_file)
            write_distance_info(G, report_file)
            write_dag_info(G, report_file)
            report_file.write("Is Eulerian: {}\n".format(nx.is_eulerian(G)))
            report_file.write("Density: {}\n".format(nx.density(G)))
            report_file.write("Flow hierarchy: {}\n".format(
                nx.flow_hierarchy(G)))
            report_file.write("----INFO FROM NETWORKX----\n")
            report_file.write("{}\n".format(nx.info(G)))
        except ZeroDivisionError as e:
            report_file.write("Zero Division: {}".format(e))
示例#31
0
    def euler_circ(self, graphe):
        """
		Cette fonction prend en paramètre un graphe et retourne un tuple constitué de la liste d'aretes et
		la liste de sommets dans l'ordre de parcours du circuit euleurien; ou -1 si le graphe n'est euleurian.
		:param netW:
		:param graphe:
		:return:
		"""
        if nx.is_eulerian(graphe):
            aretes_euler = list(nx.eulerian_circuit(graphe))
            sommets_euler = [aretes_euler[0][0]]
            for arete in aretes_euler:
                for sommet in arete:
                    if sommet != sommets_euler[-1]:
                        sommets_euler.append(sommet)
            return aretes_euler, sommets_euler
        else:
            return -1, -1
示例#32
0
 def find_euler_tour(self, nx_euler=False):
     h = nx.MultiGraph()
     h.add_edges_from(self.mst.edges())
     h.add_edges_from(self.m.edges())
     if not nx.is_eulerian(h):
         raise ValueError('h must be eulerian')
     print "find euler tour"
     t1 = time.time()
     if nx_euler:
         euler_edges = nx.eulerian_circuit(h)
         self.euler_path = [e for e in euler_edges]
     else:
         self.euler_path = self.build_euler_tour(h)
     t2 = time.time()
     print "took %s" % (t2 - t1)
     print "euler path: ", self.euler_path
     print '#edges:', len(self.euler_path), '#nodes:', len(h.nodes())
     self.plot_edges(self.euler_path, 'c--', 2)
     self.h = h
示例#33
0
 def find_euler_tour(self, nx_euler=False):
     h = nx.MultiGraph()
     h.add_edges_from(self.mst.edges())
     h.add_edges_from(self.m.edges())
     if not nx.is_eulerian(h):
         raise ValueError('h must be eulerian')
     print "find euler tour"
     t1 = time.time()
     if nx_euler:
         euler_edges = nx.eulerian_circuit(h)
         self.euler_path = [e for e in euler_edges]
     else:
         self.euler_path = self.build_euler_tour(h)
     t2 = time.time()
     print "took %s" % (t2-t1) 
     print "euler path: ", self.euler_path
     print '#edges:', len(self.euler_path), '#nodes:', len(h.nodes())
     self.plot_edges(self.euler_path,'c--',2)
     self.h = h
示例#34
0
    def compute(cls, graph: nx.Graph, depot_index: int):
        """

        :param graph: the graph where compute the TSP tour
        :param: depot_index : the index of node which is referred as depot (start and end of the tour)
        :return: the tsp Tour [e1,e2,...,en] with e1 with indexes of graph
        """
        graph = graph.copy()

        # first step -> MST of graph
        mst = nx.minimum_spanning_tree(graph)

        # even
        odd_nodes = Christofides.odd_nodes(mst)

        # induced subgraph of odd nodes
        odd_graph = graph.subgraph(odd_nodes).copy()

        # minimum weighted matching
        perfect_match = Christofides.min_weight_matching(odd_graph)

        # build Eulerian Graph: mst + perfect match
        eu_graph = nx.MultiGraph()
        for e0, e1 in list(mst.edges) + list(perfect_match):
            eu_graph.add_node(e0, pos=graph.nodes[e0]["pos"])
            eu_graph.add_node(e1, pos=graph.nodes[e1]["pos"])
            eu_graph.add_edge(e0, e1, weight=graph.edges[e0, e1]["weight"])

        # Assert a eulerian graph
        assert nx.is_eulerian(
            eu_graph
        ), "The mst + perfect matching of Christofides -> not an eulerian graph "

        # eulerian tour
        eu_tour = list(
            nx.eulerian_circuit(eu_graph, source=depot_index, keys=False))

        # shortcut tour to have a 1.5-TSP
        tsp_tour = Christofides.shorted_tour(eu_tour)
        return tsp_tour
示例#35
0
def travelingSalesman(G, vertices, start):
    """
    Christofides' algorithm to approximate tsp
    """
    vertices = vertices[:]
    vertices = list(set(sorted(vertices)))
    mst_edges = MST(G, vertices)
    mst_graph = nx.MultiGraph()
    mst_graph.add_nodes_from(vertices)
    mst_graph.add_edges_from(mst_edges)

    O = []
    for v in vertices:
        if mst_graph.degree(v) % 2 == 1:
            O.append(v)

    m = G.subgraph(O).copy()
    for u, v, data in m.edges(data=True):
        data['weight'] *= -1

    P = nx.algorithms.matching.max_weight_matching(m,
                                                   maxcardinality=True,
                                                   weight="weight")
    for u, v in P:
        a = len(mst_graph.edges())
        mst_graph.add_edge(u, v, weight=getWeight(G, u, v))

    ret = []
    seen = set()
    assert nx.is_eulerian(mst_graph)
    for u, v in nx.eulerian_circuit(mst_graph, source=start):
        if u not in seen:
            ret.append(u)
            seen.add(u)
    ret.append(start)
    return ret
示例#36
0
def print_is_of_type_attrs(graph):
	print("\n====== is of type X? ======")
	print("Directed? ->", "Yes" if nx.is_directed(graph) else "No")
	print("Directed acyclic? ->", "Yes" if nx.is_directed_acyclic_graph(graph) else "No")
	print("Weighted? ->", "Yes" if nx.is_weighted(graph) else "No")

	if nx.is_directed(graph):
		print("Aperiodic? ->", "Yes" if nx.is_aperiodic(graph) else "No")
		print("Arborescence? ->", "Yes" if nx.is_arborescence(graph) else "No")
		print("Weakly Connected? ->", "Yes" if nx.is_weakly_connected(graph) else "No")
		print("Semi Connected? ->", "Yes" if nx.is_semiconnected(graph) else "No")
		print("Strongly Connected? ->", "Yes" if nx.is_strongly_connected(graph) else "No")

	else:
		print("Connected? ->", "Yes" if nx.is_connected(graph) else "No")		
		print("Bi-connected? ->", "Yes" if nx.is_biconnected(graph) else "No")
		if not graph.is_multigraph():
			print("Chordal? -> ", "Yes" if nx.is_chordal(graph) else "No")
			print("Forest? -> ", "Yes" if nx.is_chordal(graph) else "No")

	print("Distance regular? -> ", "Yes" if nx.is_distance_regular(graph) else "No")
	print("Eulerian? -> ", "Yes" if nx.is_eulerian(graph) else "No")
	print("Strongly regular? -> ", "Yes" if nx.is_strongly_regular(graph) else "No")
	print("Tree? -> ", "Yes" if nx.is_tree(graph) else "No")
示例#37
0
print("Standard Deviation of Node Degree: {0:.2}".format(standardDeviation))
###Displaying probability distribution of Node Degree
plt.figure(4)
plt.title('Node Degree Histogram of Undirected Graph')
plt.hist(ug.degree, bins=100)

# Part A: Analysis of Connected Components
print("The Amount of Connected Components: ",
      nx.number_connected_components(ug))
ccs = [
    len(c) for c in sorted(nx.connected_components(ug), key=len, reverse=True)
]
print("Largest Connected Component: ", ccs[0])
print("Smallest Connected Component: ", ccs[-1])
# Part E: Euler Network
print("Is subnetwork 1 Eularian? ", nx.is_eulerian(separate1))
print("Is subnetwork 2 Eularian? ", nx.is_eulerian(separate2))
# Part H: Minimum Spanning tree of network (ug) and largest CC (separate1)
a = nx.minimum_spanning_tree(ug)
print("Is tree?", nx.is_tree(a))
print("Is forest?", nx.is_forest(a))
separate1.remove_edge(3, 11)
b = nx.minimum_spanning_tree(separate1)
print("Removed edge from largest CC")
print("Is tree?", nx.is_tree(b))
print("Is forest?", nx.is_forest(b))

flName = 'moreno_highschool\README.moreno_highschool'
f = open(flName, 'r')
lines = f.readlines()
示例#38
0
import networkx as nx

G = nx.Graph()
G.add_edges_from([(1, 2), (1, 3), (2, 3), (2, 4), (2, 6), (3, 4), (3, 5),
                  (4, 5), (4, 6), (5, 6), (5, 7), (6, 7)])

posicoes = {
    1: (.5, 1),
    2: (0, .75),
    3: (1, .75),
    4: (.5, .5),
    5: (1, .25),
    6: (0, .25),
    7: (.5, 0),
}

nx.draw_networkx(G, pos=posicoes)
print("Grafo G")
print("-------")
print("É Euleriano?", "Sim" if nx.is_eulerian(G) else "Não")
print("É Semieuleriano?", "Sim" if nx.is_semieulerian(G) else "Não")
print("É Tem caminho Euliriano?", "Sim" if nx.has_eulerian_path(G) else "Não")
示例#39
0
 def test_on_eulerian_multigraph(self):
     G = nx.MultiGraph(nx.cycle_graph(3))
     G.add_edge(0, 1)
     H = nx.eulerize(G)
     assert_true(nx.is_eulerian(H))
def is_eulerian(g, **kwargs):
    return nx.is_eulerian(g)
示例#41
0
def find_eulerian_path(G):
    """Returns the edges of an Eulerian path in G, (if it exits).

    An Eulerian path is a path that crosses every edge in G
    exactly once.

    Parameters
    ----------
    G: NetworkX Graph, DiGraph, MultiGraph or MultiDiGraph
        A directed or undirected Graph or MultiGraph.

    Returns
    -------
    edges: generator
        A generator that produces edges in the Eulerian path.

    Raises
    ------
    NetworkXError: If the graph does not have an eulerian path.

    Notes
    -----
    Linear time algorithm, adapted from [1]_ and [3]_.
    Information about euler paths in [2]_.
    Code for eulerian circuit in [3]_.

    Important: In [1], euler path is in reverse order,
    this implementation gives the path in correct order
    as in [3]_ for eulerian_circuit. The distinction for
    directed graph is in using the in_degree neighbors, not the out
    ones. for undirected, it is using itemgetter(1) for get_vertex,
    which uses the correct vertex for this order. Also, every graph
    has an even number of odd vertices by the Handshaking Theorem [4]_.

    References
    ----------
    .. [1] http://www.graph-magics.com/articles/euler.php
    .. [2] http://en.wikipedia.org/wiki/Eulerian_path
    .. [3] https://github.com/networkx/networkx/blob/master/networkx/algorithms/euler.py
    .. [4] https://www.math.ku.edu/~jmartin/courses/math105-F11/Lectures/chapter5-part2.pdf

    Examples
    --------
    >>> G = nx.Graph([('W', 'N'), ('N', 'E'), ('E', 'W'), ('W', 'S'), ('S', 'E')])
    >>> list(nx.find_eulerian_path(G))
    [('W', 'N'), ('N', 'E'), ('E', 'W'), ('W', 'S'), ('S', 'E')]

    >>> G = nx.Digraph([(1, 2), (2, 3)])
    >>> list(nx.find_eulerian_path(G))
    [(1,2),(2,3)]
    """
    from operator import itemgetter

    # Verify that graph is connected, short circuit
    if G.is_directed() and not nx.is_weakly_connected(G):
        raise nx.NetworkXError("G is not connected.")

    # is undirected
    if not G.is_directed() and not nx.is_connected(G):
        raise nx.NetworkXError("G is not connected.")

    # Now verify if has an eulerian circuit:
    # even condition of all nodes is satified.
    if nx.is_eulerian(G):
        x = nx.eulerian_circuit(G)  # generator of edges
        for i in x:
            yield i

    # Not all vertex have even degree,
    # check if exactly two vertex have odd degrees.
    # If yes, then there is an Euler path. If not,
    # raise an error (no euler path can be found)
    else:
        g = G.__class__(G)  # copy graph structure (not attributes)

        # list to check the odd degree condition, and a flag
        check_odd = []
        directed = False

        if g.is_directed():
            degree = g.in_degree
            out_degree = g.out_degree
            edges = g.in_edges_iter
            get_vertex = itemgetter(0)
            directed = True
        else:
            degree = g.degree
            edges = g.edges_iter
            get_vertex = itemgetter(1)

        # Verify if an euler path can be found. Complexity O(n) ?
        for vertex in g.nodes():
            deg = degree(vertex)
            # directed case
            if directed:
                outdeg = out_degree(vertex)
                if deg != outdeg:
                    # if we have more than 2 odd nodes,
                    # we do a raise (no euler path)
                    if len(check_odd) > 2:
                        raise nx.NetworkXError("G doesn't have an Euler Path.")
                # is odd and we append it.
                    else:
                        check_odd.append(vertex)
            # undirected case
            else:
                if deg % 2 != 0:
                    # if we have more than 2 odd nodes,
                    # we do a raise (no euler path)
                    if len(check_odd) > 2:
                        raise nx.NetworkXError("G doesn't have an Euler Path.")
                    # is odd and we append it.
                    else:
                        check_odd.append(vertex)

        if directed:
            def verify_odd_cond(g, check_odd):
                first = check_odd[0]
                second = check_odd[1]
                if (g.out_degree(first) == g.in_degree(first) + 1 and
                        g.in_degree(second) == g.out_degree(second) + 1):
                    return second
                elif (g.out_degree(second) == g.in_degree(second) + 1 and
                        g.in_degree(first) == g.out_degree(first) + 1):
                    return first
                else:
                    return None
            start = verify_odd_cond(g, check_odd)
        else:
            start = check_odd[0]

        # if the odd condition is not meet, raise an error.
        if not start:
            raise nx.NetworkXError("G doesn't have an Euler Path.")
        # Begin algorithm:
        vertex_stack = [start]
        last_vertex = None

        while vertex_stack:

            current_vertex = vertex_stack[-1]  # (4)
            # if no neighbors:
            if degree(current_vertex) == 0:
                # Special case, we cannot add a None vertex to the path.
                if last_vertex is not None:
                    yield (last_vertex, current_vertex)
                last_vertex = current_vertex
                vertex_stack.pop()
            # we have neighbors, so add the vertex to the stack (2),
            # take any of its neighbors (1)
            # remove the edge between selected neighbor and that vertex,
            # and set that neighbor as the current vertex (4).
            else:
                random_edge = next(edges(current_vertex))  # (1)
                vertex_stack.append(get_vertex(random_edge))  # (2)
                g.remove_edge(*random_edge)  # (3)
示例#42
0
 def test_on_complete_graph(self):
     G = nx.complete_graph(4)
     assert_true(nx.is_eulerian(nx.eulerize(G)))
     assert_true(nx.is_eulerian(nx.eulerize(nx.MultiGraph(G))))
示例#43
0
import matplotlib.pyplot as plt
from PIL import Image
from os import system

#G = nx.complete_graph(5)
G = nx.MultiGraph()

#G.add_nodes_from(["C", "A", "D", "B"])
#G.add_edges_from([{"C","A"}, {"C","A"}, {"A","B"}, {"A","B"}, {"C", "D"}, {"A", "D"}, {"B", "D"}])
G.add_edges_from([("C","A"), ("C","A"), ("A","B"), ("A","B"), ("C", "D"), ("A", "D"), ("B", "D")])
#G.add_edges_from([("C","A"), ("A","B"), ("C", "D"), ("A", "D"), ("B", "D")])
#G.add_edges_from([("C","A"), ("C","A"), ("A","B"), ("A","B"), ("C", "D"), ("A", "D"), ("B", "D"), ("A", "C"), ("B", "D")])
print("Nodes:", G.nodes())
print("Edges:", G.edges())
print("Nodes:", ", ".join(sorted(G.nodes())))
print("Edges:", ", ".join(sorted("{{{}}}".format(",".join(sorted(t))) for t in G.edges())))
print("The graph {} Eulerian.".format("is" if nx.is_eulerian(G) else "is not"))

spt = nx.minimum_spanning_edges(G, data=False)
print(list(spt))
#print("Edges:", ", ".join(sorted("{{{}}}".format(",".join(sorted(t))) for t in spt)))
#nx.set_node_attributes(G, "pos", {"C": { "pos": (0,2) }, "A": { "pos": (0,1) }, "D": { "pos": (1,0) }, "B": (0,0)})
#nx.draw_networkx(G, pos={"C": (0,2), "A": (0,1), "D": (1,0), "B": (0,0)})
#plt.axis("off")
#plt.show()

#nx.write_dot(G, "konigsberg.dot")
#system("circo -T png konigsberg.dot > konigsberg.png")
#img = Image.open('konigsberg.png')
#img.show()
示例#44
0
文件: crblh.py 项目: cerebis/crblh
                membership[n.organism] = []
            membership[n.organism].append([n.name, i+1])

    print '\nHistogram of component order'
    print 'order\tcount'
    for n in sorted(sg_order_hist):
        print '{0}\t{1}'.format(n, sg_order_hist[n])

print 'Writing subgraph info table.'
with open(args.output[0] + '.subgraph', 'w') as subinfo_h:
    subinfo_wr = csv.writer(subinfo_h, delimiter='\t')
    subinfo_wr.writerow(['id', 'size', 'order', 'density', 'eularian', 'binconn', 'modularity'])
    for i, sg in enumerate(subgraphs):
        part = com.best_partition(sg)
        subinfo_wr.writerow([i+1, sg.size(), sg.order(), nx.density(sg),
                             nx.is_eulerian(sg), nx.is_biconnected(sg), com.modularity(part, sg)])

if args.writesubs:
    print 'Writing all subgraphs ...'
    for i, sg in enumerate(subgraphs):
        out = os.path.join(args.work_dir[0], 'og{0}.graphml'.format(i+1))
        nx.write_graphml(sg, out)

iso_count = 0
for org in membership:
    print 'There remained {0} isolate genes in {1}'.format(len(isolate_genes[org]), org)
    with open(org + '.memb', 'w') as memb_h:
        memb_wr = csv.writer(memb_h, delimiter='\t')
        memb_wr.writerow(['gene','og'])
        for gn in membership[org]:
            memb_wr.writerow(gn)
示例#45
0
found = 0
for n in G.nodes_iter():
  if G.in_degree(n) > G.out_degree(n):
    n1 = n
    found +=1
  if G.out_degree(n) > G.in_degree(n):
    n2 = n
    found +=1
  if found>=2:
    break

G.add_edge(n1,n2)
print n2 + "->" + n1


if nx.is_eulerian(G):
  nodes = []
  temp_nodes = []
  start = False
  for u,v in nx.eulerian_circuit(G,source=n1):
    if (u == n1) and (v == n2):
      start = True
    if start:
      nodes.append(v) 
    else:
      temp_nodes.append(v)
  nodes += temp_nodes    
  print >>out, "->".join(str(n) for n in nodes)
  print >> sys.stderr, "Finished!"
else:
  print "Not Eulerian"
示例#46
0
def main():
    """The main function.

    Returns:
      None
    """

    G = nx.Graph()
    G.add_edges_from((
        ('せんし', 'とうぞく', dict(skill='ぬすっと斬り')),
        ('せんし', 'おどりこ', dict(skill='つるぎのまい')),
        ('せんし', 'ぎんゆうしじん', dict(skill='たたかいの歌')),
        ('せんし', 'ふなのり', dict(skill='かもめ返し')),
        ('せんし', 'ひつじかい', dict(skill='みねうち')),
        ('せんし', 'わらわせし', dict(skill='へんてこ斬り')),
        ('ぶとうか', 'まほうつかい', dict(skill='火の息')),
        ('ぶとうか', 'とうぞく', dict(skill='きゅうしょ突き')),
        ('ぶとうか', 'おどりこ', dict(skill='マッスルダンス')),
        ('ぶとうか', 'ぎんゆうしじん', dict(skill='おたけび')),
        ('ぶとうか', 'ふなのり', dict(skill='すいめんげり')),
        ('ぶとうか', 'ひつじかい', dict(skill='マトンアタック')),
        ('ぶとうか', 'わらわせし', dict(skill='しっぺ返し')),
        ('まほうつかい', 'ぶとうか', dict(skill='火の息')),
        ('まほうつかい', 'とうぞく', dict(skill='マホトラ')),
        ('まほうつかい', 'おどりこ', dict(skill='マホキテ')),
        ('まほうつかい', 'ぎんゆうしじん', dict(skill='のろいの歌')),
        ('まほうつかい', 'ふなのり', dict(skill='いなずま')),
        ('まほうつかい', 'ひつじかい', dict(skill='ラリホーマ')),
        ('まほうつかい', 'わらわせし', dict(skill='メダパニ')),
        ('そうりょ', 'おどりこ', dict(skill='死のおどり')),
        ('そうりょ', 'ぎんゆうしじん', dict(skill='やすらぎの歌')),
        ('そうりょ', 'ふなのり', dict(skill='ノアのはこぶね')),
        ('そうりょ', 'ひつじかい', dict(skill='スクルト')),
        ('とうぞく', 'せんし', dict(skill='ぬすっと斬り')),
        ('とうぞく', 'ぶとうか', dict(skill='きゅうしょ突き')),
        ('とうぞく', 'まほうつかい', dict(skill='マホトラ')),
        ('とうぞく', 'おどりこ', dict(skill='マホトラおどり')),
        ('とうぞく', 'わらわせし', dict(skill='しのび笑い')),
        ('おどりこ', 'せんし', dict(skill='つるぎのまい')),
        ('おどりこ', 'ぶとうか', dict(skill='マッスルダンス')),
        ('おどりこ', 'まほうつかい', dict(skill='マホキテ')),
        ('おどりこ', 'そうりょ', dict(skill='死のおどり')),
        ('おどりこ', 'とうぞく', dict(skill='マホトラおどり')),
        ('おどりこ', 'ふなのり', dict(skill='船上ダンス')),
        ('おどりこ', 'ひつじかい', dict(skill='ひつじのダンス')),
        ('おどりこ', 'わらわせし', dict(skill='ステテコダンス')),
        ('ぎんゆうしじん', 'せんし', dict(skill='たたかいの歌')),
        ('ぎんゆうしじん', 'ぶとうか', dict(skill='おたけび')),
        ('ぎんゆうしじん', 'まほうつかい', dict(skill='のろいの歌')),
        ('ぎんゆうしじん', 'そうりょ', dict(skill='やすらぎの歌')),
        ('ぎんゆうしじん', 'ふなのり', dict(skill='さざなみの歌')),
        ('ぎんゆうしじん', 'ひつじかい', dict(skill='ひつじかぞえ歌')),
        ('ぎんゆうしじん', 'わらわせし', dict(skill='コミックソング')),
        ('ふなのり', 'せんし', dict(skill='かもめ返し')),
        ('ふなのり', 'ぶとうか', dict(skill='すいめんげり')),
        ('ふなのり', 'まほうつかい', dict(skill='いなずま')),
        ('ふなのり', 'そうりょ', dict(skill='ノアのはこぶね')),
        ('ふなのり', 'おどりこ', dict(skill='船上ダンス')),
        ('ふなのり', 'ぎんゆうしじん', dict(skill='さざなみの歌')),
        ('ひつじかい', 'せんし', dict(skill='みねうち')),
        ('ひつじかい', 'ぶとうか', dict(skill='マトンアタック')),
        ('ひつじかい', 'まほうつかい', dict(skill='ラリホーマ')),
        ('ひつじかい', 'そうりょ', dict(skill='スクルト')),
        ('ひつじかい', 'おどりこ', dict(skill='ひつじのダンス')),
        ('ひつじかい', 'ぎんゆうしじん', dict(skill='ひつじかぞえ歌')),
        ('わらわせし', 'せんし', dict(skill='へんてこ斬り')),
        ('わらわせし', 'ぶとうか', dict(skill='しっぺ返し')),
        ('わらわせし', 'まほうつかい', dict(skill='メダパニ')),
        ('わらわせし', 'とうぞく', dict(skill='しのび笑い')),
        ('わらわせし', 'おどりこ', dict(skill='ステテコダンス')),
        ('わらわせし', 'ぎんゆうしじん', dict(skill='コミックソング')),
        #('けんじゃ', 'スーパースター', dict(skill='メガザルダンス')),
        ))

    if nx.is_eulerian(G):
        print_cycle(G)

    G.remove_edge('ぎんゆうしじん', 'ぶとうか')
    G.remove_edge('まほうつかい', 'とうぞく')
    print_cycle(G, source='まほうつかい')