How to get the path between 2 nodes using Breadth-First Search? - search

I am trying to find a path between two nodes in a graph, where the edges are unweighted.
I am using a Breadth First Search, which stops when it finds the target, in order to find the existence of a path, but I am not sure how to get the path itself.
I tried looking at the list of visited nodes, but this did not seem to help.
I saw someone answer this question using prolog, but I am a C++ programmer.
I also looked at Dijkstras algorithm, but this seems like over kill, since a simple Breadth-first Search has got me almost the whole way.
How to get the path between 2 nodes using Breadth-First Search?

In your node struct, you add a variable called parentNode which is the parent of that node in the path. In the end, you can retrieve the path by traversing from the goal node backward.

I found this simple algorithm which stores the path to the node along with the node in the queue here: https://stackoverflow.com/a/50575971/5883177
So when we pop a node from the queue, we also get the path to that node readily.
The code in the link is in python which uses tuples to store the pair. Here is a C++ implementation of the same which uses std::pair.
bool findPath(Node *n1, Node *n2, vector<Node*> &path)
{
// We use queue to perform a BFS traversal and in addition to storing the
// node we'll also store the path so far to the node.
queue<pair<Node*,vector<Node*>>> q;
// Visit the first node and add it to the queue.
n1->visited=1;
// Form the path, create a pair and add it the queue.
vector<Node*> p;
p.push_back(n1);
q.push(make_pair(n1,p));
while(!q.empty())
{
pair<Node*,vector<Node*>> curPair = q.front();
q.pop();
// visit all the unvisited nodes and check if there is n2 in it.
for(Node *u : curPair.first->adjNodes ){
if(u->visited == 0){
if(u->value == n2->value){
// found our destination. Return true
// form the path by appending this node to the path till now
curPair.second.push_back(u);
// update the passed 'path' vector with the path so far.
path = curPair.second; // all nodes will be copied into path
return true;
}
// Not our node, visit the node if unvisited
if(u->visited == 0){
u->visited = 1;
// Create a new path with this node added.
// Path so far can be obtained from the pair in queue
vector<Node*> newPath(curPair.second);
newPath.push_back(u);
// Add the node and the path to it into the queue.
q.push(make_pair(u, newPath));
}
}
}
}
return false;
}
class Node{
public:
Node(int val)
{
value = val;
visited=0;
}
int value;
vector<Node*> adjNodes;
int visited;
};

Related

Should the variable value be checked before assigning?

