Why does this work when it looks like it's missing some return calls (DFS)? - depth-first-search

def dfs(s,d):
def dfs_helper(s,d):
if s==d:
return True
if s in visited:
return False
visited.add(s)
for c in graph[s]:
dfs_helper(c,d)
return False
visited = set()
return dfs_helper(s,d)
I'm not sure why the above code is correct. I saw this in a paper but shouldn't it say return dfs_helper(c,d) instead of just dfs_helper(c,d) when looping through all the neighbors? Otherwise, how do we return anything all the way up since I thought returns only take you one level up to the immediate caller.
I.e. if we have a graph with edges (A,B), (A,C), and (C,D), I get why the dfs_helper(D,D) returns True, but when we run dfs_helper(C,D), we just run dfs_helper(D,D) but we aren't RETURNING dfs_helper(D,D) so True does not get passed back up. Shouldn't that be the case? And if not, why is that so?

Fixed this. It turns out I was on the right track.
I needed to change from
for c in graph[s]:
dfs_helper(c,d)
to
for c in graph[s]:
if dfs_helper(c,d): return True

Related

Is there a good way to exit a DFS procedure?

I've learned that a recursive depth-first search procedure searches a whole tree by its depth, tracing through all possible choices.
However, I want to modify the function such that I can call a "total exit" in the middle, which will completely stop the recursion. Is there an efficient way to do this?
There are 3 ways to do this.
Return a value saying you are done, and check for it after every call.
Throw an exception and catch it at the top level.
Switch from recursion to a stack and then break the loop.
The third is the most efficient but takes the most work. The first is the clearest. The second is simple and works..but tends to make code more complicated and is inefficient in many languages.
A common DFS works like this:
DFS(u){
mark[u] = true
for each v connected to u:
if(!mark[v]) DFS(v)
}
You can try something like this:
static bool STOP = false;
DFS(u){
if(STOP) return;
mark[u] = true
for each v connected to u:
if(!mark[v]) DFS(v)
}
placing a static bool in the beginning of the DFS should guarantee that nothing important will be done from now on with the stacked recursive calls of the DFS once you set STOP to true. Unfortunately it won't just ignore the function calls stacked, but they will finish immediatly.
coroutines
Billy's accepted answer presents a false trichotomy. There are more than three (3) ways to do this. Coroutines are perfectly suited for this because they are pausable, resumable, and cancellable -
def dfs(t):
if not t:
return # <- stop
else:
yield from dfs(t.left) # <- delegate control to left branch
yield t.value # <- yield a value and pause
yield from dfs(t.right) # <- delegate control to right branch
The caller has control over coroutines execution -
def search(t, query):
for val in dfs(t):
if val == query:
return val # <- return stops dfs as soon as query is matched
return None # <- otherwise return None if dfs is exhausted
Languages that support coroutines typically have a handful of other generic functions that makes them useful in a wide variety of ways
persistent iterators
Another option similar to coroutines is streams, or persistent iterators. See this Q&A for a concrete example.

OR between two function call

