If you want to enumerate all Eulerian paths (and, like Gassa, I have my doubts), then the following simple output-sensitive algorithm has polynomial overhead, which, since n will be very small, should suffice. There's a recursive procedure for enumerating all paths from v
that goes like this in Python.
def paths(v, neighbors, path): # call initially with path=[]
yield path[:] # return a copy of the mutable list
for w in list(neighbors[v]):
neighbors[v].remove(w) # remove the edge from the graph
path.append((v, w)) # add the edge to the path
yield from paths(w, neighbors, path) # recursively enumerate
# all path extensions from w
# in the residual graph
path.pop() # remove the edge from the path
neighbors[v].add(w) # add the edge to the graph
To return Eulerian paths only, we make two modifications. First, we prune the recursion if there is no Eulerian path extending the current path. Second, we do the first yield only when neighbors[v]
is empty, i.e., the only extension is the trivial one, so path
is Eulerian. Since the degree balance condition is satisfied, we prune by just checking strong connectivity of the non-isolated vertices at each recursive call, given that we add an arc from the starting vertex to v
. This can be accomplished with two traversals, one to verify that every non-isolated vertex can reach the starting vertex and one to verify that every non-isolated vertex is reachable from v
. (Alternatively, you could add the arc temporarily and do one traversal, but then you'd have to handle multigraphs, which you may not want to.)