Outgoing and incoming edges in undirected graphs
See original GitHub issueA number of algorithms, defined on both directed and undirected graphs, iterate over the outgoing or incoming edges of a graph. This creates some problems, because in an UndirectedGraph, you cannot iterate over the outgoingEdgesOf(V vertex). Instead, you have to iterate over edgesOf(V vertex). A number of implementations (e.g. BidirectionalDijkstraShortestPath) try to resolve this issue as follows:
abstract class Specifics{
public abstract Set<? extends E> edgesOf(V vertex);
}
class DirectedSpecifics extends Specifics{
private DirectedGraph<V, E> graph;
public DirectedSpecifics(DirectedGraph<V, E> g){
graph = g;
}
@Override
public Set<? extends E> edgesOf(V vertex){
return graph.outgoingEdgesOf(vertex);
}
}
class UndirectedSpecifics extends Specifics{
private Graph<V, E> graph;
public UndirectedSpecifics(Graph<V, E> g){
graph = g;
}
@Override
public Set<E> edgesOf(V vertex){
return graph.edgesOf(vertex);
}
}
This is becoming a bit of a pattern throughout the library, so we probably want to address this. I don’t immediately have a clean solution (requires some more thought so determine the consequences of different solutions). Here are 4 different possibilities:
- Add default functions outgoingEdgesOf and incomingEdgesOf to the Graph interface, which implements the above behavior.
- Add a dedicated method to the utility class Graphs.
- Add this behavior to the UndirectedGraph interface only (this would only solve the problem partially)
- Create a special GraphDelegator implementation. Perhaps the easiest, least invasive, but probably also the least intuitive one.
Opinions are welcome. Alternatively, propose a solution through a pull request and we’ll have a look at it.
Issue Analytics
- State:
- Created 7 years ago
- Comments:9 (7 by maintainers)

Top Related StackOverflow Question
I don’t think anything prevents us from creating a custom implementation of the Set interface if we want to eliminate the copying.
BTW for the new EdgeAccessor we’re contemplating here, I’m fine with making it produce an Iterable rather than a Set, since the intention is to provide a way to enumerate edges during traversal (as opposed to something like edgesOf, which is intended to define the data structure).
Solved in #366.