-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathGraph.java
More file actions
316 lines (287 loc) · 11.3 KB
/
Copy pathGraph.java
File metadata and controls
316 lines (287 loc) · 11.3 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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
package Graphes;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Objects;
import java.util.StringJoiner;
// TODO predecessors list builder since they're optionals to build the graph
// TODO remove
public class Graph {
private final ArrayList<Node> nodes;
private ArrayList<Arc> arcs;
private boolean debug = false;
//
// CONSTRUCTOR
//
/**
* Constructor*/
public Graph(){
this.nodes = new ArrayList<>();
this.arcs = new ArrayList<>();
}
//
// GETTERS
//
/**
* @return the list of all nodes present in the graph*/
public ArrayList<Node> listNodes (){return new ArrayList<>(nodes);}
/**
* @return the list of all arcs present in the graph*/
public ArrayList<Arc> listArcs() {return new ArrayList<>(arcs);}
/**
* @param node to get successors of
* @return list of of nodes names successors of this node*/
public ArrayList<Node> listSuccessors(Node node) {
ArrayList<Node> result = new ArrayList<>();
for (String succNode : node.getSuccessors()){
result.add(getNode(succNode));
}
return result;
}
/**
* @param node to get successors of
* @return list of of nodes names predecessors of this node*/
public ArrayList<Node> listPredecessors(Node node) {
ArrayList<Node> result = new ArrayList<>();
for (String predNode : node.getPredecessors()){
result.add(getNode(predNode));
}
return result;
}
//
// ARCS METHODS
//
/**
* Get an arc object from the graph, the arc must exist
* @param begin node from which the arc start
* @param end node from which the arc end
* @return the arc between the two nodes if it exists, or null*/
public Arc getArc(Node begin, Node end){
for (Arc arc: listArcs()) {
if (arc.getBegin() == begin && arc.getEnd() == end) {return arc;}
}
return null;
}
/**
* Look for an arc between two nodes in the arc list of the graph
* @param begin node from which the arc start
* @param end node from which the arc end
* @return true if an arc exist between the two nodes*/
public Boolean existArc(Node begin, Node end){
return existArc(begin,end,listArcs());
}
/**
* Look for an arc between two nodes in one arc list
* Private because graph user don't any other arc list
* Static because it doesn't need to be and instance of the object
* @param begin node from which the arc start
* @param end node from which the arc end
* @param arcsList a list of arcs
* @return true if an arc exist between the two nodes*/
private static Boolean existArc(Node begin, Node end, ArrayList<Arc> arcsList){
for (Arc arc: arcsList) {
if (arc.getBegin() == begin && arc.getEnd() == end) {return true;}
}
return false;
}
/**
* Get the cost of an arc, the arc must exist
* @param begin node from which the arc start
* @param end node from which the arc end
* @return the value of the requested arc, or -1 if it doesn't exist*/
public Integer getArcValue (Node begin, Node end){
if (existArc(begin,end)) {return Objects.requireNonNull(getArc(begin, end)).getValue();}
return -1;
}
/**
* Set the cost of an arc, the arc must exist
* @param begin node from which the arc start
* @param end node from which the arc end*/
public void setArcValue (Node begin, Node end, Integer value){
if (existArc(begin,end)) {Objects.requireNonNull(getArc(begin, end)).setValue(value);}
}
/**
* Add a new arc between two
* private method because arc list is auto generated from node successors
* @param begin node from which the arc start
* @param end node from which the arc end*/
private void addArc(Node begin, Node end){
if (!existArc(begin, end)){
arcs.add(new Arc(begin,end));
}
}
/**
* Add a new valued arc between two nodes
* private method because arc list is auto generated from node successors
* @param begin node from which the arc start
* @param end node from which the arc end
* @param value cost of this arc*/
private void addArc(Node begin, Node end, Integer value){
if (!existArc(begin, end)){
arcs.add(new Arc(begin,end,value));
}
}
/**
* Remove an arc between two nodes
* private method because arc list is auto generated from node successors
* @param begin node from which the arc start
* @param end node from which the arc end*/
private void removeArc(Node begin, Node end){
if (existArc(begin, end)){arcs.remove(getArc(begin, end));}
}
//
// NODE METHODS
//
/**
* Access a node with just his name, each node must have an unique name
* @param nodeName name of the node to retrieve
* @return the node object corresponding to the requested name or null if it doesn't exist*/
public Node getNode(String nodeName){
for (Node node: nodes) {if (node.getName().equalsIgnoreCase(nodeName)) {return node;}}
System.out.println("Error : node " + nodeName + " does not exist in this graph");
return null;
}
/**
* Access a node with just his name, each node must have an unique name
* Private because not required outside this class
* @param nodeName name of the node to retrieve
* @return true if the node exist in graph*/
private Boolean existNode(String nodeName){
for (Node node: nodes) {if (node.getName().equalsIgnoreCase(nodeName)) {return true;}}
return false;
}
/**
* Access a node with just his name, each node must have an unique name
* Private because not required outside this class
* @param node node to check
* @return true if the node exist in graph*/
private Boolean existNode(Node node){
return nodes.contains(node);
}
/**
* Add a new node to the graph
* @param node node to be added to the graph*/
public void addNode(Node node){
if (!existNode(node)) {nodes.add(node);}
}
/**
* Remove a node from the graph
* @param node node to be removed from the graph*/
public void removeNode(Node node){
if (existNode(node)) {nodes.remove(node);}
}
//
// BUILDERS
//
/**
* Build all the arcs from this node / to the successors of this node
* @param node node to build arcs from*/
private void buildArcsFromNode(Node node, ArrayList<Arc> arcsList){
if (debug) System.out.println("Building arc from "+node.getName());
for (String nodeName: node.getSuccessors()) {
// If node exist
if (existNode(nodeName)) {
// If arc don't already exist
if (!existArc(node,getNode(nodeName))){
// If arc don't already in the arcsList create it and add it to the list
if (!existArc(getNode(nodeName),node,arcsList)) {
// System.out.println("Arc=" + getArc(node,getNode(nodeName)));
arcsList.add(new Arc(node,getNode(nodeName)));
if (debug) System.out.println("arc from "+node.getName()+" to "+nodeName+" added");
} else {if (debug) System.out.println("arc from "+node.getName()+" to "+nodeName+" already exist");}
} else {
// If exist add it to the list if it's not already in it
if (!arcsList.contains(getArc(node,getNode(nodeName)))) {
arcsList.add(getArc(node,getNode(nodeName)));
if (debug) System.out.println("existing arc from "+node.getName()+" to "+nodeName+" added");
}
}
}
else {System.out.println("Error in node "+ node.getName() +" : successor " + nodeName + " does not exist in graph");}
}
if (debug) System.out.println();
}
/**
* Build all the arcs to this node / from the predecessors of this node
* @param node node to build arcs from
* @deprecated this method is useless because arcs lists can be build from the list of successors alone*/
private void buildArcsToNode(Node node, ArrayList<Arc> arcsList){
if (debug) System.out.println("Building arc to "+node.getName());
for (String nodeName: node.getPredecessors()) {
// If node exist
if (existNode(nodeName)) {
// If arc don't already exist
if (!existArc(getNode(nodeName),node)){
// If arc don't already in the arcList create it and add it to the list
if (!existArc(getNode(nodeName),node,arcsList)) {
arcsList.add(new Arc(getNode(nodeName),node));
if (debug) System.out.println("arc from "+node.getName()+" to "+nodeName+" added");
} else {if (debug) System.out.println("arc from "+node.getName()+" to "+nodeName+" already exist");}
}
// If exist add it to the list
else {
if (!arcsList.contains(getArc(getNode(nodeName),node))) {
arcsList.add(getArc(getNode(nodeName),node));
if (debug) System.out.println("existing arc to "+node.getName()+" from "+nodeName+" added");
}
}
}
else {if (debug) System.out.println("Error in node " + node.getName() +" : predecessor " + nodeName + " does not exist in graph");}
}
if (debug) System.out.println();
}
/**
* Build the list of arcs of the graph
* Needs to be executed after adding or removing nodes*/
public void buildArcs(){
ArrayList<Arc> arcsList = new ArrayList<>();
for (Node node: nodes) {
buildArcsFromNode(node,arcsList);
// buildArcsToNode(node,arcsList);
}
Collections.sort(arcsList);
this.arcs = arcsList;
}
//
// MISC
//
/**
* Enable or disable graph debug mode / verbose
* @param debug set to true to enable debug mode, false to disable it*/
public void setDebug(boolean debug) { this.debug = debug; }
//
// PRINTERS
//
/**
* Return the list of nodes
* @return A multiline string listing all the nodes*/
public String nodesToString(){
StringBuilder nodeString = new StringBuilder();
for (Node node: nodes) {
nodeString.append(node).append(System.lineSeparator());
}
return nodeString.toString();
}
/**
* Return the list of arcs
* @return A multiline string listing all the arcs*/
public String arcsToString(){
StringJoiner arcsString = new StringJoiner(",");
for (Arc arc: arcs) {
arcsString.add(arc.toString());
}
return "{"+arcsString.toString()+"}";
}
/**
* Convert the graph to a string
* @return a string representation of the graph*/
@Override
public String toString(){
return "Graph nodes:"
+ System.lineSeparator()
+ nodesToString()
+ System.lineSeparator()
+ "Graph arcs:"
+ System.lineSeparator()
+ arcsToString();
}
}