Example #1
0
def eulerian_path(G: DirectedGraph) -> list:
    """
    Find eulerian path in the given graph
    Args:
        graph to find eulerian path in
    Return:
        path if found or None if not found
    """

    cycle = eulerian_cycle(G)
    if cycle is not None:
        return cycle

    in_edges = [0] * G.V()
    out_edges = [0] * G.V()
    for u in range(G.V()):
        for v, c in G.adj(u):
            in_edges[v] += c
            out_edges[u] += c

    # start vertex
    s = -1
    cnt = 0
    for v in range(G.V()):
        if (in_edges[v] + out_edges[v]) % 2 == 1:
            cnt += 1
            if cnt > 2:
                return None

            if s == -1 or out_edges[s] % 2 == 0:
                s = v
    if s == -1:
        return None

    G = deepcopy(G)
    E = G.E()

    tour = []
    cur = s
    while True:
        try:
            tour.append(cur)
            (v, c) = G.adj(cur).__next__()
            G.remove_edge(DirectedEdge(cur, v))
            cur = v
        except StopIteration:
            break

    def selfloop(u: int):
        nonlocal G
        path = []
        cur = u
        while cur != u or not path:
            path.append(cur)
            (v, c) = G.adj(cur).__next__()
            G.remove_edge(DirectedEdge(cur, v))
            cur = v
        path.append(u)
        return path

    index = 0
    while index < len(tour):
        try:
            G.adj(tour[index]).__next__()
            tour = tour[:index] + selfloop(tour[index]) + tour[index + 1:]
        except StopIteration:
            index += 1
    return tour if len(tour) == E + 1 else None
Example #2
0
#!/usr/bin/env python3
from common import IO
from graph.directed import Graph, GraphMatrix
from graph import algorithm

io = IO()

G = Graph.fromfile(io.filein)
G_matrix = GraphMatrix.from_graph(G)

# Eulerian cycle, part 1
io.section('Eulerian cycle')
eulerian_cycle = algorithm.eulerian_cycle(G_matrix)
if eulerian_cycle is not None:
    io.print('Eulerian cycle found: ')
    io.print_path(eulerian_cycle)
else:
    io.print('Eulerian cycle not found!')

    # Eulerian path, part 2
    io.section('Eulerian path')
    eulerian_path = algorithm.eulerian_path(G_matrix)
    if eulerian_path is not None:
        io.print('Eulerian path found: ')
        io.print_path(eulerian_path)
    else:
        io.print('Eulerian path not found!')


# Hamiltonian cycle, part 1
io.section('Hamiltonian cycle')