简体   繁体   中英

How to calculate the shortest path between two vertices in Graph with given parameters?

We need to compute the minCost() , which has follwing parameters:

  1. gNodes - no of Nodes in graph g.
  2. an array of int's, gFrom , where each gfrom[i] denotes a node connected by ith edge in graph g.
  3. an array of int's, gTo , where each gTo[i] denotes a node connected by ith edge in graph g.
  4. an array of int's, gWeight , denoting the respective weights of each edge in graph g.
  5. an int, start , denoting the start node index.
  6. an int, end , denoting the end node index.
  7. an integer, wExtra , denoting the weight of optional extra edge.

We need to find the path from start to end having minimum possible weight. We can add at most one extra edge(ie. zero or one) having wExtra weight between any two distinct nodes that are not already connected by an edge. The function must return an int denoting the minimum path weight from start to end.

I was able to come up with following code (Dijkstra algorithm) but it doesn't give the expected output.

    public static int minCost(int gNodes, int[] gFrom, int[] gTo, int[] gWeights, int start, int end) {
//making a array to store shortest length and filling it with infinity except the first one
            int[] shortest = new int[gNodes];
            for (int i = 0; i < gNodes; i++) {
                shortest[i] = Integer.MAX_VALUE;
            }
            shortest[start]=0;
//filling the Queue with all vertices
        Queue<Integer> theQ = new PriorityQueue<>();
        for (int i = 0; i < gNodes; i++) {
            theQ.add(i + 1);
        }
//following the algorithm
        while (!theQ.isEmpty()) {
            int u = theQ.poll();
//making a list of adjacent vertices

            List<Integer> adjacent = new ArrayList<>();
            for (int i = 0; i < gFrom.length; i++) {
                if (gFrom[i] == u) {
                    adjacent.add(gTo[i]);
                } else if (gTo[i] == u) {
                    adjacent.add(gFrom[i]);
                }
            }
            for (int v: adjacent) {
                int weight=0;
                for (int i = 0; i < gFrom.length; i++) {
                    if ((gFrom[i] == u && gTo[i] == v) || (gFrom[i] == v && gTo[i] == u)) {
                        weight = gWeights[i];
                    }
                }

//relaxing the verices
                if (shortest[v] > shortest[u] + weight) {
                    shortest[v] = shortest[u] + weight;
                }
                if (v == end) {
                    return shortest[v];
                }
                theQ.add(v);
            }
        }
        return -1;
    }


    public static void main(String[] args) {
        int gNodes = 4;
        int[] gFrom = {1, 2, 2, 3};
        int[] gTo = {2, 3, 4, 4};
        int[] gWeights = {2, 1, 2, 3};
        int start =1;
        int end = 4;
        System.out.println(shortestDistance(gNodes, gFrom, gTo, gWeights, start, end));
    }
}

It's not giving the expected output which I think is because I can't think of how to use that wExtra . Also, the code is quite messy. Please let me know what's wrong or feel free to provide any robust code that does it well. Thanks.

A possible idea to integrate wExtra is the following:

Duplicate the graph, such that you have two nodes for every input node. The original graph represents the state before introducing the new edge. The copy represents the state after the introduction. For every node n in the original graph, you should then introduce directed edges with weight wExtra to all nodes m in the copy, where the original of m is not adjacent to n . This basically represents the fact that you can introduce a new edge between any two non-adjacent edges. But once you have done this, you cannot go back. Then, run usual Dijkstra on the modified graph between start and either the original end or the copy of end and you should get the correct result.

The best way to visualize this is probably to interpret the two sub graphs as layers. You start at the original layer and want to get to one of the two end nodes (whichever is closer). But you may switch layers only once.

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