import java.util.PriorityQueue;
import java.util.HashSet;
import java.util.Set;
import java.util.Collections;
import java.util.List;
import java.util.ArrayList;
import java.util.Comparator;
//diff between uniform cost search and dijkstra algo is that UCS has a goal
class UniformCostSearchAlgo{
public static void main
(String[] args
){
//initialize the graph base on the Romania map
Node n1 = new Node("Arad");
Node n2 = new Node("Zerind");
Node n3 = new Node("Oradea");
Node n4 = new Node("Sibiu");
Node n5 = new Node("Fagaras");
Node n6 = new Node("Rimnicu Vilcea");
Node n7 = new Node("Pitesti");
Node n8 = new Node("Timisoara");
Node n9 = new Node("Lugoj");
Node n10 = new Node("Mehadia");
Node n11 = new Node("Drobeta");
Node n12 = new Node("Craiova");
Node n13 = new Node("Bucharest");
Node n14 = new Node("Giurgiu");
//initialize the edges
n1.adjacencies = new Edge[]{
new Edge(n2,75),
new Edge(n4,140),
new Edge(n8,118)
};
n2.adjacencies = new Edge[]{
new Edge(n1,75),
new Edge(n3,71)
};
n3.adjacencies = new Edge[]{
new Edge(n2,71),
new Edge(n4,151)
};
n4.adjacencies = new Edge[]{
new Edge(n1,140),
new Edge(n5,99),
new Edge(n3,151),
new Edge(n6,80),
};
n5.adjacencies = new Edge[]{
new Edge(n4,99),
new Edge(n13,1) // changed cost
};
n6.adjacencies = new Edge[]{
new Edge(n4,80),
new Edge(n7,97),
new Edge(n12,146)
};
n7.adjacencies = new Edge[]{
new Edge(n6,97),
new Edge(n13,101),
new Edge(n12,138)
};
n8.adjacencies = new Edge[]{
new Edge(n1,118),
new Edge(n9,111)
};
n9.adjacencies = new Edge[]{
new Edge(n8,111),
new Edge(n10,70)
};
n10.adjacencies = new Edge[]{
new Edge(n9,70),
new Edge(n11,75)
};
n11.adjacencies = new Edge[]{
new Edge(n10,75),
new Edge(n12,120)
};
n12.adjacencies = new Edge[]{
new Edge(n11,120),
new Edge(n6,146),
new Edge(n7,138)
};
n13.adjacencies = new Edge[]{
new Edge(n7,101),
new Edge(n14,90),
new Edge(n5,211)
};
n14.adjacencies = new Edge[]{
new Edge(n13,90)
};
UniformCostSearch(n1,n13);
List<Node> path = printPath(n13);
System.
out.
println("Path: " + path
);
}
public static void UniformCostSearch(Node source, Node goal){
source.pathCost = 0;
PriorityQueue<Node> queue = new PriorityQueue<Node>(20,
new Comparator<Node>(){
//override compare method
public int compare(Node i, Node j){
if(i.pathCost > j.pathCost){
return 1;
}
else if (i.pathCost < j.pathCost){
return -1;
}
else{
return 0;
}
}
}
);
queue.add(source);
Set<Node> explored = new HashSet<Node>();
boolean found = false;
//while frontier is not empty
do{
Node current = queue.poll();
explored.add(current);
if(current.value.equals(goal.value)){
found = true;
}
for(Edge e: current.adjacencies){
Node child = e.target;
double cost = e.cost;
child.pathCost = current.pathCost + cost;
if(!explored.contains(child) && !queue.contains(child)){
child.parent = current;
queue.add(child);
}
else if((queue.contains(child))&&(child.pathCost>current.pathCost)){
child.parent=current;
// the next two calls decrease the key of the node in the queue
queue.remove(child);
queue.add(child);
}
}
}while(!queue.isEmpty());
}
public static List<Node> printPath(Node target){
List<Node> path = new ArrayList<Node>();
for(Node node = target; node!=null; node = node.parent){
path.add(node);
}
return path;
}
}
class Node{
public double pathCost;
public Edge[] adjacencies;
public Node parent;
value = val;
}
return value;
}
}
class Edge{
public final double cost;
public final Node target;
public Edge(Node targetNode, double costVal){
cost = costVal;
target = targetNode;
}
}
aW1wb3J0IGphdmEudXRpbC5Qcmlvcml0eVF1ZXVlOwppbXBvcnQgamF2YS51dGlsLkhhc2hTZXQ7CmltcG9ydCBqYXZhLnV0aWwuU2V0OwppbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOwppbXBvcnQgamF2YS51dGlsLkxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwppbXBvcnQgamF2YS51dGlsLkNvbXBhcmF0b3I7CgovL2RpZmYgYmV0d2VlbiB1bmlmb3JtIGNvc3Qgc2VhcmNoIGFuZCBkaWprc3RyYSBhbGdvIGlzIHRoYXQgVUNTIGhhcyBhIGdvYWwKCmNsYXNzIFVuaWZvcm1Db3N0U2VhcmNoQWxnb3sKICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpewoKICAgICAgICAvL2luaXRpYWxpemUgdGhlIGdyYXBoIGJhc2Ugb24gdGhlIFJvbWFuaWEgbWFwCiAgICAgICAgTm9kZSBuMSA9IG5ldyBOb2RlKCJBcmFkIik7CiAgICAgICAgTm9kZSBuMiA9IG5ldyBOb2RlKCJaZXJpbmQiKTsKICAgICAgICBOb2RlIG4zID0gbmV3IE5vZGUoIk9yYWRlYSIpOwogICAgICAgIE5vZGUgbjQgPSBuZXcgTm9kZSgiU2liaXUiKTsKICAgICAgICBOb2RlIG41ID0gbmV3IE5vZGUoIkZhZ2FyYXMiKTsKICAgICAgICBOb2RlIG42ID0gbmV3IE5vZGUoIlJpbW5pY3UgVmlsY2VhIik7CiAgICAgICAgTm9kZSBuNyA9IG5ldyBOb2RlKCJQaXRlc3RpIik7CiAgICAgICAgTm9kZSBuOCA9IG5ldyBOb2RlKCJUaW1pc29hcmEiKTsKICAgICAgICBOb2RlIG45ID0gbmV3IE5vZGUoIkx1Z29qIik7CiAgICAgICAgTm9kZSBuMTAgPSBuZXcgTm9kZSgiTWVoYWRpYSIpOwogICAgICAgIE5vZGUgbjExID0gbmV3IE5vZGUoIkRyb2JldGEiKTsKICAgICAgICBOb2RlIG4xMiA9IG5ldyBOb2RlKCJDcmFpb3ZhIik7CiAgICAgICAgTm9kZSBuMTMgPSBuZXcgTm9kZSgiQnVjaGFyZXN0Iik7CiAgICAgICAgTm9kZSBuMTQgPSBuZXcgTm9kZSgiR2l1cmdpdSIpOwoKICAgICAgICAvL2luaXRpYWxpemUgdGhlIGVkZ2VzCiAgICAgICAgbjEuYWRqYWNlbmNpZXMgPSBuZXcgRWRnZVtdewogICAgICAgICAgICBuZXcgRWRnZShuMiw3NSksCiAgICAgICAgICAgIG5ldyBFZGdlKG40LDE0MCksCiAgICAgICAgICAgIG5ldyBFZGdlKG44LDExOCkKICAgICAgICB9OwoKICAgICAgICBuMi5hZGphY2VuY2llcyA9IG5ldyBFZGdlW117CiAgICAgICAgICAgIG5ldyBFZGdlKG4xLDc1KSwKICAgICAgICAgICAgbmV3IEVkZ2UobjMsNzEpCiAgICAgICAgfTsKCiAgICAgICAgbjMuYWRqYWNlbmNpZXMgPSBuZXcgRWRnZVtdewogICAgICAgICAgICBuZXcgRWRnZShuMiw3MSksCiAgICAgICAgICAgIG5ldyBFZGdlKG40LDE1MSkKICAgICAgICB9OwoKICAgICAgICBuNC5hZGphY2VuY2llcyA9IG5ldyBFZGdlW117CiAgICAgICAgICAgIG5ldyBFZGdlKG4xLDE0MCksCiAgICAgICAgICAgIG5ldyBFZGdlKG41LDk5KSwKICAgICAgICAgICAgbmV3IEVkZ2UobjMsMTUxKSwKICAgICAgICAgICAgbmV3IEVkZ2UobjYsODApLAogICAgICAgIH07CgogICAgICAgIG41LmFkamFjZW5jaWVzID0gbmV3IEVkZ2VbXXsKICAgICAgICAgICAgbmV3IEVkZ2UobjQsOTkpLAogICAgICAgICAgICBuZXcgRWRnZShuMTMsMSkgLy8gY2hhbmdlZCBjb3N0CiAgICAgICAgfTsKCiAgICAgICAgbjYuYWRqYWNlbmNpZXMgPSBuZXcgRWRnZVtdewogICAgICAgICAgICBuZXcgRWRnZShuNCw4MCksCiAgICAgICAgICAgIG5ldyBFZGdlKG43LDk3KSwKICAgICAgICAgICAgbmV3IEVkZ2UobjEyLDE0NikKICAgICAgICB9OwoKICAgICAgICBuNy5hZGphY2VuY2llcyA9IG5ldyBFZGdlW117CiAgICAgICAgICAgIG5ldyBFZGdlKG42LDk3KSwKICAgICAgICAgICAgbmV3IEVkZ2UobjEzLDEwMSksCiAgICAgICAgICAgIG5ldyBFZGdlKG4xMiwxMzgpCiAgICAgICAgfTsKCiAgICAgICAgbjguYWRqYWNlbmNpZXMgPSBuZXcgRWRnZVtdewogICAgICAgICAgICBuZXcgRWRnZShuMSwxMTgpLAogICAgICAgICAgICBuZXcgRWRnZShuOSwxMTEpCiAgICAgICAgfTsKCiAgICAgICAgbjkuYWRqYWNlbmNpZXMgPSBuZXcgRWRnZVtdewogICAgICAgICAgICBuZXcgRWRnZShuOCwxMTEpLAogICAgICAgICAgICBuZXcgRWRnZShuMTAsNzApCiAgICAgICAgfTsKCiAgICAgICAgbjEwLmFkamFjZW5jaWVzID0gbmV3IEVkZ2VbXXsKICAgICAgICAgICAgbmV3IEVkZ2UobjksNzApLAogICAgICAgICAgICBuZXcgRWRnZShuMTEsNzUpCiAgICAgICAgfTsKCiAgICAgICAgbjExLmFkamFjZW5jaWVzID0gbmV3IEVkZ2VbXXsKICAgICAgICAgICAgbmV3IEVkZ2UobjEwLDc1KSwKICAgICAgICAgICAgbmV3IEVkZ2UobjEyLDEyMCkKICAgICAgICB9OwoKICAgICAgICBuMTIuYWRqYWNlbmNpZXMgPSBuZXcgRWRnZVtdewogICAgICAgICAgICBuZXcgRWRnZShuMTEsMTIwKSwKICAgICAgICAgICAgbmV3IEVkZ2UobjYsMTQ2KSwKICAgICAgICAgICAgbmV3IEVkZ2UobjcsMTM4KQogICAgICAgIH07CgogICAgICAgIG4xMy5hZGphY2VuY2llcyA9IG5ldyBFZGdlW117CiAgICAgICAgICAgIG5ldyBFZGdlKG43LDEwMSksCiAgICAgICAgICAgIG5ldyBFZGdlKG4xNCw5MCksCiAgICAgICAgICAgIG5ldyBFZGdlKG41LDIxMSkKICAgICAgICB9OwoKICAgICAgICBuMTQuYWRqYWNlbmNpZXMgPSBuZXcgRWRnZVtdewogICAgICAgICAgICBuZXcgRWRnZShuMTMsOTApCiAgICAgICAgfTsKCiAgICAgICAgVW5pZm9ybUNvc3RTZWFyY2gobjEsbjEzKTsKCiAgICAgICAgTGlzdDxOb2RlPiBwYXRoID0gcHJpbnRQYXRoKG4xMyk7CgogICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiUGF0aDogIiArIHBhdGgpOwoKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHZvaWQgVW5pZm9ybUNvc3RTZWFyY2goTm9kZSBzb3VyY2UsIE5vZGUgZ29hbCl7CgogICAgICAgIHNvdXJjZS5wYXRoQ29zdCA9IDA7CiAgICAgICAgUHJpb3JpdHlRdWV1ZTxOb2RlPiBxdWV1ZSA9IG5ldyBQcmlvcml0eVF1ZXVlPE5vZGU+KDIwLCAKICAgICAgICAgICAgbmV3IENvbXBhcmF0b3I8Tm9kZT4oKXsKCiAgICAgICAgICAgICAgICAvL292ZXJyaWRlIGNvbXBhcmUgbWV0aG9kCiAgICAgICAgICAgICAgICBwdWJsaWMgaW50IGNvbXBhcmUoTm9kZSBpLCBOb2RlIGopewogICAgICAgICAgICAgICAgICAgIGlmKGkucGF0aENvc3QgPiBqLnBhdGhDb3N0KXsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChpLnBhdGhDb3N0IDwgai5wYXRoQ29zdCl7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGVsc2V7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICApOwoKICAgICAgICBxdWV1ZS5hZGQoc291cmNlKTsKICAgICAgICBTZXQ8Tm9kZT4gZXhwbG9yZWQgPSBuZXcgSGFzaFNldDxOb2RlPigpOwogICAgICAgIGJvb2xlYW4gZm91bmQgPSBmYWxzZTsKCiAgICAgICAgLy93aGlsZSBmcm9udGllciBpcyBub3QgZW1wdHkKICAgICAgICBkb3sKCiAgICAgICAgICAgIE5vZGUgY3VycmVudCA9IHF1ZXVlLnBvbGwoKTsKICAgICAgICAgICAgZXhwbG9yZWQuYWRkKGN1cnJlbnQpOwoKCiAgICAgICAgICAgIGlmKGN1cnJlbnQudmFsdWUuZXF1YWxzKGdvYWwudmFsdWUpKXsKICAgICAgICAgICAgICAgIGZvdW5kID0gdHJ1ZTsKCgogICAgICAgICAgICB9CgoKCgogICAgICAgICAgICBmb3IoRWRnZSBlOiBjdXJyZW50LmFkamFjZW5jaWVzKXsKICAgICAgICAgICAgICAgIE5vZGUgY2hpbGQgPSBlLnRhcmdldDsKICAgICAgICAgICAgICAgIGRvdWJsZSBjb3N0ID0gZS5jb3N0OwogICAgICAgICAgICAgICAgY2hpbGQucGF0aENvc3QgPSBjdXJyZW50LnBhdGhDb3N0ICsgY29zdDsKCgoKICAgICAgICAgICAgICAgIGlmKCFleHBsb3JlZC5jb250YWlucyhjaGlsZCkgJiYgIXF1ZXVlLmNvbnRhaW5zKGNoaWxkKSl7CgogICAgICAgICAgICAgICAgICAgIGNoaWxkLnBhcmVudCA9IGN1cnJlbnQ7CiAgICAgICAgICAgICAgICAgICAgcXVldWUuYWRkKGNoaWxkKTsKCiAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKGNoaWxkKTsKICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4ocXVldWUpOwogICAgICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigpOwoKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYoKHF1ZXVlLmNvbnRhaW5zKGNoaWxkKSkmJihjaGlsZC5wYXRoQ29zdD5jdXJyZW50LnBhdGhDb3N0KSl7CiAgICAgICAgICAgICAgICAgICAgY2hpbGQucGFyZW50PWN1cnJlbnQ7CgogICAgICAgICAgICAgICAgICAgIC8vIHRoZSBuZXh0IHR3byBjYWxscyBkZWNyZWFzZSB0aGUga2V5IG9mIHRoZSBub2RlIGluIHRoZSBxdWV1ZQogICAgICAgICAgICAgICAgICAgIHF1ZXVlLnJlbW92ZShjaGlsZCk7CiAgICAgICAgICAgICAgICAgICAgcXVldWUuYWRkKGNoaWxkKTsKICAgICAgICAgICAgICAgIH0KCgogICAgICAgICAgICB9CiAgICAgICAgfXdoaWxlKCFxdWV1ZS5pc0VtcHR5KCkpOwoKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIExpc3Q8Tm9kZT4gcHJpbnRQYXRoKE5vZGUgdGFyZ2V0KXsKICAgICAgICBMaXN0PE5vZGU+IHBhdGggPSBuZXcgQXJyYXlMaXN0PE5vZGU+KCk7CiAgICAgICAgZm9yKE5vZGUgbm9kZSA9IHRhcmdldDsgbm9kZSE9bnVsbDsgbm9kZSA9IG5vZGUucGFyZW50KXsKICAgICAgICAgICAgcGF0aC5hZGQobm9kZSk7CiAgICAgICAgfQoKICAgICAgICBDb2xsZWN0aW9ucy5yZXZlcnNlKHBhdGgpOwoKICAgICAgICByZXR1cm4gcGF0aDsKCiAgICB9Cgp9CgpjbGFzcyBOb2RlewoKICAgIHB1YmxpYyBmaW5hbCBTdHJpbmcgdmFsdWU7CiAgICBwdWJsaWMgZG91YmxlIHBhdGhDb3N0OwogICAgcHVibGljIEVkZ2VbXSBhZGphY2VuY2llczsKICAgIHB1YmxpYyBOb2RlIHBhcmVudDsKCiAgICBwdWJsaWMgTm9kZShTdHJpbmcgdmFsKXsKCiAgICAgICAgdmFsdWUgPSB2YWw7CgogICAgfQoKICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKXsKICAgICAgICByZXR1cm4gdmFsdWU7CiAgICB9Cgp9CgpjbGFzcyBFZGdlewogICAgcHVibGljIGZpbmFsIGRvdWJsZSBjb3N0OwogICAgcHVibGljIGZpbmFsIE5vZGUgdGFyZ2V0OwoKICAgIHB1YmxpYyBFZGdlKE5vZGUgdGFyZ2V0Tm9kZSwgZG91YmxlIGNvc3RWYWwpewogICAgICAgIGNvc3QgPSBjb3N0VmFsOwogICAgICAgIHRhcmdldCA9IHRhcmdldE5vZGU7CgogICAgfQp9
Zerind
[Zerind]
Sibiu
[Zerind, Sibiu]
Timisoara
[Zerind, Sibiu, Timisoara]
Oradea
[Timisoara, Sibiu, Oradea]
Lugoj
[Sibiu, Oradea, Lugoj]
Fagaras
[Oradea, Lugoj, Fagaras]
Rimnicu Vilcea
[Rimnicu Vilcea, Lugoj, Oradea, Fagaras]
Pitesti
[Lugoj, Fagaras, Oradea, Pitesti]
Craiova
[Lugoj, Fagaras, Oradea, Pitesti, Craiova]
Mehadia
[Fagaras, Mehadia, Oradea, Craiova, Pitesti]
Bucharest
[Bucharest, Oradea, Pitesti, Craiova, Mehadia]
Giurgiu
[Oradea, Mehadia, Craiova, Pitesti, Giurgiu]
Drobeta
[Giurgiu, Pitesti, Craiova, Drobeta]
Path: [Arad, Sibiu, Fagaras, Bucharest]