java.lang.Object
org.jgrapht.alg.cycle.HierholzerEulerianCycle<V,E>
- Type Parameters:
V
- the graph vertex typeE
- the graph edge type
- All Implemented Interfaces:
EulerianCycleAlgorithm<V,
E>
An implementation of Hierholzer's algorithm for finding an Eulerian cycle in Eulerian graphs. The
algorithm works with directed and undirected graphs which may contain loops and/or multiple
(parallel) edges. The running time is linear, i.e. $O(|E|)$ where $|E|$ is the cardinality of the
edge set of the graph.
See the Wikipedia article for details and references about Eulerian cycles and a short description of Hierholzer's algorithm for the construction of an Eulerian cycle. The original presentation of the algorithm dates back to 1873 and the following paper: Carl Hierholzer: Über die Möglichkeit, einen Linienzug ohne Wiederholung und ohne Unterbrechung zu umfahren. Mathematische Annalen 6(1), 30–32, 1873.
- Author:
- Dimitrios Michail
-
Nested Class Summary
Modifier and TypeClassDescriptionprotected class
protected class
-
Field Summary
Modifier and TypeFieldDescriptionprotected HierholzerEulerianCycle<V,
E>.EdgeNode protected boolean
protected V
protected HierholzerEulerianCycle<V,
E>.VertexNode -
Constructor Summary
-
Method Summary
Modifier and TypeMethodDescriptionprotected void
addEdge
(HierholzerEulerianCycle<V, E>.VertexNode sNode, HierholzerEulerianCycle<V, E>.VertexNode tNode, E e) Add an edge to the index.Build final walkprotected void
cleanup()
Release any memory held.protected Pair<HierholzerEulerianCycle<V,
E>.EdgeNode, HierholzerEulerianCycle<V, E>.EdgeNode> Computes a partial cycle assuming that all vertices have an even degree.getEulerianCycle
(Graph<V, E> g) Compute an Eulerian cycle of a graph.protected HierholzerEulerianCycle<V,
E>.VertexNode getOppositeVertex
(HierholzerEulerianCycle<V, E>.VertexNode v, HierholzerEulerianCycle<V, E>.EdgeNode e) Compute the opposite end-point of an end-point of an edge.protected void
initialize
(Graph<V, E> g) Index the graph and create a double-linked list representation suitable for vertex and edge removals in constant time.boolean
isEulerian
(Graph<V, E> graph) Test whether a graph is Eulerian.protected void
moveToFront
(HierholzerEulerianCycle<V, E>.VertexNode vNode) Move a vertex as first in the vertex list.protected void
unlink
(HierholzerEulerianCycle<V, E>.EdgeNode eNode) Unlink an edge from the adjacency lists of its end-points.protected void
unlink
(HierholzerEulerianCycle<V, E>.VertexNode vNode) Unlink a vertex from the vertex list.protected void
updateGraphAndInsertLocations
(Pair<HierholzerEulerianCycle<V, E>.EdgeNode, HierholzerEulerianCycle<V, E>.EdgeNode> partialCycle, HierholzerEulerianCycle<V, E>.VertexNode partialCycleSourceVertex) Iterate over the partial cycle to remove vertices with zero degrees and compute new insert locations for vertices with non-zero degrees.
-
Field Details
-
g
-
isDirected
protected boolean isDirected -
verticesHead
-
eulerianHead
-
startVertex
-
-
Constructor Details
-
HierholzerEulerianCycle
public HierholzerEulerianCycle()
-
-
Method Details
-
isEulerian
Test whether a graph is Eulerian. An Eulerian graph is a graph containing an Eulerian cycle.- Parameters:
graph
- the input graph- Returns:
- true if the graph is Eulerian, false otherwise
-
getEulerianCycle
Compute an Eulerian cycle of a graph.- Specified by:
getEulerianCycle
in interfaceEulerianCycleAlgorithm<V,
E> - Parameters:
g
- the input graph- Returns:
- an Eulerian cycle
- Throws:
IllegalArgumentException
- in case the graph is not Eulerian
-
initialize
Index the graph and create a double-linked list representation suitable for vertex and edge removals in constant time. Ignore any vertices with zero degrees.- Parameters:
g
- the graph to index
-
cleanup
protected void cleanup()Release any memory held. -
computePartialCycle
protected Pair<HierholzerEulerianCycle<V,E>.EdgeNode, computePartialCycle()HierholzerEulerianCycle<V, E>.EdgeNode> Computes a partial cycle assuming that all vertices have an even degree. The partial cycle always begin from the first graph vertex in the vertex list.- Returns:
- the partial's cycle head and tail nodes as a pair
-
updateGraphAndInsertLocations
protected void updateGraphAndInsertLocations(Pair<HierholzerEulerianCycle<V, E>.EdgeNode, HierholzerEulerianCycle<V, E>.EdgeNode> partialCycle, HierholzerEulerianCycle<V, E>.VertexNode partialCycleSourceVertex) Iterate over the partial cycle to remove vertices with zero degrees and compute new insert locations for vertices with non-zero degrees. It is important to move vertices with new insert locations to the front of the vertex list, in order to make sure that we always start partial cycles from already visited vertices.- Parameters:
partialCycle
- the partial cyclepartialCycleSourceVertex
- the source vertex of the first edge in the partial cycle
-
buildWalk
Build final walk- Returns:
- the final walk
-
addEdge
protected void addEdge(HierholzerEulerianCycle<V, E>.VertexNode sNode, HierholzerEulerianCycle<V, E>.VertexNode tNode, E e) Add an edge to the index.- Parameters:
sNode
- source vertextNode
- target vertexe
- original (wrapped) edge
-
unlink
Unlink a vertex from the vertex list.- Parameters:
vNode
- vertex to unlink
-
moveToFront
Move a vertex as first in the vertex list.- Parameters:
vNode
- vertex to move to front
-
unlink
Unlink an edge from the adjacency lists of its end-points.- Parameters:
eNode
- edge to unlink
-
getOppositeVertex
protected HierholzerEulerianCycle<V,E>.VertexNode getOppositeVertex(HierholzerEulerianCycle<V, E>.VertexNode v, HierholzerEulerianCycle<V, E>.EdgeNode e) Compute the opposite end-point of an end-point of an edge.- Parameters:
v
- vertex that is part of edgee
- edge used to find opposite vertex- Returns:
- opposite vertex in edge
-