Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/398.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在深度优先搜索Java上向列表添加路径的边_Java - Fatal编程技术网

在深度优先搜索Java上向列表添加路径的边

在深度优先搜索Java上向列表添加路径的边,java,Java,我正在尝试在有向图上实现深度优先搜索算法。该图存在多个顶点(V顶点),每个顶点都有一组边(E边)。每条边都有一个指向下一条边的指针(.getTo())和一个指向上一条边的指针(.getFrom())。我想找到从起始顶点到目标顶点的边的路径。为了存储和创建路径,我创建了一个helper类DGPath。我想用递归的方式来做这件事 在DGPath创建路径帮助器类下面: /** * represents a path of connected vertices and edges in the

我正在尝试在有向图上实现深度优先搜索算法。该图存在多个顶点(
V顶点
),每个顶点都有一组边(
E边
)。每条边都有一个指向下一条边的指针(
.getTo()
)和一个指向上一条边的指针(
.getFrom()
)。我想找到从起始顶点到目标顶点的边的路径。为了存储和创建路径,我创建了一个helper类
DGPath
。我想用递归的方式来做这件事

DGPath
创建路径帮助器类下面:

/**
     * represents a path of connected vertices and edges in the graph
     */
    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;
        }
    }
最后,在深度优先搜索方法的
递归
辅助方法下面:

private void dfsHelper(V current, Set<V> discovered) {
        discovered.add(current);
        for (E edge : current.getEdges()) {
            while(edge.getTo() != null){
                V nextV = edge.getTo();
                if (!discovered.contains(nextV)) {
                    dfsHelper(nextV, discovered);
                }
            }
        }

    }
private void dfsHelper(V当前,已发现集){
发现。添加(当前);
对于(E edge:current.getEdges()){
while(edge.getTo()!=null){
V nextV=edge.getTo();
如果(!discovered.contains(nextV)){
dfsHelper(nextV,已发现);
}
}
}
}
这段代码现在不工作,它一直停留在递归中

  • 如何更改此代码以找到从起始顶点到目标顶点的正确路径
  • 如何在
    DGPath.edges
    中保存用于从起点到目标的边

我认为问题在于在for循环中调用dfsheloper函数(我看不出需要循环的原因!!)。对于每个迭代,必须在循环结束时清空path.visited,然后再次执行
path.visited.add(start)

关于第二个问题,请为路径定义另一个字段,例如边,每当您向
path.visted
添加新节点时,请将相应的边添加到
path.edges
(不要忘记刷新path.edges,如每次迭代的
path.visted

调用
depthFirstSearch

后,path.visitored将具有您想要的内容。我通过保存边修复了工作算法:

DGPath帮助器类仍然与上面相同

DFS方法和Recrive“helper”:

我修正了方法(见我的答案),谢谢你的反应。帮助我朝着正确的方向思考!
private void dfsHelper(V current, Set<V> discovered) {
        discovered.add(current);
        for (E edge : current.getEdges()) {
            while(edge.getTo() != null){
                V nextV = edge.getTo();
                if (!discovered.contains(nextV)) {
                    dfsHelper(nextV, discovered);
                }
            }
        }

    }
public DGPath depthFirstSearch(String startId, String targetId) {
        // get node/vertex on ID
        V start = this.getVertexById(startId);
        V target = this.getVertexById(targetId);
        // if they dont exist return null
        if (start == null || target == null) return null;
        // create new path
        DGPath path = new DGPath();
        // set starting node/vertex
        path.start = start;

        // easy target
        if (start == target) {
            path.visited.add(start);
            return path;
        }

        // return the recursive method with starting point, target and the path
        return dfsRecursive(path.start, target, path);
    }

    private DGPath dfsRecursive(V current, V target, DGPath path) {
        // if node/vertex is already visited we have no path
        if (path.getVisited().contains(current)) {
            return null;
        }
        // add current node/vertex to visited set
        path.getVisited().add(current);
        // if we reach the destination we return the path
        if (current.equals(target)) {
            return path;
        }
        // else we go check all de edges connected to the vertex
        for (E edge : current.getEdges()){
            // if there is a new path we continue recursive until destination is reached
            if (dfsRecursive(edge.getTo(), target, path) != null) {
                // we add the edges as first in the set of edges to create the path
                path.getEdges().addFirst(edge);
                return path;
            }
        }
        return null;
    }