Wrong output in recursive fibonacci number program - recursion

I have written the program to print fibonacci numbers upto the limit as the user wants. I wrote that program in recursive fashion which should give the output as expected. It is giving the right output but with appended wrong values too. This happens if the user wants to print 4 or more than 4 fibonacci numbers. Also in the recursive function I have decreased the count value before passing it in the same function call. If i decrease the count value in the called function parameters then the while loop runs endlessly. When the loop finishes after some steps and the user limit input is 5 then the output is
Enter the limit number....
5
Fibonacci numbers are: 0 1 1 2 3 3 2 3 3
Finished.........
Can anyone tell me the fault in my program or the exact reason behind this output. Thanks in advance for it.
Program is as follows:
public class FibonacciNumbers
{
public static void main(String[] args)
{
int i=0, j=1;
Scanner sc = new Scanner(System.in);
System.out.println("Enter the limit number....");
int num = sc.nextInt();
System.out.print("Fibonacci numbers are: " + i + " " + j + " " );
fibonacci(num-2, i, j);
System.out.println("\nFinished.........");
}
public static void fibonacci(int count, int i, int j)
{
int sum = 0;
while(count > 0)
{
sum = i+j;
i=j;
j=sum;
System.out.print(sum + " ");
--count;
fibonacci(count, i, j);
}
}
}