I know this might sound like a silly question but I'm curious should I check my variable value before assigning?
like for example if I'm flipping my skin (Node2D composed of sprite & raycast) based on direction (Vector2) :
func _process(delta):
...
if(direction.x>0):
skin.scale.x=1
elif(direction.x<0):
skin.scale.x=-1
#OR
if(direction.x>0):
if(skin.scale.x!=1):
skin.scale.x=1
elif(direction.x<0):
if(skin.scale.x!=-1):
skin.scale.x=-1
would the skin scale be altered every _process hence consuming more CPU usage
OR
if the value is same will it be ignored?
First of all, given that this is GDScript, so the number of lines will be a performance factor.
We will look at the C++ side…
But before that… Be aware that GDScript does some trickery with properties.
When you say skin.scale Godot will call get_scale on the skin object, which returns a Vector2. And Vector2 is a value type. That Vector2 is not the scale that the object has, but a copy, an snapshot of the value. So, in virtually any other language skin.scale.x=1 is modifying the Vector2 and would have no effect on the scale of the object. Meaning that you should do this:
skin.scale = Vector2(skin.scale.x + 1, skin.scale.y)
Or this:
var skin_scale = skin.scale
skin_scale.x += 1
skin.scale = skin_scale
Which I bet people using C# would find familiar.
But you don't need to do that in GDScript. Godot will call set_scale, which is what most people expect. It is a feature!
So, you set scale, and Godot will call set_scale:
void Node2D::set_scale(const Size2 &p_scale) {
if (_xform_dirty) {
((Node2D *)this)->_update_xform_values();
}
_scale = p_scale;
// Avoid having 0 scale values, can lead to errors in physics and rendering.
if (Math::is_zero_approx(_scale.x)) {
_scale.x = CMP_EPSILON;
}
if (Math::is_zero_approx(_scale.y)) {
_scale.y = CMP_EPSILON;
}
_update_transform();
_change_notify("scale");
}
The method _change_notify only does something in the editor. It is the Godot 3.x instrumentation for undo/redo et.al.
And set_scale will call _update_transform:
void Node2D::_update_transform() {
_mat.set_rotation_and_scale(angle, _scale);
_mat.elements[2] = pos;
VisualServer::get_singleton()->canvas_item_set_transform(get_canvas_item(), _mat);
if (!is_inside_tree()) {
return;
}
_notify_transform();
}
Which, as you can see, will update the Transform2D of the Node2D (_mat). Then it is off to the VisualServer.
And then to _notify_transform. Which is what propagates the change in the scene tree. It is also what calls notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED) if you have enabled it with set_notify_transform. It looks like this (this is from "canvas_item.h"):
_FORCE_INLINE_ void _notify_transform() {
if (!is_inside_tree()) {
return;
}
_notify_transform(this);
if (!block_transform_notify && notify_local_transform) {
notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED);
}
}
And you can see it delegates to another _notify_transform that looks like this (this is from "canvas_item.cpp"):
void CanvasItem::_notify_transform(CanvasItem *p_node) {
/* This check exists to avoid re-propagating the transform
* notification down the tree on dirty nodes. It provides
* optimization by avoiding redundancy (nodes are dirty, will get the
* notification anyway).
*/
if (/*p_node->xform_change.in_list() &&*/ p_node->global_invalid) {
return; //nothing to do
}
p_node->global_invalid = true;
if (p_node->notify_transform && !p_node->xform_change.in_list()) {
if (!p_node->block_transform_notify) {
if (p_node->is_inside_tree()) {
get_tree()->xform_change_list.add(&p_node->xform_change);
}
}
}
for (CanvasItem *ci : p_node->children_items) {
if (ci->top_level) {
continue;
}
_notify_transform(ci);
}
}
So, no. There is no check to ignore the change if the value is the same.
However, it is worth noting that Godot invalidates the global transform instead of computing it right away (global_invalid). This is does not make multiple updates to the transform in the same frame free, but it makes them cheaper than otherwise.
I also remind you that looking at the source code is no replacement for using a profiler.
Should you check? Perhaps… If there are many children that need to be updated the extra lines are likely cheap enough. If in doubt: measure with a profiler.

Modify object from multiple async streams in Dart

Imagine we had a object like this
class Foo {
List<int> data = [];
void addAndCheck(int n){
for(int number in data){
// check something
}
data.add(n);
}
}
and the imagine we spawn a bunch of subscriptions like this
Foo foo = Foo();
for(int i = 0; i++; i<10){
subscriptions.add(api.someRandomStream().listen((response){
foo.addAndCheck(response.value);
}));
}
As it stands, if this code is run it might work but as soon as the streams start emitting around the same time we get a exception: Concurrent modification during iteration
The cause is the for loop, but how can this problem be solved? In a language like Java there are things like ConcurrentHashMap, Collections.synchronizedList(...), etc..
If you get a concurrent modification error during the iteration, then you are doing something asynchronous inside the loop. That is, your function is probably async and there is at least one await inside the loop. That will allow another event to trigger while you are awaiting, and then modify the list.
There are several ways to avoid the exception, all with different trade-offs:
Don't do anything asynchronous in the loop, and make sure that nothing you do in there will call addAndCheck again. Then there should be no problem because the loop will complete before anyone else has a chance to modify the list. That obviously only works if you don't need to do something asynchronous.
Copy the list. If you do for(int number in [...data]) { ... } (or in data.toList() as it used to be written), then the list that you iterate is a different list than the one which is modified. It also means that you might not have checked all the elements that are actually in the list at the point you reach the add call.
Don't use an iterator. If you do for (int i = 0; i < data.length; i++) { var number = data[i]; ... } instead, you will not get a concurrent modification error from the iterator. If elements are added at the end of the list, then you will eventually reach them, and all is well. If elements are removed from the list, or added in any place other than at the end, then you might be skipping elements or seeing some of them twice, which may be bad for you.
Use a mutex. If you want to be sure that all the tests on existing elements are performed before any other element is added, then you need to prevent anything from happening while you are adding. Assume a Mutex class of some sort, which would allow you to write code like:
class Foo {
List<int> data = [];
final _mutex = Mutex();
void addAndCheck(int n) async {
await _mutex.acquire();
for(int number in data){
// check something
}
data.add(n);
_mutex.release();
}
}
(I found package:mutex by searching, I have no experience with it).
This might slow down your code, though, making every operation wait for the previous one to complete entirely.
In the end, only you can say which trade-off is best for the behavior of your code.

ANTLR4: getFirstChildWithType with a ParseTree

I've been playing around with ANTLR4, trying to convert an ANTLR3 project.
I have generated a lexer, a parser and a visitor class from an ANLTR4 grammar coming from the official repository. In the visitor, I am calling one of my classes using the ctx available from the visitor:
myFunction(ctx.getChild(0))
Then, in myFunction, I want to retrieve the first child having a specific type, so I tried doing:
final ParseTree classNameElement =
(ParseTree) ((GrammarAST) node).getFirstChildWithType(MyParser.IDENTIFIER);
where node is the argument of myFunction, thus a ParseTree. getFirstChildWithType seems to be available only in GrammarAST, hence the cast.
I am getting the error: cannot be cast to org.antlr.v4.tool.ast.GrammarAST
So maybe this is not possible as is and I must have missed something, but I want to find the first child having a specific type from a ParseTree.
Thank you!
Notice that GrammarAST is in the ANTLR tool hierarchy. With a generated parse-tree, you should be dealing exclusively with the runtime.
To search a parse-tree node for a child of a given type:
public ParseTree getFirstChildOfType(ParseTree node, int tokentype) {
for (int idx = 0; idx < node.getChildCount(); idx++) {
ParseTree child = node.getChild(idx);
if (child instanceof TerminalNode) {
Token token = (Token) child.getPayload();
if (token.getType() == tokentype) {
return child;
}
}
}
return null;
}
This will get the first direct, i.e., child terminal, of the given type. Will need to recurse into non-TerminalNodes if the absolute first of type is desired.
If the latter is actually the desired function, there may be a better/more direct use of parse-tree walker to obtain the desired overall goal.

Nodejs difference between two paths

I am trying to get the difference between two path. I've come with a solution, but I am not really happy about it, even if it works. Is there a better / easier way to do this?
var firstPath = '/my/first/path'
, secondPath = '/my/first/path/but/longer'
// what I want to get is: '/but/longer'
// my code:
var firstPathDeconstruct = firstPath.split(path.sep)
, secondPathDeconstruct = secondPath.split(path.sep)
, diff = []
secondPathDeconstruct.forEach(function(chunk) {
if (firstPathDeconstruct.indexOf(chunk) < 0) {
diff.push(chunk)
}
})
console.log(diff)
// output ['but', 'longer']
Node provides a standard function, path.relative, which does exactly this and also handles all of the various relative path edge cases that you might encounter:
From the online docs:
path.relative(from, to)
Solve the relative path from from to to.
Examples:
path.relative('C:\\orandea\\test\\aaa', 'C:\\orandea\\impl\\bbb')
// returns
'..\\..\\impl\\bbb'
path.relative('/data/orandea/test/aaa', '/data/orandea/impl/bbb')
// returns
'../../impl/bbb'

XMLSlurper appendNode does not see changes

I am having troubles using XMLSlurper to update an XML document. Most things work, but in some situations a "find" doesn't find a Node I just appended (appendNode). The new Node is there at the end of processing, but is not found when I am in the middle of adding children.
I found a post about XMLSlurper that says that finding the new Node requires calling parseText again and/or StreaMarkupBuilder (see below). Really?! That seems so kludgy that I thought I'd verify on SO.
Here is a code snippet. The "find" gets NoChildren even though the Node was just added.
codeNode.appendNode {
'lab:vendorData'() {}
}
vendorNode = codeNode.children().find { it.name() == "vendorData" }
"appendNode doea not modify the slurped document directly. The edit is applied "on the fly" when the document is written out using StreamingMarkupBuilder."
http://markmail.org/message/5nmxbhwna7hr5zcq#query:related%3A5nmxbhwna7hr5zcq+page:1+mid:bkdesettsnfnieno+state:results
Why can't I find my new Node?!
This is what I got to work. Is not elegant, but got past "update" problem:
...
codeNode.appendNode {
'lab:vendorData'() {}
}
//-- must re-slurp to see appended node
labDoc = new XmlSlurper().parseText(serializeXml(labDoc))
codeNode = getResultNodeFor( nextResult.getCode() );
vendorNode = codeNode.children().find { it.name() == "vendorData" }
...
def String serializeXml(GPathResult xml){
XmlUtil.serialize(new StreamingMarkupBuilder().bind {
mkp.declareNamespace("lab", "www.myco.com/LabDocument")
mkp.yield labDoc
} )
}

Resources