What is the meaning of a || between two function call
like
{
//some code
return Find(n.left,req)||Find(n.right,req);
}
http://www.careercup.com/question?id=7560692
can some one help me to understand . Many thanks in advance.
It means that it returns true if one of the two functions is true (or both of them).
Depends on the programming language, the method calls Find(n.left,req) -> if it's true - returns true. if it's false, it calls Find(n.right,req) and returns its Boolean value.
In Java (and C and C#) || means "lazy or". The single stroke | also means "or", but operates slightly differently.
To calculate a||b, the computer calculates the truth value (true or false) of a, and if a is true it returns the value true without bothering to calculate b, hence the word "lazy". Only if a is false, will it checks b to see if it is true (and so if a or b is true).
To calculate a|b, the computer works out the value of a and b first, then "ors" the answers together.
The "lazy or" || is more efficient, because it sometimes does not need to calculate b at all. The only reason you might want to use a|b is if b is actually a function (method) call, and because of some side-effect of the method you want to be sure it executes exactly once. I personally consider this poor programming technique, and on the very few occasions that I want b to always be explicitly calculated I do this explicitly and then use a lazy or.
Eg consider a function or method foo() which returns a boolean. Instead of
boolean x = a|foo(something);
I would write
boolean c=foo(something);
boolean x = a||c;
Which explicitly calls foo() exactly once, so you know what is going on.
Much better programming practice, IMHO. Indeed the best practice would be to eliminate the side effect in foo() entirely, but sometimes that's hard to do.
If you are using lazy or || think about the order you evaluate it in. If a is easy to calculate and usually true, a||b will be more efficient than b||a, as most of the time a simple calculation for a is all that is needed. Conversely if b is usually false and is difficult to calculate, b||a will not be much more efficient than a|b. If one of a or b is a constant and the other a method call, you should have the constant as the first term a||foo() rather than foo()||a as a method call will always be slower than using a simple local variable.
Hope this helps.
Peter Webb
return Find(n.left,req)||Find(n.right,req);
means execute first find {Find(n.left,req)} and return true if it returns true or
execute second find return the value true if it return true, otherwise false.

Binary trees- pseudo codes?

I'm trying to write this pseudo code for checking whether a data-structure based on trees
is a binary tree.
I'm having a little problem with understanding this pseudo code form.
This is what I wrote:
Is-Binary(x)
if (x=null) {Then Return True
}
else {
if (x.Right<>Null) {Then
if (x.key<x.right.key){Then
Is-Binary(x.Right)}
else {Return False}}
if (x.Left<>Null) {Then
if (x.key>x.Left.key){Then
Is-binart(x.Left)}
else {Return False}}
}
My question: Can I assume that after the first true will be accepted, the program wont finish?
What does the return means here? will it sum up all the true/false and give the final soulotion (based on the fact that true*false=false?)
If so, what else can I do?
Thank you
You'll only get one result, either true or false, because you're not accumulating anything. Assuming you're starting from the top of a tree, say you only go one level deep, you'll only get true or false as a result. Then, if you get another level deeper (with another call), you're just facing the same possibilities: True, false, or deeper in the tree.
[Edit, after further observation:] Unless I'm mistaken, you'll get True the first time you hit a null, which might never happen because you never call Is-Binary on a null-value.
So if X is null you get true, else you get false.

Problem with Ruby recursive lambda call

I have the following code that correctly traverses all the nodes in a graph like so:
seen = {}
dfs = lambda do |node|
return if seen[node]
seen[node] = true
$edges[node].each {|n| dfs.call n}
end
dfs.call 0
However, I would like to write it this way, which I understand is correct:
$edges[node].each &dfs
However, when I do this it appears that dfs is only being called on the first element of the list of nodes in $edge[node]. What gives?
Surprisingly enough, your problem is not in the recursion! It actually is because of the shared seen collection among all calls in $nodes[node].each &dfs.
Let's go through the operation: the call to $nodes[node].first should not have any problems, because we know the snippet works for any one node. There is a problem however: seen is not reset, and you are already going to the next node! You already saw all the nodes, so when you try even one on the next cycle, it will immediately return out of the proc because of the condition. The same will happen for every other call as you loop through $nodes. It only seems that the calls to the rest of the nodes never happened!
To solve your problem, isolate seen to the scope of each call of dfs, which we can still do in functional programming:
dfs = lambda do |node|
seen = []
sub_dfs = lambda do |sub_node|
return if seen.include? sub_node
seen << sub_node
$edges[sub_node].each &sub_dfs
end
sub_dfs.call node
end
$edges[some_node].each &dfs
Now seen is safely isolated in each call to dfs.
Another way to make recursive lambdas:
fac = lambda{|n, &context| n.zero? ? 1 : n * eval("fac.call(#{n-1}) {}",context.binding)}
But have to be called with empty block though
fac.call(2){} = 2
fac.call(3){} = 6
fac.call(4){} = 24
binding is used to evaluate the code outside of lambda scope

Ruby Array find_first object?

Am I missing something in the Array documentation? I have an array which contains up to one object satisfying a certain criterion. I'd like to efficiently find that object. The best idea I have from the docs is this:
candidates = my_array.select { |e| e.satisfies_condition? }
found_it = candidates.first if !candidates.empty?
But I am unsatisfied for two reasons:
That select made me traverse the whole array, even though we could have bailed after the first hit.
I needed a line of code (with a condition) to flatten the candidates.
Both operations are wasteful with foreknowledge that there's 0 or 1 satisfying objects.
What I'd like is something like:
array.find_first(block)
which returns nil or the first object for which the block evaluates to true, ending the traversal at that object.
Must I write this myself? All those other great methods in Array make me think it's there and I'm just not seeing it.
Either I don't understand your question, or Enumerable#find is the thing you were looking for.
use array detect method if you wanted to return first value where block returns true
[1,2,3,11,34].detect(&:even?) #=> 2
OR
[1,2,3,11,34].detect{|i| i.even?} #=> 2
If you wanted to return all values where block returns true then use select
[1,2,3,11,34].select(&:even?) #=> [2, 34]
Guess you just missed the find method in the docs:
my_array.find {|e| e.satisfies_condition? }
Do you need the object itself or do you just need to know if there is an object that satisfies.
If the former then yes: use find:
found_object = my_array.find { |e| e.satisfies_condition? }
otherwise you can use any?
found_it = my_array.any? { |e| e.satisfies_condition? }
The latter will bail with "true" when it finds one that satisfies the condition.
The former will do the same, but return the object.

Resources