Reputation: 2572
We need to compute the minCost(), which has follwing parameters:
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.
Upvotes: 0
Views: 965
Reputation: 32587
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.
Upvotes: 1