简体   繁体   English

保存广度优先搜索中遍历的边 Java

[英]Saving the edges traversed in breadth first search Java

Below is my bfs algorithm, the algorithm works and finds the node given the start and target.下面是我的 bfs 算法,该算法有效并找到给定起点和目标的节点。 But I want to save edges for the used path in a linkedList to draw the path.但我想在linkedList中保存使用路径的边缘来绘制路径。

My BFS:我的 BFS:

public DGPath breadthFirstSearch(String startId, String targetId) {

        V start = this.getVertexById(startId);
        V target = this.getVertexById(targetId);
        if (start == null || target == null) return null;

        DGPath path = new DGPath();
        path.start = start;
        path.visited.add(start);

        // easy target
        if (start == target) return path;

        // TODO calculate the path from start to target by breadth-first-search
        //  register all visited vertices while going, for statistical purposes
        //  if you hit the target: complete the path and bail out !!!
        Queue<V> fifoQueue = new LinkedList<>();
        Map<V,V> visitedFrom = new HashMap<>();

        fifoQueue.offer(start);
        visitedFrom.put(start, null);

        while (!fifoQueue.isEmpty()) {
            V current = fifoQueue.poll();
            for (E e : current.getEdges()) {
                V neighbour = e.getTo();
                path.visited.add(neighbour);
                if (neighbour == target) {
                    while (current != null) {
                        path.getEdges().addFirst(e);
                        current = visitedFrom.get(current);

                    }
                    return path;
                } else if (!visitedFrom.containsKey(neighbour)) {
                    visitedFrom.put(neighbour,current);
                    fifoQueue.offer(neighbour);
                }
            }
        }


        // no path found, graph was not connected ???
        return null;
    }

The DGPath is the class that creates the path as shown below: DGPath 是创建路径的 class,如下所示:

public class DGPath {
        private V start = null;
        private LinkedList<E> edges = new LinkedList<>();
        private double totalWeight = 0.0;
        private Set<V> visited = new HashSet<>();

        /**
         * representation invariants:
         * 1. The edges are connected by vertices, i.e. FOR ALL i: 0 < i < edges.length: edges[i].from == edges[i-1].to
         * 2. The path begins at vertex == start
         * 3. if edges is empty, the path also ends at vertex == start
         * otherwise edges[0].from == start and the path continues along edges[i].to for all 0 <= i < edges.length
         **/

        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder(
                    String.format("Weight=%f Length=%d Visited=%d (",
                            this.totalWeight, 1 + this.edges.size(), this.visited.size()));
            sb.append(start.getId());
            for (E e : edges) {
                sb.append(", " + e.getTo().getId());
            }
            sb.append(")");
            return sb.toString();
        }

        public V getStart() {
            return start;
        }

        public LinkedList<E> getEdges() {
            return edges;
        }

        public double getTotalWeight() {
            return totalWeight;
        }

        public Set<V> getVisited() {
            return visited;
        }
    }

I want to save the right edges in de linkedlist edges from the BGPath class (called path in my BFS algo method).我想将右edges保存在来自BGPath class(在我的 BFS 算法方法中称为path )的链接linkedlist edges中。 So I already saved the used vertices in a map to go back to the root.所以我已经将 map 到 go 中使用的顶点保存回根。 But when I add the edge to the path it just saves the last edge used multiple times.. The problem is the vertex can have multiple edges, so I need to add the edge from the previous that was pointing to the last "current" until I'm back to the root.但是当我将边添加到路径时,它只会保存多次使用的最后一条边。问题是顶点可以有多个边,所以我需要从指向最后一个“当前”的前一个边添加边,直到我回到了根源。 But I cant wrap my head around the right way to do this.但我不能用正确的方法来做这件事。

The line where I now add the edge to the list of edges is: path.getEdges().add(e)我现在将边缘添加到边缘列表的行是: path.getEdges().add(e)

I think, your problem is the same line, where your are adding the edges, that line is adding the same edge in inner while loop again and again, so you are only traversing back but not adding those nodes to your edges list.我认为,您的问题是同一行,您正在添加边缘,该行一次又一次地在内部 while 循环中添加相同的边缘,因此您只是遍历而不将这些节点添加到边缘列表中。

I think, it should be like this我想,应该是这样的

while (!fifoQueue.isEmpty()) {
            V current = fifoQueue.poll();
            for (E e : current.getEdges()) {
                V neighbour = e.getTo();
                path.visited.add(neighbour);
                if (neighbour == target) {
                    path.getEdges().addFirst(e):
                    while (current != null) {
                        path.getEdges().addFirst(current) ;
                        current = visitedFrom.get(current);
                    }
                    return path;
                } else if (!visitedFrom.containsKey(neighbour)) {
                    visitedFrom.put(neighbour,current);
                    fifoQueue.offer(neighbour);
                }
            }
        }


        // no path found, graph was not connected ???
        return null;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM