简体   繁体   English

使用 DFS 和堆栈的未加权图中的最短路径

[英]Shortest path in unweighted graph using DFS and stack

Im new at coding in java, im trying to code a program that can find the shortest path in an unweighted graph using DFS method and a stack.我是 java 编码的新手,我正在尝试编写一个程序,该程序可以使用 DFS 方法和堆栈在未加权图中找到最短路径。 Im looking forward for a recursive DFS method that can find the shortes path between two nodes.我期待着一种递归 DFS 方法,可以找到两个节点之间的最短路径。 I dont know how to implement DFS im searching for help, here is my code.我不知道如何实现 DFS 即时搜索帮助,这是我的代码。

    import java.util.ArrayList;
    import java.util.LinkedList;
    import java.util.Stack;

    import javax.swing.JOptionPane;

    public class pruebaGrafosinpesos {

public static void main(String[] args) {
    // TODO Auto-generated method stub
    int opcion=0, i=0, origen=0, destino=0, contador=0, n=-1;
    boolean[] visitados= new boolean[10];//arreglo que indica los nodos visitados
    Stack<Integer> camino= new Stack();//stack que guarda el camino recorrido
    Stack<Integer> temp= new Stack();//stack que guarda el camino recorrido
    LinkedList<Integer>[] nodo = new LinkedList[10];//arreglo de las conexiones de cada nodo

    for(i=0; i<10; i++) {
        nodo[i]= new LinkedList<Integer>();
    }

    for(i=0; i<10; i++) {
        visitados[i]=false;
    }

    //inicializo el grafo
    nodo[0].add(1); nodo[0].add(2);
    nodo[1].add(0); nodo[1].add(2); nodo[1].add(3);
    nodo[2].add(1); nodo[2].add(5); nodo[2].add(6);
    nodo[3].add(1); nodo[3].add(4); nodo[3].add(7);
    nodo[4].add(3); nodo[4].add(5); nodo[4].add(7);
    nodo[5].add(2); nodo[5].add(4); nodo[5].add(6); nodo[5].add(8);
    nodo[6].add(2); nodo[6].add(5); nodo[6].add(8);
    nodo[7].add(3); nodo[7].add(4); nodo[7].add(8);
    nodo[8].add(4); nodo[8].add(5); nodo[8].add(6); nodo[8].add(9);
    nodo[9].add(7); nodo[9].add(8);

    ///////////////// Matriz //////////////////////
    /*|   | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
      | 0 | / | * | * |   |   |   |   |   |   |   |
      | 1 | * | / | * | * |   |   |   |   |   |   |
      | 2 |   | * | / |   |   | * | * |   |   |   |
      | 3 |   | * |   | / | * |   |   | * |   |   |
      | 4 |   |   |   | * | / | * |   | * |   |   |
      | 5 |   |   | * |   | * | / | * |   | * |   |
      | 6 |   |   | * |   |   | * | / |   | * |   |
      | 7 |   |   |   | * | * |   |   | / | * |   |
      | 8 |   |   |   |   | * | * | * |   | / | * |
      | 9 |   |   |   |   |   |   |   | * | * | / |*/
    ///////////////////////////////////////////////

    do {
        opcion=Integer.parseInt(JOptionPane.showInputDialog("1.-Encontrar el camino mas corto\n 2.-Salir\n Escoge una opcion"));
        switch(opcion) {
            case 1:
                origen=Integer.parseInt(JOptionPane.showInputDialog("Dame el nodo origen"));
                destino=Integer.parseInt(JOptionPane.showInputDialog("Dame el nodo destino"));

                n=origen;

                while(contador<=10) {
                    if(visitados[n]==false) {//si el nodo no ha sido visitado
                        visitados[n]=true;//se visita
                        camino.push(n);//se agrega al stack del camino recorrido
                        contador++;
                    }




                }

                break;

            case 2:
                break;

        }
    }while(opcion!=2);

}

} }

If you are happy to use a recursive method then you really don't need your stack variables.如果您乐于使用递归方法,那么您真的不需要堆栈变量。 You just need a single field to store the shortest path found so far您只需要一个字段来存储目前找到的最短路径

I can provide some pseudocode here for you to convert to Java我可以在这里提供一些伪代码供您转换为 Java

shortest = null
dfs({start})

dfs(path):
    if end of path is destination
        if shortest is null or path is shorter than shortest
            shortest = path
    else
        for each node reachable from end of path
            if node not in path
                dfs(path + node)

That algorithm will perform a DFS of the entire graph and find the shortest path from start to destination nodes.该算法将对整个图执行 DFS,并找到从起点到目标节点的最短路径。 You could also have it return the shortest path instead of storing it as a side effect of the search.您也可以让它返回最短路径,而不是将其存储为搜索的副作用。


For your interest, here's a solution using a slightly different data structure.为了您的兴趣,这里有一个使用稍微不同的数据结构的解决方案。 The path essentially acts as a stack.路径本质上充当堆栈。

public class Network {
    private final List<Node> nodes;

    private class Node {
        private final List<Node> links = new ArrayList<>();
    }

    public class Path {
        private final Optional<Path> previous;
        private final Node end;

        private Path(Optional<Path> previous, Node node) {
            this.previous = previous;
            this.end = node;
        }

        public String toString() {
            return nodes().map(n -> Integer.toString(nodes.indexOf(n))).collect(Collectors.joining(", "));
        }

        private Stream<Node> nodes() {
            return Stream.concat(previous.stream().flatMap(Path::nodes), Stream.of(end));
        }
    }

    public Network(int nodeCount) {
        this.nodes = IntStream.range(0, nodeCount).mapToObj(i -> new Node()).collect(Collectors.toList());
    }

    public void linkNodes(int from, int to) {
        assert from != to : "link to self";
        getNode(from).links.add(getNode(to));
        getNode(to).links.add(getNode(from));
    }

    public Optional<Path> shortest(int from, int to) {
        return shortest(new Path(Optional.empty(), getNode(from)), getNode(to));
    }

    private Optional<Path> shortest(Path path, Node to) {
        if (path.end.equals(to))
            return Optional.of(path);
        else
            return path.end.links.stream()
                    .filter(ln -> path.nodes().noneMatch(ln::equals))
                    .flatMap(ln -> shortest(new Path(Optional.of(path), ln), to).stream())
                    .min(Comparator.comparingLong(p -> p.nodes().count()));
    }

    private Node getNode(int id) {
        assert id >= 0 && id < nodes.size(): "illegal node id";
        return nodes.get(id);
    }
}

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

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