-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathWeightedGraph.java
More file actions
executable file
·137 lines (105 loc) · 4.1 KB
/
Copy pathWeightedGraph.java
File metadata and controls
executable file
·137 lines (105 loc) · 4.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
package com.codeWithArsalon.NonLinearDS;
import java.util.*;
public class WeightedGraph {
private class Node{
private String label;
private List<Edge> edges = new ArrayList<>(); //replace adjacency list, list of edge objects, could use HashMap
public Node(String label) {
this.label = label;
}
@Override
public String toString() {
return label;
}
public void addEdge(Node to, int weight){
edges.add(new Edge(this, to, weight)); //object oriented approach
}
public List<Edge> getEdges(){
return edges;
}
}
private class Edge{
private Node from;
private Node to;
private int weight;
public Edge(Node from, Node to, int weight) {
this.from = from;
this.to = to;
this.weight = weight;
}
@Override
public String toString() {
return from + "->" + to;
}
}
private class NodeEntry{
private Node node;
private int priority;
public NodeEntry(Node node, int priority) {
this.node = node;
this.priority = priority;
}
}
private Map<String, Node> nodes = new HashMap<>();
public void addNode(String label){
nodes.putIfAbsent(label, new Node(label)); //automatically initializes edges to a new ArrayList
}
public void addEdge(String from, String to, int weight){
var fromNode = nodes.get(from);
if (fromNode == null)
throw new IllegalArgumentException(); //not a valid node
var toNode = nodes.get(to);
if(toNode == null)
throw new IllegalArgumentException();
fromNode.addEdge(toNode, weight);
toNode.addEdge(fromNode, weight);
}
public Path getShortestPath(String from, String to){
var fromNode = nodes.get(from);
var toNode = nodes.get(to);
Map<Node, Integer> distances = new HashMap<>();
for (var node : nodes.values())
distances.put(node, Integer.MAX_VALUE); //set all values to max
distances.replace(fromNode, 0); //returns current node object, sets 0 as distance value for current
Map<Node, Node> previousNodes = new HashMap<>();
Set<Node> visited = new HashSet<>();
PriorityQueue<NodeEntry> queue = new PriorityQueue<>(
Comparator.comparingInt(ne -> ne.priority)); //anon func gets nodeEntry, returns priority, comparator compares priority
queue.add(new NodeEntry(fromNode, 0));
while(!queue.isEmpty()){
var current = queue.remove().node; //returns nodeEntry obj, so access node field (we want node)
visited.add(current);
for(var edge : current.getEdges()){ //returns list of nodeEdge objects (neighbors)
if(visited.contains(edge.to))
continue;
var newDistance = distances.get(current) + edge.weight;
if(newDistance < distances.get(edge.to)){
distances.replace(edge.to, newDistance);
previousNodes.put(edge.to, current); //edge.to = neighbor
queue.add(new NodeEntry(edge.to, newDistance));
}
}
}
return buildPath(previousNodes, toNode);
}
private Path buildPath( Map<Node, Node> previousNodes, Node toNode) {
Stack<Node> stack = new Stack<>();
stack.push(toNode);
var previous = previousNodes.get(toNode);
while(previous != null){
stack.push(previous);
previous = previousNodes.get(previous);
}
var path = new Path();
while(!stack.isEmpty())
path.add(stack.pop().label); //returns node obj, access label field
return path;
}
public void print(){
for(var node : nodes.values()) {//returns all source nodes
var edges = node.getEdges(); //returns a array list of edges
if(!edges.isEmpty())
System.out.println(node + " is connected to " + edges);
}
}
}