so I have a few questions on recursions. I am in a class and I am reviewing my notes and text and getting a little confused:
1) Am I getting this correct? Iterators and recursion seem so similar.
Recursion = a function that refers to itself and has a base case to get to the end of the problem.
Iterator: Using ++ or -- to go through all the data to get a piece of information.
2) What is recursive descent ? Is it getting closer to the base case? Then what is recursive ascent?
3) We are given this sample of recursion and it is confusing me:
Product of Positive Integer from 1 to n
Denoted by n! => n! = 1.2.3....(n-2).(n-1).n
0! = 1 , 5! = 1.2.3.4.5 = 120, 6! = 5! . 6 = 720
n! = n . ( n – 1 )!
Definition
– If n = 0 then n! = 1
– If n > 0, then n! = n. (n-1) !
Why is there an exclamation point after (n-1)? What are these dots, like n.(n-1)?
Recursion and iteration are not the same. You can iterate without recursion, and recursion means no iteration.
Let's leave recursive descent for now. That has to do with parsers.
The example is the mathematical operation of taking a factorial. The exclamation point means "factorial". The dot means multiplication.
Remember?
0! = 1
1! = 1
2! = 2*1
3! = 3*2*1 = 3*2!
4! = 4*3*2*1 = 4*3!
and so on.
This is a classic problem to illustrate recursion to undergrads seeing it for the first time:
function factorial_recursion(n) {
if (n <= 1) {
return 1;
} else {
return n*factorial(n-1);
}
}
You can write the same thing without recursion by iterating:
function factorial_iter(n) {
var value = 1;
if (n > 1) {
for (i = 1; i <= n; ++i) {
value *= i;
}
}
return value;
}
Well the dots are multiplication. It is confusing to use dots, but we know 5! = 1*2*3*4*5 so the dots must be multiplication. Also, the ! is the symbol to denote factorial. 5! = 5 * 4!
Yes, iteration and recursion are somehow similar, and it is known that any recursive solution has an equivalent iterative solution and vice versa. However, many problems are much simpler to solve in one of these approaches rather than in the other. The factorial example is easily solvable in both approaches.
Whenever you see how a problem can be reduced to one or more occurrences of the same problem on smaller magnitudes, you can easily proceed with a recursive solution.
I suppose that recursive descent is diving into deeper levels of the recursion, while ascent is the opposite: returning from a call and getting closer to the top level call.
The dots stand for multiplication.
Related
I hate that ranges include the end. Here is an example where I've deliberately removed the end of the range.
N = 100
for x in 0.0 : 2*pi/N : 2*pi*(N-1)/N
println(x)
end
Is there any way to avoid the ugliness of this for loop?
Yes, there is
N = 100
for x in range(0; step=2π/N, length=N)
println(x)
end
Maybe not the most elegant way... take the first n-1 elements
r = 0.0 : 2*pi/N : 2*pi
r = Iterators.take(r,length(r)-1)
Unfortunately, inclusive ranges (and 1-based indexing) is baked into the idioms of Julia at a fundamental level.
However, for this specific case, do note that stepping with floating point values can be problematic, as adding N values might be less than, equal to, or greater than the final value, giving different results for the for loop. Although julia tries really hard, there's no way to quite do the right thing in all circumstances. As a bonus, working in integer values only for the ranges simplifies things. You might want to consider:
for ix in 0:N-1
x = ix * 2 * pi / N
println(x)
end
Alternatively, the range() function has a form with a len parameter:
for x in range(0, 2*pi*(N-1)/N, length=n)
println(x)
end
Or indeed, combining this with the other answer of only taking (N-1) could work.
You could actually define your own operator such as:
▷(a,b) = a:b-1
Now you can write:
julia> 3▷6
3:5
Julia also natively supports custom indices for arrays. There is a package CustomUnitRanges that is maybe an overkill here.
I have some code written in OCaml
let rec sumodds n =
if (n mod 2)<>0 then
let sum = sumodds (n-1) in
n + sum
else sumodds(n-1);;
and I am trying to add up all odd numbers from 0 to n, but I am not sure how to make the program stop once n reaches zero. If I could get some help that would be awesome. If there are any other mistakes in the program, feel free to let me know what they are.
The way to get the function to stop is to test for the "stop condition". I.e., you need to add an if statement that tests whether you have reached such a low value for n that the result is obvious.
Very commonly a recursive function looks like this:
let rec myfun arg =
if is_trivial_value arg then
obvious_answer
else
let s = myfun (smallish_part_of arg) in
combine arg s
You just need to add a test for the trivial value of your argument n.
Update
As #Goswin_von_Brederlow points out, another very common pattern for recursive functions is this:
let rec myfun2 accum arg =
if is_trivial_vaue arg then
accum
else
myfun2 (combine arg accum) (smallish_part_of arg)
This is the tail recursive transformation of the above form. You can code in either form, but they are different. So you need to keep them straight in your mind. As an FP programmer you need to (and will pretty easily) learn to translate between the two forms.
just add "if n <= 0 then n" in the 2nd line
I'm currently working on a side project that deals with a lot of recursive calls. I'm not a computer scientist, so I'm not exactly sure how to optimize my code. I know that recursive functions are not very efficient and I've heard that you can often replace it with tail calls, but I'm not exactly sure how to go about doing this. This function takes in three arrays: appendList, sequence, and used. The other arguments, base, length, index and last word are integers.
function Recursion(appendList, base, length, sequence, used, lastWord, index)
#Global variables:
global G_Seq_List
global G_Seq_Index
used = ones(UInt8, 1, base^length)
used[1] = 0
if index == base^length
check = zeros(UInt8, base^length, 1)
for i = 1 : base^length
index = 1
for j = 1 : length
k = mod(i+j-1,base^length)
index = index + base^(length - j)*sequence[k+1]
end
check[index] = check[index] + 1
if check[index] != 1
return
end
end
G_Seq_List[G_Seq_Index,:] = sequence[:]
G_Seq_Index = G_Seq_Index + 1
return
end
#Builds Sequence
for i = 1 : base^length
if appendList[i , mod(lastWord - 1, base^(length - 1)) + 1] == 1
if used[i] == 1
tempUsed = used
tempUsed[i] = 0
tempCounter = index + 1
tempSequence = sequence
tempSequence[tempCounter] = mod(i - 1, base)
Recursion(appendList, base, length, tempSequence, tempUsed, i, tempCounter)
end
end
end
end
Is it a quick fix to turn this recursion into a tail call? If not, what kind of things can I do to optimize this function?
In general, any recursion can be converted to a loop, and a loop will generally have better performance, since it has similar algorithmic performance without the need to allocate new frames and store extra information.
"Tail call optimization" is something the compilers (or runtimes) do, which is to automatically convert the recursion to a loop if the recursive call is a last call in the function (hence the name - "tail call"), typically by reusing the same call frame instead of allocating a new one. Reusing the frame is okay since if all you do with the result of the recursive call is return it, you don't need anything else from the enclosing function invocation, so there's no reason to keep the frame alive in the first place.
So, what you need to check is:
Whether your compiler supports tail-call optimization.
What you have to do in order to allow the compiler to do so - usually the straightforward return f(...) pattern will work, but sometimes the compiler can support more complex code.
Both depend on your specific compiler, so I would look up documentation about it - I could not tell what it is from your question.
We all know the program for this
int fact(int n)
{
if(n==0)
return(1);
return(n*fact(n-1));
}
But what is not clear to me is how the inner thing is happening?
How is it calculating 5*4*3*2*1 (if n is 5)
Please give a clear explanation on this.
Thanks.....
Mathematically, the recursive definition of factorial can be expressed recursively like so (from Wikipedia):
Consider how this works for n = 3, using == to mean equivalence:
3! == 2! * 3 == (1! * 2) * 3 == ((1) * 2) * 3
This can be derived purely symbolically by repeatedly applying the recursive rule.
What this definition does is first expand out a given factorial into an equivalent series of multiplications. It then performs the actual multiplications. The C code you have performs the exact same way.
What might help to understand it, is that when you are recursively calling the function, the new "cycle" will use N-1, not N.
This way, once you get to N==0, the last function you called will return a 1. At this point all the stack of functions are waiting for the return of the nested function. That is how now you exactly multiply the results of each of the functions on the stack.
In other words, you factorize the number given as input.
this is a dynamic programming pseudocode for TSP (Travelling Salesman Problem). i understood its optimal substructure but i can't figure out what the code in red brackets do.
i am not asking anyone to write the actual code, i just need explanation on what is happening so i can write my own.... thanks:)
here is a link for the pseudocode, i couln't uploaded over here.
http://www.imagechicken.com/viewpic.php?p=1266328410025325200&x=jpg
Here is some less mathematical pseudo-code. I don't know if this will explain what's happening, but it may help you read it. This isn't a functional algorithm (lots of := all over), so I'm going to use Python pseudo-code.
# I have no idea where 'i' comes from. It's not defined anywhere
for k in range(2,n):
C[set(i,k), k] = d(1,k)
shortest_path = VERY_LARGE_NUMBER
# I have to assume that n is the number of nodes in the graph G
# other things that are not defined:
# d_i,j -- I will assume it's the distance from i to j in G
for subset_size in range(3,n):
for index_subset in subsets_of_size(subset_size, range(1,n)):
for k in index_subset:
C[S,k] = argmin(lambda m: C[S-k,m] + d(G,m,k), S - k)
shortest_path = argmin(lambda k: C[set(range(1,n)),k] + d(G,1,k), range(2,n))
return shortest_path
# also needed....
def d(G, i, j):
return G[i][j]
def subsets_of_size(n, s): # returns a list of sets
# complicated code goes here
pass
def argmin(f, l):
best = l[0]
bestVal = f(best)
for x in l[1:]:
newVal = f(x)
if newVal < bestVal:
best = x
bestVal = newVal
return best
Some notes:
The source algorithm is not complete. At least, its formatting is weird in the inner loop, and it rebinds k in the second argmin. So the whole thing is probably wrong; I've not tried to run this code.
arguments to range should probably all be increased by 1 since Python counts from 0, not 1. (and in general counting from 1 is a bad idea).
I assume that G is a dictionary of type { from : { to : length } }. In other words, an adjacency list representation.
I inferred that C is a dictionary of type { (set(int),int) : int }. I could be wrong.
I use a set as keys to C. In real Python, you must convert to a frozen_set first. The conversion is just busywork so I left it out.
I can't remember the set operators in Python. I seem to remember it uses | and & instead of + and -.
I didn't write subsets_of_size. It's fairly complicated.