简体   繁体   中英

Issue in Implementing Dijkstra's algorithm

I am trying to solve a problem where I need to find the max distance between 2 points in a graph. I wrote this code for implementing Dijkstra's algorithm (obviously by changing the minimization to maximization), but it doesn't seem to work in some cases, and I am unable to figure out the unhandled case. Can anyone help me in pointing out what am I missing in my implementation or if something is inherently incorrect?

public double maxDistance(int n, int start, int end) {
    
    Map<Integer, List<Integer>> adjacencyList = getAdjacencyList(); // Adj. list in form of HashMap 
    Map<String, Double> distanceMap = getDistanceMap(); // <Edge, Double> (value is distance)
    Queue<Integer> bfsQueue = new LinkedList<>(); // queue to do a BFS
    
    boolean[] visited = new boolean[n];
    double[] distance = new double[n];
    
    bfsQueue.add(start);
    
    while (!bfsQueue.isEmpty()) {
        int node = bfsQueue.poll();
        
        List<Integer> neighbors = adjacencyList.getOrDefault(node, new ArrayList<>());
        for (int neighbor: neighbors) {
            if (visited[neighbor]) continue;
            bfsQueue.add(neighbor);
            double edgeLength = distanceMap.get(new Edge(node, neighbor));
            double newLength = distance[node] + edgeLength;
            if (newLength > distance[neighbor]) {
                distance[neighbor] = newLength;
            }
        }
        visited[node] = true;
    }

    return distance[end];
}

First, Dijkstra's algorithm finds the shortest path, thus it should be minDistance , not maxDistance .

Next, to implement a breadth-first search, you need a sorted data structure. Your bfsQueue is currently just a LinkedList . With a linked list, you iterate over the items in the order of insertion. But in Dijkstra's algorithm it is important to always handle the next nearest neighbor. It is thus usually implemented with a priority queue.

As example why this makes a difference: Image you want to go from A to B. There are two routes available, a long one consisting of two edges, and a shorter one consisting of 4 edges. In your case, you basically expand through the graph by the number of edges since the start, and not by the distance. So you would first find the route consisting of two edges, even if this is the slower one.

If you use a PriorityQueue , be alerted that reducing the distance/priority of a neighbor as you do it currently ( if (newLength > distance[neighbor]) { distance[neighbor] = newLength; } ) will not work, as the priority queue will not automatically re-sort. You'll have to first remove the neighbor from the priority queue, update the distance, and then re-insert it into the priority queue so it gets sorted into the right place.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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