-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Traversal from terminal by depth or breadth first #335
base: main
Are you sure you want to change the base?
Conversation
Signed-off-by: Franck LECUYER <[email protected]>
…or messages Signed-off-by: BOUTIER Charly <[email protected]>
Signed-off-by: BOUTIER Charly <[email protected]>
Signed-off-by: BOUTIER Charly <[email protected]>
Signed-off-by: BOUTIER Charly <[email protected]>
Signed-off-by: BOUTIER Charly <[email protected]>
Signed-off-by: BOUTIER Charly <[email protected]>
Adds equipment information on problematic VSC and Busbar index
4fcdf56
to
32e5119
Compare
Signed-off-by: FranckLecuyer <[email protected]>
result = traverser.traverse(node, null, nextNode); | ||
} else { | ||
throw new AssertionError(); | ||
if (traversalType == TraversalType.DEPTH_FIRST) { // traversal by depth first |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Separate DFS and BFS in two differents methods, otherwise it's a bit difficult to differentiate the recursive DFS with the BFS
} | ||
} else { // traversal by breadth first | ||
boolean keepGoing = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should be able to get rid of the boolean keepGoing, see proposed changes. Instead of encounteredEdges, we could keep track of visitedNodes similarly to the "done" set in the DFS implementation. See suggestion
LinkedList<Integer> vertexToTraverse = new LinkedList<>(); | ||
vertexToTraverse.offer(node); | ||
while (!vertexToTraverse.isEmpty()) { | ||
int firstV = vertexToTraverse.getFirst(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rename to currentNode?
vertexToTraverse.offer(node); | ||
while (!vertexToTraverse.isEmpty()) { | ||
int firstV = vertexToTraverse.getFirst(); | ||
vertexToTraverse.poll(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can be one line int firstV = vertexToTraverse.poll(); ?
if (done.contains(firstV)) { | ||
continue; | ||
} | ||
done.add(firstV); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need done here as we have the encounteredEdges Set. we need to choose one or the other
NodeBreakerBiConnectable biConnectable = edge.getBiConnectable(); | ||
int node1 = biConnectable.getNode1(); | ||
int node2 = biConnectable.getNode2(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we can also use int nextNode similarly to the DFS to avoid the following if clause duplicated
break; | ||
} | ||
} | ||
return keepGoing; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something like this seems to work for me on tests but I haven't tested on a real network only on the tests implemented.
boolean traverseFromNode(int node, TraversalType traversalType, VoltageLevel.NodeBreakerView.TopologyTraverser traverser) {
Graph<Integer, Edge> graph = NodeBreakerTopology.INSTANCE.buildGraph(index, getVoltageLevelResource(), true, true);
if (traversalType == TraversalType.DEPTH_FIRST) {
Set<Integer> visitedNodes = new HashSet<>();
return traverseFromNodeDFS(graph, node, traverser, visitedNodes);
} else {
return traverseFromNodeBFS(graph, node, traverser);
}
}
private boolean traverseFromNodeBFS(Graph<Integer, Edge> graph, int node, TopologyTraverser traverser) {
Set<Integer> visitedNodes = new HashSet<>();
LinkedList<Integer> nodeQueue = new LinkedList<>();
nodeQueue.offer(node);
while (!nodeQueue.isEmpty()) {
int currentNode = nodeQueue.poll();
for (Edge edge : graph.edgesOf(currentNode)) {
NodeBreakerBiConnectable biConnectable = edge.getBiConnectable();
int nextNode = biConnectable.getNode1() == currentNode ? biConnectable.getNode2() : biConnectable.getNode1();
if (visitedNodes.contains(nextNode)) {
continue;
}
visitedNodes.add(nextNode);
TraverseResult traverserResult;
if (biConnectable instanceof SwitchAttributes) {
traverserResult = traverseSwitch(traverser, biConnectable, currentNode, nextNode);
} else if (biConnectable instanceof InternalConnectionAttributes) {
traverserResult = traverser.traverse(currentNode, null, nextNode);
} else {
throw new AssertionError();
}
if (traverserResult == TraverseResult.CONTINUE) {
nodeQueue.offer(nextNode);
} else if (traverserResult == TraverseResult.TERMINATE_TRAVERSER) {
return false;
}
}
}
return true;
}
private boolean traverseFromNodeDFS(Graph<Integer, Edge> graph, int node,
TopologyTraverser traverser, Set<Integer> visitedNodes) {
if (visitedNodes.contains(node)) {
return true;
}
visitedNodes.add(node);
for (Edge edge : graph.edgesOf(node)) {
NodeBreakerBiConnectable biConnectable = edge.getBiConnectable();
int nextNode = biConnectable.getNode1() == node ? biConnectable.getNode2() : biConnectable.getNode1();
TraverseResult result;
if (visitedNodes.contains(nextNode)) {
continue;
}
if (biConnectable instanceof SwitchAttributes) {
result = traverseSwitch(traverser, biConnectable, node, nextNode);
} else if (biConnectable instanceof InternalConnectionAttributes) {
result = traverser.traverse(node, null, nextNode);
} else {
throw new AssertionError();
}
if (result == TraverseResult.CONTINUE) {
if (!traverseFromNodeDFS(graph, nextNode, traverser, visitedNodes)) {
return false;
}
} else if (result == TraverseResult.TERMINATE_TRAVERSER) {
return false;
}
}
return true;
}
Please check if the PR fulfills these requirements
Does this PR already have an issue describing the problem?
What kind of change does this PR introduce?
Feature
What is the current behavior?
The traversal from a terminal is only done by depth first
What is the new behavior (if this is a feature change)?
The traversal from a terminal can now be done by depth or breadth first
Does this PR introduce a breaking change or deprecate an API?
Other information:
Waiting for PR : powsybl/powsybl-core#2626
Waiting for next powsybl-core release