0

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.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Maks
  • 1
  • 1

1 Answers1

1

I'm not an expert of the bidirectional searches. But I note that you have one searchTreeParentByChild for the both parts of the path. And this parts of the path should be built from another start points and in another direct. But your tree can be used only for building path in the ONE direct from child to parent. Not from parent to child!

Lip
  • 11
  • 1