简体   繁体   English

Dijkstra无向图的最短路径

[英]Dijkstra shortest path for an undirected graph

My following code is working perfectly fine for directed graphs and when given an undirected graph, it will not return the shortest path. 我的下面的代码对于有向图非常有效,当给定无向图时,它不会返回最短路径。

public void Djikstra(int s){
    boolean[] marked = new boolean[V];
    dist = new double[V];

    for(int i = 0; i<V; i++){ # initializing array
        dist[i] = Double.POSITIVE_INFINITY;
    }
    dist[s] = 0.0;

    Queue<Integer> pqs = new PriorityQueue<Integer>();

    pqs.add(s);
    while(!pqs.isEmpty()){
        int v = pqs.poll();

        if(marked[v]) continue;
        marked[v] = true;

        for(Edge e : get_list(v)){ # get_list(v) will return an iterable from the adjacency list at index v 
            v = e.getV()
            int w = e.getW();
            if(dist[w] > dist[v] + e.getWeight()){
                dist[w] = dist[v] + e.getWeight();
                distances[w] = e #all the distances will be stored in this array
                pqs.add(w);
            }
        }
    }
}

I'm not sure what's my mistake over here? 我不确定这里的错误是什么? I'm kind of sure it's a simple error, some hints will do the job. 我确定这是一个简单的错误,一些提示将完成这项工作。

Thanks. 谢谢。

Edit: 编辑:

public void addEdge(Edge e){
    adj[e.getV()].add(e);
    adj[e.getW()].add(e);
}

Consider the differences between a directed path from node 1 to 2 and an undirected path from node 1 to 2. 考虑从节点1到2的有向路径与从节点1到2的无向路径之间的差异。

What would you need to add to the directed graph (which your algorithm can solve) to make it equivalent to the undirected graph? 您需要将哪些内容添加到有向图(您的算法可以解决)以使其等效于无向图?

EDIT: 编辑:

Figured it out, I think. 我想,想出来了。 Here's the hint: You are currently changing resetting v inside of your for loop. 这是提示:您正在更改for循环中的重置v。 This will not cause an error with a directed graph, but what happens if the edge is listed as going from w to v instead of v to w undirected? 这不会导致有向图的错误,但是如果边缘被列为从w到v而不是v到w是无向的,会发生什么?

EDIT2: EDIT2:

Something like this: 像这样的东西:

First, remove v = e.getV(); 首先,删除v = e.getV();

Second, change the next line to int w = (v == e.getV()) ? e.getW() : e.getV(); 第二,将下一行更改为int w = (v == e.getV()) ? e.getW() : e.getV(); int w = (v == e.getV()) ? e.getW() : e.getV();

This sets the value of w to whichever vertex of your edge v is NOT. 这会将w的值设置为边v的哪个顶点不是。

This second suggestion is equivalent to the following (maybe a bit easier to read): 第二个建议等同于以下内容(可能更容易阅读):

int w = e.getW();
if (w == v) {
    w = e.getV();
}

You have to add two different edges, the direct and the inverse. 您必须添加两个不同的边,直接和反向。 Change 更改

public void addEdge(Edge e){
    adj[e.getV()].add(e);
    adj[e.getW()].add(e);
}

in

public void addEdge(Edge e){
    adj[e.getV()].add(e);
}

and, when you add the edges, do it like this: 并且,当您添加边时,请执行以下操作:

Edge e = new Edge(from, to, weight);
Edge f = new Edge(to, from, weight);

addEdge(e);
addEdge(f);

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

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