how to follow a recursive isBST function? - recursion

I'm trying to follow a specific implementation of a recursive (in-order traversal) isBST function.
I tried to simulate it with the simple invalid BST example:
root=5, root.left=3, root.left.right=8
5
/
3
\
8
i'm getting either 'true' or 'false' but without having to check the last node '8'.
the code is as follows:
/* wrapper that keeps track of the previous value */
class PrevWrapper {
int data = Integer.MIN_VALUE;
}
boolean isBST(Node root, PrevWrapper prev) {
/* base case: we reached null*/
if (root == null) {
return true;
}
if(!isBST(root.left, prev)) {
return false;
}
/* If previous in-order node's data is larger than
* current node's data, BST property is violated */
if (prev.data > root.data) {
return false;
}
/* set the previous in-order data to the current node's data*/
prev.data = root.data;
return isBST(root.right, prev);
}
boolean isBST(Node root) {
return isBST(root, new PrevWrapper());
}
what is the correct order of returning the recursive calls?
EDIT:
I was thinking:
(#)isBST(5,min), isBST(3,min), isBST(3.left=null,min) - returns true, skips to prev=3, isBST(8,3), isBST(8.left=null,3) - returns true, skips to prev=8, isBST(8.right=null,8) - returns true to (#), checks 8 > 5? returns false.
I think I got it, is this the correct order of calls?
thanks in advance.

Related

How can I get out of this infinite loop?

I am writing a recursive function to find the index of a node in a linked list. It looks like this:
function indexAt(node, collection, linkedList) {
let index = 0;
if (node === nodeAt(index, linkedList,collection)) {
return index
} else {
index ++
return indexAt(node, collection, linkedList)
}
}
It calls on the nodeAt function, which looks like this:
function nodeAt(index, linkedList, collection) {
let node = collection[linkedList];
for (let i=0; i < index; i++) {
node = next(node, collection)
}
return node
}
This works fine when the index is 0, but when it is anything else, it increments the index, then sets it back to 0, entering an infinite loop. How can I fix this without fundamentally altering the code?
Well at the start of the function you reset the index to 0. So every time it recurs, it resets the index, thus causing your infinite loop.
An easy fix is to declare the index variable outside the function. That will ensure it's not reset every time the function recurs.
A better fix would be to pass the index as an argument to the function so that it will always keep track of its own index.
Just make a helper that holds the extra variable:
function indexAt(node, collection, linkedList) {
function indexAt(index, node, collection, linkedList) {
if (node === nodeAt(index, linkedList, collection)) {
return index
} else {
return indexAt(index + 1, node, collection, linkedList)
}
}
return indexAt(0, node, collection, linkedList);
}
Now you count from 0...n and make nodeAt start at the beginning each time making this O(n^2). A much better way would be that the helper has the current node, initialized at collection[linkedList] and stepping with next(currentNode) and index + 1 until node === currentNode. That would be a O(n) solution. indexAt doesn't really need to be recursive unless it is a requirement.

Stream handling in kotlin

How will Kotlin work the following code?
Will a collection of 5000000 integers be created as temporary collection or will the filter feed its result immediately to the forEach which means, that only 20 integers will be looked at?
If not, how would I be able to avoid the intermediate collection?
Code:
class Tests {
#Test
fun test() {
var counter = 0
(1..10_000_000).filter { it % 2 == 1 }.forEach {
counter++
if (counter > 10)
return
}
}
}
Your code sample uses operations on Iterable<T>, which works eagerly: the .filter { ... } call will process the whole range and produce a list storing intermediate results.
To alter that, consider using Sequence<T> (e.g. with .asSequence()) that works lazily, so that the intermediate operations such as .filter { ... } produce another lazy sequence and only do the work when items are queried by terminal operations such as .forEach { ... }:
(1..10000000).asSequence()
.filter { it % 2 == 1 }
.forEach { /* ... */ }
See: Kotlin's Iterable and Sequence look exactly same. Why are two types required?
You can actually see the answer to your question pretty quickly by just adding println(it) into filter:
//...
.filter {
println(it)
it % 2 == 1
}
//...
You'll see every number printed. That's because your processing works eagerly as explained here.
As already suggested, lazy Sequences to the rescue: (1..10_000_000).asSequence()
Now, the println(it) in filter will only print the numbers 1..21, which is definetly preferable in your example.

Recursive Function into Non-Recursive Function?

I have the following recursive Grails function:
private boolean isCyclic(TreeNode node) {
boolean cyclic = false
def myParents = this.parents
// if there are parents of this node
if (myParents.size() != 0) {
// if the new node is in the parents set of this node
if (myParents.contains(node)) {
cyclic = true
return cyclic
}
else {
// go into each parent of this node and test if new node is contained in their parents
myParents.each { parent ->
log.debug "go to parent: "+parent.name
if (cyclic) {
return cyclic
}
cyclic = parent.isCyclic(node)
}
}
}
return cyclic
}
How can I transform this function into a non-recursive function?
I think your code above is a contains method, rather than a cyclic check...
However here's a quick example of both a contains method and a cyclic check in an iterative style... Fingers crossed they're right
def contains( TreeNode node ) {
// if this node is the one we're looking for, return true
if( node == this ) {
return true
}
// A queue of nodes to work on
def parentQueue = this.parents as Queue
// A set of nodes we've seen (to avoid loops)
def seen = [ this ] as Set
// While we have nodes to look for
while( parentQueue ) {
// get the next node
def next = parentQueue.pop()
// Check if it's the one we're looking for
if( next == node ) return true
// And if not, add it's parents to the queue
// assuming we've not seen it before
if( !seen.contains( next ) ) {
next.parents.each { parentQueue.offer( it ) }
}
}
// Not found
return false
}
def isCyclic() {
// A queue of nodes to work on
def parentQueue = this.parents as Queue
// A set of nodes we've seen (to detect loops)
def seen = [ this ] as Set
// While we have nodes to look for
while( parentQueue ) {
// Look at the next element in the queue
def next = parentQueue.pop()
// If we've seen it before, it's cyclic
if( seen.contains( next ) ) return true
// Otherwise, record we've seen this node
seen << next
// And add its parents tothe queue
next.parents.each { parentQueue.offer( it ) }
}
// All done, not cyclic
return false
}
Tom Moertel wrote solution for this problem on his blog.
He clearly explained the transformation of recursive function into the iterative (link).
I have used his approach to transform my own functions when I needed and I was convinced that is correct.
I hope that helps.
Basically to transform a recursive function into an iterative function you should notice which is the case base(this case is the stop case of recursive function), put all functionality into a loop and use that base case as exit condition of used loop.
Perhaps i didn't explain it very well but every recursive function has an iterative function.

Programming recursive functions in alloy

I am trying to construct a recursive function in Alloy. According to the grammar displayed on Daniel Jackson's book, this is possible. My function is:
fun auxiliaryToAvoidCyclicRecursion[idTarget:MethodId, m:Method]: Method{
(m.b.id = idTarget) => {
m
} else (m.b.id != idTarget) => {
(m.b = LiteralValue) => {
m
} else {
some mRet:Method, c:Class | mRet in c.methods && m.b.id = mRet.id => auxiliaryToAvoidCyclicRecursion[idTarget, mRet]
}
}
}
But the solver claims about the call auxiliaryToAvoidCyclicRecursion[idTarget, mRet] saying that:
"This must be a formula expression.
Instead, it has the following possible type(s):
{this/Method}"
The problem is exactly what the error message says: the return type of your auxiliaryToAvoidCyclicRecursion function is Method, which you are trying to use in a boolean implication, where formula is expected (i.e., something of type Boolean). You'd get the same kind of error in any other statically typed language.
You could rewrite your function as a predicate to work around this problem:
pred auxiliaryToAvoidCyclicRecursion[idTarget:MethodId, m:Method, ans: Method] {
(m.b.id = idTarget) => {
ans = m
} else (m.b.id != idTarget) => {
(m.b = LiteralValue) => {
ans = m
} else {
some mRet:Method, c:Class {
(mRet in c.methods && m.b.id = mRet.id) =>
auxiliaryToAvoidCyclicRecursion[idTarget, mRet, ans]
}
}
}
}
This should not give you a compilation error, but to run it make sure you enable recursion (Options -> Recursion Depth). As you will see, the maximum recursion depth is 3, meaning that the Alloy Analyzer can unroll your recursive calls up to 3 times, regardless of the scope of your analysis. When that is not enough, you still have the option to rewrite your model such that the recursive predicate in question is modeled as a relation. Here is a simple example to illustrate that.
Linked list with a recursively defined function for computing the list length:
sig Node {
next: lone Node
} {
this !in this.^#next
}
fun len[n: Node]: Int {
(no n.next) => 1 else plus[1, len[n.next]]
}
// instance found when recursion depth is set to 3
run { some n: Node | len[n] > 3 } for 5 but 4 Int
// can't find an instance because of too few recursion unrollings (3),
// despite the scope being big enough
run { some n: Node | len[n] > 4 } for 5 but 4 Int
Now the same list where len is modeled as a relation (i.e., a field in Node)
sig Node {
next: lone Node,
len: one Int
} {
this !in this.^#next
(no this.#next) => this.#len = 1 else this.#len = plus[next.#len, 1]
}
// instance found
run { some n: Node | n.len > 4 } for 5 but 4 Int
Note that the latter approach, which doesn't use recursion (and therefore does not depend on the value of the "recursion depth" configuration option), can be (and typically is) significantly slower than the former.

Backtracking recursively with multiple solutions

function BACKTRACKING-SEARCH(csp) returns a solution, or failure
return RECURSIVE- BACKTRACKING({ }, csp)
function RECURSIVE-BACKTRACKING(assignment,csp) returns a solution, or failure
if assignment is complete then
return assignment
var ←SELECT-UNASSIGNED-VARIABLE(VARIABLES[csp],assignment,csp)
for each value in ORDER-DOMAIN-VALUES(var,assignment,csp) do
if value is consistent with assignment according to CONSTRAINTS[csp] then
add {var = value} to assignment
result ← RECURSIVE-BACKTRACKING(assignment, csp)
if result ̸= failure then
return result
remove {var = value} from assignment
return failure
This is a backtracking recursion algorythm pseudocode from AIMA. However, I don't understand if it returns ALL possible solutions or just first one found. In case it is the last option, could you please help me modify it to return a list of possible solutions instead (or at least updating some global list).
EDIT: I implemented this algorithm in Java. However, there is one problem:
if I don't return assignment, but save it in result instead, the recursion stop condition fails (i.e. it doesn't exist anymore). How can I implement another stop-condition? Maybe I should return true in the end?
Here is my code :
/**
* The actual backtracking. Unfortunately, I don't have time to implement LCV or MCV,
* therefore it will be just ordinary variable-by-variable search.
* #param line
* #param onePossibleSituation
* #param result
*/
public static boolean recursiveBacktrack(Line line, ArrayList<Integer> onePossibleSituation, ArrayList<ArrayList<Integer>> result){
if (onePossibleSituation.size() == line.getNumOfVars()){
// instead of return(assignment)
ArrayList<Integer> situationCopy = new ArrayList<Integer>();
situationCopy.addAll(onePossibleSituation);
result.add(situationCopy);
onePossibleSituation.clear();
}
Block variableToAssign = null;
// iterate through all variables and choose one unassigned
for(int i = 0; i < line.getNumOfVars(); i++){
if(!line.getCspMiniTaskVariables().get(i).isAssigned()){
variableToAssign = line.getCspMiniTaskVariables().get(i);
break;
}
}
// for each domain value for given block
for (int i = line.getCspMiniTaskDomains().get(variableToAssign.getID())[0];
i <= line.getCspMiniTaskDomains().get(variableToAssign.getID())[0]; i++){
if(!areThereConflicts(line, onePossibleSituation)){
//complete the assignment
variableToAssign.setStartPositionTemporary(i);
variableToAssign.setAssigned(true);
onePossibleSituation.add(i);
//do backtracking
boolean isPossibleToPlaceIt = recursiveBacktrack(line,onePossibleSituation,result);
if(!isPossibleToPlaceIt){
return(false);
}
}
// unassign
variableToAssign.setStartPositionTemporary(-1);
variableToAssign.setAssigned(false);
onePossibleSituation.remove(i);
}
// end of backtracking
return(false);
}
This code checks if solution found and if it is, returns the solution. Otherwise, continue backtracking. That means, it returns the first solution found.
if result ̸= failure then
return result
remove {var = value} from assignment
You can modify it like that:
if result ̸= failure then
PRINT result // do not return, just save the result
remove {var = value} from assignment
Or, better, modify this part:
if assignment is complete then
print assignment
return assignment // print it and return
About edited question:
First, return true in the first if, so recursion will know that it found a solution. The second step, there is a mistake, probably:
if(!isPossibleToPlaceIt){
return(false);
}
Should be
if(isPossibleToPlaceIt){
return(true);
}
Because if your backtracking has found something, it returns true, which means you don't have to check anything else any longer.
EDIT#2: If you want to continue backtracking to find ALL solutions, just remove the whole previous if section with return:
//if(isPossibleToPlaceIt){
// return(true);
//}
So we will continue the search in any way.

Resources