实现广度优先的图遍历到给定深度

时间:2016-12-30 01:02:05

标签: java breadth-first-search

我正在尝试实现广度优先的图遍历,它返回从一个节点到另一个节点的路径数,但只返回给定数量的节点。

例如,给定节点A,B,C,D,E的列表,如果我想知道从A到D可以获得的不同路径的数量,但仅当路径不超过2个停止时。 A-B-D,A-E-D被认为是可以接受的,但是A-B-E-D会停止太多,所以答案就是两条路径。

我正在尝试实现此算法,但我不确定如何跟踪深度,因此我的搜索只会达到n级深度。

这是我到目前为止编写的代码。问题在于searchNumPaths()方法。

public class PathSearch{
private int maxSearches;
private int pathCount;
private int numPaths;
private String node;
private ArrayList<ArrayList<String>> path;
ArrayList<Node> visited;

public PathSearch(int maxSearches, int pathCount) {
    node = "";
    this.maxSearches = maxSearches;
    this.pathCount = pathCount;
    path = new ArrayList<ArrayList<String>>();
    visited = new ArrayList<Node>();
}

public int searchNumPaths(HashMap<String, Node> graph, Node startLocation, String endLocation, Queue<String> queue) {
    //queue.add(startLocation.getLocation());
    while(!queue.isEmpty()) {
        node = queue.remove();
        System.out.println("\n" + node +"\n");
        for (Edge realPath: graph.get(node).getNeighbors()) {
                node = realPath.getEndLocation();
                System.out.println(node);
                queue.add(node);
                if (node.equals(endLocation)) {
                    numPaths++;
                }   
        }
        pathCount++;
        if (pathCount>6){
            break;
        }
        for (int i = 0; i<queue.size(); i++) {
            searchNumPaths(graph, graph.get(queue.peek()), endLocation, queue);
            queue.remove();
        }

    }
    return numPaths;
}

public static void main(String[] args) throws IOException {
    Train train = new Train();
    Graph graph = new Graph(train.readFile("input.txt"));
    LinkedList<String> queue = new LinkedList<String>();
    queue.add("A");
    PathSearch great = new PathSearch(10, 0);
    HashMap<String, Node> map = graph.returnMap();
    Node node = graph.returnMap().get("A");
    String nodeTwo = graph.returnMap().get("C").getLocation();
    //System.out.println(queue.remove());
    System.out.println("Number of paths: " + great.searchNumPaths(map, node, nodeTwo, queue));

}

}

1 个答案:

答案 0 :(得分:0)

您可以创建一个QueueNode类,其中包含您放入队列的当前字符串以及指示节点深度的数字。然后,您可以继续搜索,直到遇到深度太高的节点。这样的事情(T在你的案例中是String):

public class QueueNode<T> {

    T value;
    int depth;

    public QueueNode(T value, int depth) {
        this.value = value;
        this.depth = depth;
    }

    // And so on.. Getters etc.

}

创建新的QueueNode对象时,只需将深度设置为大于当前节点深度的深度即可。

通过这样做,您可以向searchNumPaths函数添加类似的内容(在调用queue.remove()之后):

if (node.getDepth() > maxDepth) {
    return numPaths;
}

请注意,这仅在您的队列保证返回深度增加的节点时才有效。对于广度优先搜索,这始终是正确的,但是如果您要将其更改为A星搜索或稍后的搜索,则此假设会中断。