Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/309.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 Prim';s MST至Dijkstra SPT_Java_Algorithm - Fatal编程技术网

Java Prim';s MST至Dijkstra SPT

Java Prim';s MST至Dijkstra SPT,java,algorithm,Java,Algorithm,我遵循这本书的内容,在第294页中,它描述了通过修改Prim的最小生成树(MST)算法(我测试过并运行良好),我们可以使用经典的Dijkstra算法:将优先级分配从p=e->wt()边权重更改为p=wt[v]+e->wt()从源到边缘目标的距离。问题是,当我进行更改时,随后的条件从未计算为true,这是可以理解的wt是一个双数组,初始化为例如double.MAX_值因此,无论v和w是什么,该条件都不会成立(假设权重为非负): 你弄错了,因为v!=w、 wt[v]+e->wt()可以小于wt[w

我遵循这本书的内容,在第294页中,它描述了通过修改Prim的最小生成树(MST)算法(我测试过并运行良好),我们可以使用经典的Dijkstra算法:将优先级分配从
p=e->wt()
边权重更改为
p=wt[v]+e->wt()
从源到边缘目标的距离。问题是,当我进行更改时,随后的条件从未计算为
true
,这是可以理解的
wt
是一个双数组,初始化为例如
double.MAX_值
因此,无论
v
w
是什么,该条件都不会成立(假设权重为非负):


    你弄错了,因为v!=w、 wt[v]+e->wt()可以小于wt[w]。实际的错误是您需要设置
    wt[source]=0
    (dijkstra是单源最短路径,您需要一个源!)!关于这本书:如果他们忘了那一部分,他们的坏处是:-P

    谢谢。很好的捕获,但是算法仍然不起作用:(好的,我检查了发生了什么,条件
    if(wt[w]
    永远不会为真,因为
    wt[min]
    when
    min==source
    为零。
    P = wt[v] + e->wt();
    if (P < wt[w]) { // this can never happen ... bug?
       // ...
    } 
    
    import java.util.*;
    
    public class AdjacencyList {
        //=============================================================
        // members
        //=============================================================
        private static class Edge {
            int source;
            int target;
            double weight;
        };
        private static class Vertex {
            int index;
            String name;
            List<Edge> edges = new ArrayList<Edge>();
            public Vertex(int index, String name) {
                this.index = index;
                this.name = name;
            }
        };
        private static final int UNDEFINED = -1;
        private int edgesCount = 0;
        private final Vertex[] vertices;
        private final boolean digraph;
        private int orderCount;
    
        //=============================================================
        // public
        //=============================================================
        public AdjacencyList(int verticesCount, boolean digraph) {
            this.vertices = new Vertex[verticesCount];
            this.digraph = digraph;
        }
    
        public Vertex createVertex(int index) {
            return createVertex(index, String.valueOf(index));
        }
    
        public Vertex createVertex(int index, String name) {
            Vertex vertex = new Vertex(index, name);
            vertex.index = index;
            vertex.name = name;
            vertices[index] = vertex;
    
            return vertex;
        }
    
        public Edge addEdge(int begin, int end, double weight) {
            return addEdge(vertices[begin], vertices[end], weight);
        }
    
        public Edge addEdge(Vertex begin, Vertex end, double weight) {
            edgesCount++;
            Edge edge   = new Edge();
            edge.source = begin.index;
            edge.target = end.index;
            edge.weight = weight;
            vertices[begin.index].edges.add(edge);
            if (!digraph) {
                Edge reverse = new Edge();
                reverse.source = end.index;
                reverse.target = begin.index;
                reverse.weight = edge.weight;
                vertices[end.index].edges.add(reverse);
            }
            return edge;
        }
    
        // inefficient find edge O(V)
        public Edge findEdge(int begin, int end) {
            Edge result = null;
            Vertex vertex = vertices[begin];
            List<Edge> adjacency = vertex.edges;
            for (Edge edge : adjacency) {
                if (edge.target == end) {
                    result = edge;
                    break;
                }
            }
            return result;
        }
    
        // inefficient remove edge O(V)
        public void removeEdge(int begin, int end) {
            edgesCount--;
            removeOneEdge(begin, end);
            if (!digraph) {
                removeOneEdge(end, begin);
            }
        }
    
        public final Vertex[] getVertices() {
            return vertices;
        }
    
        public int getVerticesCount() {
            return vertices.length;
        }
    
        public int getEdgesCount() {
            return edgesCount;
        }
    
        public Vertex getSource() {
            return vertices[0];
        }
    
        public Vertex getSink() {
            return vertices[vertices.length - 1];
        }
    
        public void dijkstra() {
            int verticesCount = getVerticesCount();
            double[] wt = new double[verticesCount];
            for (int i = 0; i < wt.length; i++) {
                wt[i] = Double.MAX_VALUE;
            }
            wt[getSource().index] = 0.0;
            Edge[] fr  = new Edge[verticesCount];
            Edge[] mst = new Edge[verticesCount];
            int min = -1;
            Edge edge = null;
            for (int v = 0; min != 0; v = min) {
                min = 0;
                for (int w = 1; w < verticesCount; w++) {
                    if (mst[w] == null) {
                        double P = 0.0;
                        edge = findEdge(v, w);
                        if (edge != null) {
                            if ((P = wt[v] + edge.weight) < wt[w]) {
                                wt[w] = P;
                                fr[w] = edge;
                            }
                        }
    
                        if (wt[w] < wt[min]) {
                            min = w;
                        }
                    }
                }
    
                if (min != 0) {
                    mst[min] = fr[min];
                }
            }
    
            for (int v = 0; v < verticesCount; v++) {
                if (mst[v] != null) {
                    System.out.print(mst[v].source + "->" + mst[v].target + " ");
                }
            }
        }
    
        public void pushRelabel() {
            // TODO
        }
    
        //=============================================================
        // private
        //=============================================================
    
        private void removeOneEdge(int begin, int end) {
            Vertex beginVertex = vertices[begin];
            List<Edge> adjacency = beginVertex.edges;
            int position = -1;
            for (int i = 0; i < adjacency.size(); i++) {
                if (adjacency.get(i).target == end) {
                    position = i;
                    break;
                }
            }
            if (position != -1) {
                adjacency.remove(position);
            }
        }
    
        private static AdjacencyList createDijkstraGraph() {
            int numberOfVertices = 6;
            boolean directed = true;
            AdjacencyList graph = new AdjacencyList(numberOfVertices, directed);
            for (int i = 0; i < graph.getVerticesCount(); i++) {
                graph.createVertex(i);
            }
            graph.addEdge( 0, 1, .41);
            graph.addEdge( 1, 2, .51);
            graph.addEdge( 2, 3, .50);
            graph.addEdge( 4, 3, .36);
            graph.addEdge( 3, 5, .38);
            graph.addEdge( 3, 0, .45);
            graph.addEdge( 0, 5, .29);
            graph.addEdge( 5, 4, .21);
            graph.addEdge( 1, 4, .32);
            graph.addEdge( 4, 2, .32);
            graph.addEdge( 5, 1, .29);
            return graph;
        }
    
        /**
         * Test main
         *
         * @param args
         */
        public static void main(String[] args) {
            // build the graph and test dijkstra shortest path
            AdjacencyList directedDijkstra = createDijkstraGraph();
            // expected:
            System.out.println("\n\n*** testing dijkstra shortest path");
            directedDijkstra.dijkstra();
        }
    }