I tried implement bidirectional path search (when one search started from the head vertex of a path, and other started from the end vertex and these two path will be union, when they have a non-empty intersection) in Java 17.
I have a graph, which contains collections of vertices and edges (edge contains links to two vertices (from and to) and weight by int of type).
Unfortunately, my implementation of this search method don't work. I tried to build a tree, and then build the path. The tree called searchTreeParentByChild in my method and have a type Map<Vertex, Vertex>.
public BidirectionalSearch buildSearchTree(Vertex start, Vertex end) {
if (!graph.vertices().containsAll(List.of(start, end)))
throw new IllegalArgumentException("start or stop vertices not from this graph");
if (start.equals(end))
return this;
searchTreeParentByChild.clear();
Queue<Vertex> unvisitedVertexQueueFromStart = new ArrayDeque<>();
Queue<Vertex> unvisitedVertexQueueFromEnd = new ArrayDeque<>();
unvisitedVertexQueueFromStart.add(start);
unvisitedVertexQueueFromEnd.add(end);
searchTreeParentByChild.put(start, null);
while (!unvisitedVertexQueueFromStart.isEmpty() && !unvisitedVertexQueueFromEnd.isEmpty()) {
var curStart = unvisitedVertexQueueFromStart.poll();
for (var e : curStart.edges()) {
if (!searchTreeParentByChild.containsKey(e.to())) {
searchTreeParentByChild.put(e.to(), curStart);
unvisitedVertexQueueFromStart.add(e.to());
}
}
var intersection = curStart.edges().stream()
.map(Edge::to)
.filter(unvisitedVertexQueueFromEnd::contains)
.findAny();
if (intersection.isPresent())
return this;
var curEnd = unvisitedVertexQueueFromEnd.poll();
for (var e : curEnd.edges()) {
if (!searchTreeParentByChild.containsValue(e.to())) {
searchTreeParentByChild.put(curEnd, e.to());
unvisitedVertexQueueFromEnd.add(e.to());
}
}
intersection = curEnd.edges().stream()
.map(Edge::to)
.filter(unvisitedVertexQueueFromStart::contains)
.findAny();
if (intersection.isPresent())
return this;
}
return this;
}
My method will stop, if any vertex is contained in intersection of both parts of the path. But I'm not sure that I've done it right.
This implementation return only second part of path, how can I get full path from start to end vertices.