You don't need both the while loop AND the recursive function calls. You have to choose between using a loop OR recursive calls.
The recursive solution:
public static void fibonacci(int count, int i, int j) {
if (count>0){
int sum = i+j;
i=j;
j=sum;
System.out.print(sum + " ");
--count;
fibonacci(count, i, j);
}
}
The solution involving a loop:
public static void fibonacci(int count, int i, int j) {
int sum = 0;
while(count > 0) {
sum = i+j;
i=j;
j=sum;
System.out.print(sum + " ");
--count;
}
}
The problem with your code
If you look closely at the following output of your code, you can see that in the beginning of the output there are the actual 7 first fibonacci numbers, and after that comes an unneeded series of the same fibonacci numbers. You printed two numbers from main, and then you expected 5 more numbers but got 31:
Enter the limit number.... 7
Fibonacci numbers are: 0 1 1 2 3 5 8 8 5 8 8 3 5 8 8 5 8 8 2 3 5 8 8 5
8 8 3 5 8 8 5 8 8
This happens because when you first call the fibonacci function with count=5, the while loop has 5 iterations, so it prints 5 fibonacci numbers and the fibonacci function is called 5 times from there with these count parameters: 4,3,2,1,0. When the fibonacci function is called with the parameter count=4, it prints 4 numbers and calls fibonacci 4 times with these parameters: 3,2,1,0 because the while loop then has 4 iterations. I drew an image of the recursive calls (I omitted the f(0) calls because they don't print anything):
If you add it all up, you can see that the program prints 31 fibonacci numbers altogether which is way too much because you wanted to print only 5! This trouble is caused by using while and recursive calls at the same time. You want the recursive behaviour to be like this instead, with no while loop:
OR you want one while loop and no recursion:

Related

Modify dijkstra's algorithm with some conditions

Given an undirected graph with costs on edges, find the shortest path, from given node A to B. Let's put it this way: besides the costs and edges we start at time t = 0 and for every node you are given a list with some times that you can't pass through those nodes at that times, and you can't do anything in that time you have to wait until "it passes". As the statement says, you are a prisoner and you can teleport through the cells and the teleportation time requires the cost of the edge time, and those time when you can't do anything is when a guardian is with you in the cell and they are in the cell at every timestamp given from the list, find the minimum time to escape the prison.
What I tried:
I tried to modify it like that: in the normal dijkstra you check if it's a guardian at the minimum time you find for every node, but it didn't work.. any other ideas?
int checkGuardian(int min, int ind, List *guardians)
{
for (List iter = guardians[ind]; iter; iter = iter->next)
if(min == iter->value.node)
return min + iter->value.node;
return 0;
}
void dijkstra(Graph G, int start, int end, List *guardians)
{
Multiset H = initMultiset();
int *parent = (int *)malloc(G->V * sizeof(int));
for (int i = 0; i < G->V; ++i)
{
G->distance[i] = INF;
parent[i] = -1;
}
G->distance[start] = 0;
H = insert(H, make_pair(start, 0));
while(!isEmptyMultiset(H))
{
Pair first = extractMin(H);
for (List iter = G->adjList[first.node]; iter; iter = iter->next)
if(G->distance[iter->value.node] > G->distance[first.node] + iter->value.cost
+ checkGuardian(G->distance[first.node] + iter->value.cost, iter->value.node, guardians))
{
G->distance[iter->value.node] = G->distance[first.node] + iter->value.cost
+ checkGuardian(G->distance[first.node] + iter->value.cost, iter->value.node, guardians);
H = insert(H, make_pair(iter->value.node, G->distance[iter->value.node]));
parent[iter->value.node] = first.node;
}
}
printf("%d\n", G->distance[end]);
printPath(parent, end);
printf("%d\n", end);
}
with these structures:
typedef struct graph
{
int V;
int *distance;
List *adjList;
} *Graph;
typedef struct list
{
int size;
Pair value;
struct list *tail;
struct list *next;
struct list *prev;
} *List;
typedef struct multiset
{
Pair vector[MAX];
int size;
int capacity;
} *Multiset;
typedef struct pair
{
int node, cost;
} Pair;
As an input you are given number of nodes, number of edges and start node. For the next number of edges lines you are reading and edge between 2 nodes and the cost associated with that edge, then for the next number of nodes lines you are reading a character "N" if you can't escape from that cell and "Y" if you can escape from that cell then the number of timestamps guardians are in then number of timestamps, timestamps.
For this input:
6 7 1
1 2 5
1 4 3
2 4 1
2 3 8
2 6 4
3 6 2
1 5 10
N 0
N 4 2 3 4 7
Y 0
N 3 3 6 7
N 3 10 11 12
N 3 7 8 9
I would expect this output:
12
1 4 2 6 3
But I get this output:
10
1 4 2 6 3

How do I add the results of work-items in a work-group in OpenCL?

I'm calling the kernel below with GlobalWorkSize 64 4 1 and WorkGroupSize 1 4 1 with the argument output initialized to zeros.
__kernel void kernelB(__global unsigned int * output)
{
uint gid0 = get_global_id(0);
uint gid1 = get_global_id(1);
output[gid0] += gid1;
}
I'm expecting 6 6 6 6 ... as the sum of the gid1's (0 + 1 + 2 + 3). Instead I get 3 3 3 3 ... Is there a way to get this functionality? In general I need the sum of the results of each work-item in a work group.
EDIT: It seems it must be said, I'd like to solve this problem without atomics.
You need to use local memory to store the output from all work items. After the work items are done their computation, you sum the results with an accumulation step.
__kernel void kernelB(__global unsigned int * output)
{
uint item_id = get_local_id(0);
uint group_id = get_group_id(0);
//memory size is hard-coded to the expected work group size for this example
local unsigned int result[4];
//the computation
result[item_id] = item_id % 3;
//wait for all items to write to result
barrier(CLK_LOCAL_MEM_FENCE);
//simple O(n) reduction using the first work item in the group
if(local_id == 0){
for(int i=1;i<4;i++){
result[0] += result[i];
}
output[group_id] = result[0];
}
}
Multiple work items are accessing elements of global simultaneously and the result is undefined. You need to use atomic operations or write unique location per work item.

Recursively Find A Path

I have a series of numbers ranging from 0-9. Each number represents a position with an x and y co-ordinate. So, position 0 could represent (5, 5) or something similar, always (x, y). Now what I need to do is recursively bash each possible route using 5 positions to get the position given by a user. So for example:
Input = (1, 2) //This is the co-ordinate the user gives.
Now given this input it should take every possible path and find the shortest one. Some paths could be:
start 0 1 2 3 4 input
start 0 1 2 3 5 input
start 0 1 2 3 6 input
start 0 1 2 3 7 input
start 0 1 2 4 3 input
start 1 0 2 3 5 input
and so on....
It could be any combination of 5 numbers from the 0-9. It must end at the input destination and begin at start destination. Numbers cannot be reused. So I need to recursively add all the distances for a given course (ex. start 0 1 2 3 4 input) and find the shortest possible course while going through those 5 points.
Question: What would the base and recursive case be?
Basically what you want to do is generate all combinations of size k (the length of the path) from the set {1,..,n}, and then calculate the value of the path for it.
Here's a C# code sample:
void OPTPathForKSteps(List<int> currentPath, List<int> remainingPositions, int remainingSteps)
{
if (remainingSteps == 0)
{
// currentPath now contains a combination of k positions
// do something with currentPath...
}
else
{
for (int i = 0; i < remainingPositions.Count; i++)
{
int TempPositionIndex = remainingPositions[i];
currentPath.Add(TempPositionIndex);
remainingPositions.RemoveAt(i);
OPTPathForKSteps(currentPath, remainingPositions, remainingSteps - 1);
remainingPositions.Insert(i, TempPositionIndex);
currentPath.RemoveAt(currentPath.Count - 1);
}
}
}
This is the initial call for the function (assume Positions is an integer list of 0...n positions, and k is the length of the path):
OPTPathForKSteps(new List<int>(), Positions, K);
You can change the function and add arguments so it will return the optimal path and minimal value.
There are other (maybe shorter) ways to create these combinations, the good thing about my implementation is that it is light on the memory, and doesn't require storing all the possible combinations.

Determining the big Oh for (n-1)+(n-1)

I have been trying to get my head around this perticular complexity computation but everything i read about this type of complexity says to me that it is of type big O(2^n) but if i add a counter to the code and check how many times it iterates per given n it seems to follow the curve of 4^n instead. Maybe i just misunderstood as i placed an count++; inside the scope.
Is this not of type big O(2^n)?
public int test(int n)
{
if (n == 0)
return 0;
else
return test(n-1) + test(n-1);
}
I would appreciate any hints or explanation on this! I completely new to this complexity calculation and this one has thrown me off the track.
//Regards
int test(int n)
{
printf("%d\n", n);
if (n == 0) {
return 0;
}
else {
return test(n - 1) + test(n - 1);
}
}
With a printout at the top of the function, running test(8) and counting the number of times each n is printed yields this output, which clearly shows 2n growth.
$ ./test | sort | uniq -c
256 0
128 1
64 2
32 3
16 4
8 5
4 6
2 7
1 8
(uniq -c counts the number of times each line occurs. 0 is printed 256 times, 1 128 times, etc.)
Perhaps you mean you got a result of O(2n+1), rather than O(4n)? If you add up all of these numbers you'll get 511, which for n=8 is 2n+1-1.
If that's what you meant, then that's fine. O(2n+1) = O(2⋅2n) = O(2n)
First off: the 'else' statement is obsolete since the if already returns if it evaluates to true.
On topic: every iteration forks 2 different iterations, which fork 2 iterations themselves, etc. etc. As such, for n=1 the function is called 2 times, plus the originating call. For n=2 it is called 4+1 times, then 8+1, then 16+1 etc. The complexity is therefore clearly 2^n, since the constant is cancelled out by the exponential.
I suspect your counter wasn't properly reset between calls.
Let x(n) be a number of total calls of test.
x(0) = 1
x(n) = 2 * x(n - 1) = 2 * 2 * x(n-2) = 2 * 2 * ... * 2
There is total of n twos - hence 2^n calls.
The complexity T(n) of this function can be easily shown to equal c + 2*T(n-1). The recurrence given by
T(0) = 0
T(n) = c + 2*T(n-1)
Has as its solution c*(2^n - 1), or something like that. It's O(2^n).
Now, if you take the input size of your function to be m = lg n, as might be acceptable in this scenario (the number of bits to represent n, the true input size) then this is, in fact, an O(m^4) algorithm... since O(n^2) = O(m^4).

Summing elems of array using binary recursion

I wasn't starting to understand linear recursion and then I thought I practice up on sorting algorithms and then quick sort was where I had trouble with recursion. So I decided to work with a simpler eg, a binary sum that I found online. I understand that recursion, like all function calls, are executed one # a time and not at the same time (which is what multi-threading does but is not of my concern when tracing). So I need to execute all of recursive call A BEFORE recursive call B, but I get lost in the mix. Does anyone mind tracing it completely. The e.g. I have used of size, n = 9 where elems are all 1's to keep it simple.
/**
* Sums an integer array using binary recursion.
* #param arr, an integer array
* #param i starting index
* #param n size of the array
* floor(x) is largest integer <= x
* ceil(x) is smallest integer >= x
*/
public int binarySum(int arr[], int i, int n) {
if (n == 1)
return arr[i];
return binarySum(arr, i, ceil(n/2)) + binarySum(arr,i + ceil(n/2), floor(n/2));
}
What I personally do is start with an array of size 2. There are two elements.
return binarySum(arr, i, ceil(n/2)) + binarySum(arr,i + ceil(n/2), floor(n/2)) will do nothing but split the array into 2 and add the two elements. - case 1
now, this trivial starting point will be the lowest level of the recursion for the higher cases.
now increase n = 4. the array is split into 2 : indices from 0-2 and 2-4.
now the 2 elements inside indices 0 to 2 are added in case 1 and so are the 2 elements added in indices 2-4.
Now these two results are added in this case.
Now we are able to make more sense of the recursion technique, some times understanding bottom up is easier as in this case!
Now to your question consider an array of 9 elements : 1 2 3 4 5 6 7 8 9
n = 9 => ceil(9/2) = 5, floor(9/2) = 4
Now first call (top call) of binarySum(array, 0, 9)
now n = size is not 1
hence the recursive call....
return binarySum(array, 0, 5) + binarySum(array, 5, 4)
now the first binarySum(array, 0 ,5) operates on the first 5 elements of the array and the second binarySum(array,5,4) operates on the last 4 elements of the array
hence the array division can be seen like this: 1 2 3 4 5 | 6 7 8 9
The first function finds the sum of the elements: 1 2 3 4 5
and the second function finds the sum of the elements 6 7 8 9
and these two are added together and returned as the answer to the top call!
now how does this 1+2+3+4+5 and 6+7+8+9 work? we recurse again....
so the tracing will look like
1 2 3 4 5 | 6 7 8 9
1 2 3 | 4 5 6 7 | 8 9
1 2 | 3 4 | 5 6 | 7 8 | 9
[1 | 2]___[3]___[4 5]___[6 7]___[8 9]
Till this we are fine..we are just calling the functions recursively.
But now, we hit the base case!
if (n == 1)
return arr[i];
[1 + 2]____[3]____[4 + 5]____[6 + 7]____[8 + 9]
[3 + 3] ____ [9] ____[13 + 17]
[6 + 9] [30]
[15 + 30]
[45]
which is the sum.
So for understanding see what is done to the major instance of the problem and you can be sure that the same thing is going to happen to the minor instance of the problem.
This example explains binary sum with trace in java
the trace is based on index of array , where 0 - is yours starting index and 8 is length of the array
int sum(int* arr, int p, int k) {
if (p == k)
return arr[k];
int s = (p + k) / 2;
return sum(arr, p, s) + sum(arr, s + 1, k);
}

Resources