Forgive me i'm new to recursion but as far as i understand this should work, but it doesn't. I made this method that calls itself recursively when successfully found a path:
private void RandStep(Point pos)
{
Collections.shuffle(Arrays.asList(directions), rand); //Incorrect, should have a local directions array. Nothing to do with the question though.
for (int i = 0; i < directions.length;i++)
{
//Check if the positions are within map bounds.
if (pos.x + directions[i].x >= 0 && pos.x + directions[i].x < width && pos.y + directions[i].y >= 0 && pos.y + directions[i].y < height)
{
//Check if the position is unvisited.
if (!mazeMap[pos.x + directions[i].x][pos.y + directions[i].y].visited)
{
//Break walls this tile.
CarvePassage(pos, directions[i]);
mazeMap[pos.x + directions[i].x][pos.y + directions[i].y].visited = true;
position.setLocation(pos.x + directions[i].x, pos.y + directions[i].y);
RandStep(position);
}
}
}
}
First it randomizes an array with 4 directions.
Then i loop through the array to find a possible direction.
Then It checks if the direction found is valid otherwise it goes to the next direction in the array
When it is valid it calls another method that carves the wall of the current tile and the next tile.
It changes the current position to the next and sets it's flag to visited.
Finally it calls itself again to make the next step.
This all works until the first time it gets stuck between visited cells or map bounds. If i understand recursion correctly it should exit this method and go to the previous run of RandStep and finish the direction loop. When it does not find any valid cells there: it again should exit and finish the loop in the previous RandStep. This should be repeated until it finished the direction loop of the very first RandStep run.
Like i said, it stops at the moment it cannot find any valid cells. It does not continue the previous methods on the recursion stack.
Quite simply, it's because you don't step back!
position.setLocation(pos.x + directions[i].x, pos.y + directions[i].y);
RandStep(position);
Should be something like:
position.setLocation(pos.x + directions[i].x, pos.y + directions[i].y);
RandStep(position);
position.setLocation(pos.x - directions[i].x, pos.y - directions[i].y);
As a bit of intuition, think about what happens in the base case of recursion. all tiles around you are visited, and you are at a dead end. That situation looks like:
_
| |
|x|
(x = "you are here")
Then, position.setLocation(pos.x + directions[i].x, pos.y + directions[i].y); puts you here:
_
|x|
| |
Then, RandStep(position); does nothing since all locations around you are explored. So the next thing you want to do is step backwards, which is accomplished by something like: position.setLocation(pos.x - directions[i].x, pos.y - directions[i].y);.
Let's take a closer look at what is happening under the hood. Assuming you are familiar with what a heap and a stack are, the variable position resides on the heap, as it is not local to your function RandStep. On the other hand, pos is local, so it resides on the stack. With every recursive call, a new stack frame is allocated (from frameA to frameC). I represent positions as single values for the sake of brevity. Let's say that you start from position 0, and then break the walls towards position 1. What happens is that a new frame is allocated for the new value of pos, but positionis overwritten. The same when you transition from position 1 to position 2. Let's say that from position 2 there's nowhere to go, so we need to trace back. Then frameC is deallocated. However, instead of using the value of pos in the top frame (which is frameB now), your call to RandStep was made on position, so the value that you use is the one on the heap, which remained unchanged despite the frame deallocation.
"Stepping back" as suggested by Intredasting acutally means manually updating the heap, so that position follows the same evolution as pos. In my opinion, that defeats the purpose of recursion. Its beauty is that it takes care itself of the stepping back part by deallocation.
In conclusion, what you need to do is avoid changing the heap at all in recursive functions.
|STACK | |STACK | |STACK |
| | | | | |
| | | | |frameC: pos = 2|---> got stuck, deallocate frame
| | |frameB: pos=1 | |frameB: pos = 1| and backtrack
|frameA: pos=0 | |frameA: pos=0 | |frameA: pos = 0|
|---------------| |--------------| |---------------|
|HEAP | |HEAP | |HEAP |
|position = 0 | |position=1 | |position = 2 |
| | | | | |
| | | | | |
----------------- ---------------- -----------------
Related
Below is a function which takes int and return int. Within the function I call the function itself and if i==1, I want to go out of my function.
Basically I'm trying to calculate factorial in recursive manner.
Code Snippet
static int factorial(int i){
result = result * i;
if(i==1){
return 0;
}
factorial(i-1);
return 1;
}
Note - result is an global int variable and is initialize to 1.
Why this function returns 1 instead of 0.
[Note when i==1 then with return statement the pointer should come out of the function]
Please don't post better algorithm for factorial, I'm looking for - why this code is behaving a bit different.
Your code doesn't even compile as result isn't defined.
Then, the method could return either 0 or 1, nothing else regarding the return you wrote, so you can't expect to get real values.
Then the real algorithm
for 0 or 1, return 1
else return the value multiplied by the factorial(previous)
static int factorial(int i) {
if (i <= 1) { // for 0 or 1
return 1;
}
return i * factorial(i - 1);
}
example calling factorial(3):
int i = factorial(3);
+--------------------------------------------------+
|result = result * 3; |
|if (i==1) { |
| // not executed |
|} |
|factorial(2); |
| +-------------------------------------------+ |
| |result = result * 2; | |
| |if (i==1) { | |
| | // not executed | |
| |} | |
| |factorial(1); | |
| | +---------------------------------+ | |
| | |result = result * 1; | | |
| | |if (i==1) { | | |
| | | return 0; | | |
| | |// nothing more in factorial(1) | | |
| | +---------------------------------+ | |
| |// factorial(1) returned 0 (value not used)| |
| |return 1; // factorial(2) | |
| +-------------------------------------------+ |
|// factorial(2) returned 1 (value not used) |
|return 1; // factorial(3) |
+--------------------------------------------------+
i = 1; // the value returned by last call
factorial(3) returns 1! recursion was terminated by return 0, but that value is not being used
Zero would have been returned if the last two lines were joined to return factorial(i-1);
only factorial(1) will return 0, e.g. int i = factorial(1)
Because u are not returning 0. Your function will always return 1 which is the returned value of the first call. All the other recursive function calls are being made but not being used to return by the parent function. For example if you call factorial(5) then all the recurring calls (from 4 to 1) would execute and process the "result" variable but you will only get the returned value of factorial(5) which is always going to be 1.
The fundamental problem with your code is that it is confused about how it wants to return data.
You have a result global variable which is supposed to be how this function 'communicates' the answer, but it also has a return value. They sound quite different (one is a variable, one is a language construct), but they are used for the same purpose here. Half the time you return, half the time you set result, and this leads to your code having the effects you are observing.
The solution is to pick a side. Either use only result - update the method to have a void return value, and do not use the return x; statement (only return;). Alternatively, get rid of result entirely, and communicate using return.
if(i==1){
return 0;
}
Take this line and compare to the very next one:
factorial(i-1);
This line calls the factorial function and throws out whatever it returned because you don't assign it anywhere. That is why you can't observe that 0 you are returning: Because you ignore it.
It looks to me like you think that return 0; somehow sets result, or that result holds 'whatever the function returned' but this isn't true. They are separate things.
I've been working on a program that lets you enter pizza toppings. It's pretty much complete, except for the removeToppings() method.
The problem is, I can't seem to figure out the correct way to remove the toppings in the index that the user chooses and all of the toppings BEFORE it. I have found numerous ways to remove indexes that come AFTER, but even then I can't find ways to reverse them.
Here's the method in question:
public static void removeTopping()
{
Scanner in = new Scanner(System.in);
printPizza();
System.out.println("What topping do you want to remove?\n"
+ "Keep in mind, this loses everything else above it.\n"
+ "Enter index number: ");
int remove = in.nextInt();
toppings.subList(remove, toppings.size()).clear(); //this is the problem line!
}
The printPizza() method would print something that looks like this:
|index|topping|
| 0 | cheese
| 1 | three
| 2 | cheese
| 3 | two
| 4 | cheese
| 5 | one
| 6 | sauce
| 7 | crust
Say I enter 5, the program would remove indexes 5, 6, and 7. I would want it to remove 0-5. Any pointers would be much appreciated.
You can use a for loop to achieve this.
The loop will start by removing the index specified by the remove variable. Then, the loop will decrement i until it reaches -1, by this point, it will have removed every element below the index you set.
for (int i = remove; i > -1; i--) {
myList.remove(i);
}
If in your example you also want to remove the position 5:
toppings.subList(0, remove + 1).clear();
public static void reversePrint(int[] numbers){
if(numbers.length == 0) //Base case
return;
int[] a = new int[numbers.length-1];
for(int i = 0; i < numbers.length-1;i++)
a[i] = numbers[i+1];
reversePrint(a);
System.out.println(numbers[0]);
}
public static void main(String[] args){
int[] array = new int[]{5,1,34,12,7};
reversePrint(array);
}
Output:
7
12
34
1
5
Everything is pretty straightforward, have a function called reversePrint. When you pass those numbers to the function reversePrint, it takes the first value out, (in this case '5') and then it calls reversePrint again,now with the smaller list.
This Continues until finally we're left with no more numbers, and begins to print them out.
My confusion is in line '10', if the list of numbers is getting less and less by removing the first number each time, how does calling 'System.out.println(numbers[0]);' retrieve numbers that have been removed from the list, and doing so in reverse order?
Here's a scheme to understand the stack of calls in this recursion:
reversePrint([5,1,34,12,7]) {
reversePrint([1,34,12,7]) { // <-- this list IS A COPY, it just ignores the first number
reversePrint([34,12,7]) {
reversePrint([12,7]) {
reversePrint([7]) {
reversePrint([]);
print(7); // <-- this is the first number of the current list
};
print(12);
};
print(34);
};
print(1);
};
print(5);
};
As you can see, the System.out.println(numbers[0]) is called AFTER propagating the recursion. Note that a new array is created in each call, you don't lose the first number.
First, you don't actually remove numbers: you copy them from numbers to a skipping the one in position 0. That System.out.println prints from numbers, so the integer at index 0 will still be the same.
Second, the System.out.println statement is after the recursive call, so it will be executed after that call returns. So basically, the first System.out.println that will execute will be the one in the last call:
for ...
reversePrint
|
| for ...
| reversePrint
| |
| | for ...
| | reversePrint
| | |
| | | for ...
| | | reversePrint
| | | |
| | | | for ...
| | | | reversePrint
| | | | |
| | | | | return
| | | | |
| | | | System.out.println
| | | |
| | | System.out.println
| | |
| | System.out.println
| |
| System.out.println
|
System.out.println
That's an exceptionally ineffective implementation of
Arrays.asList(5, 1, 34, 12, 7).reverse().forEach(System.out::println)
But to answer your question, the reversePrint creates a new array with the first item removed from the array, then prints out the first of the original. The second call will receive [1, 34, 12, 7] because the first has removed the 5, so it will print out the 1.
how does calling 'System.out.println(numbers[0]);' retrieve numbers that have been removed from the list, and doing so in reverse order?
No numbers have been removed from any array in this code. Each recursive call creates a new array and copies to it all the elements of the current array except of the first element.
Therefore the array passed to the i'th call to reversePrint() contains the last n-i+1 elements of the original array.
The recursion ends when reversePrint() is called for an empty array. When the last recursive call returns, the next to last call prints numbers[0], which contains the last element of the original array. Then the previous reversePrint() prints numbers[0], which contains the next to last element of the original array, and so on...
These are the recursive calls:
reversePrint({5,1,34,12,7})
reversePrint({1,34,12,7})
reversePrint({34,12,7})
reversePrint({12,7})
reversePrint({7})
reversePrint({})
Now, after each of them returns, numbers[0] is printed, so you get
7
12
34
1
5
Perhaps doing it the classic way (rather than making a copy of the array as you do) it would be clearer what is happening.
// Private version to pass the offset which increases on each call.
private static void reversePrint(int[] numbers, int from){
// Base case - stop at end of array.
if(numbers.length > from) {
// Print everything else first.
reversePrint(numbers, from+1);
// Then the one I am at.
System.out.println(numbers[from]);
}
}
public static void reversePrint(int[] numbers){
reversePrint(numbers, 0);
}
public void test() throws Exception {
System.out.println("Hello world!");
int[] array = new int[]{5,1,34,12,7};
reversePrint(array);
}
When I run this piece of code for n=5 the output I get is "5 3 1 1 3 5"
I get the 5 3 1 part but after that n=-1 but when I run the code with a debugger it when n=-1 it goes to the line after numbers(n-2);i.e System.out.prt(n+ ""); even though that statement is contained in the if block.
Why does this happen?
public void numbers(int n)
{
if(n>0)
{
System.out.print(n+" ");
numbers(n-2);
System.out.print(n+" ");
}
}
TLDR : when n=-1 System.out.prt(n+ "");even though it is within the if block which only runs when n>0.
Any help would be much appreciated. Thanks in advance!
Here is what happens behind the scenes, for n == 5:
numbers(5);
if(5 > 0)--> true :
System.out.print(5 + " "); // (1)
numbers(3);
| if(3 > 0)--> true :
| System.out.print(3 + " "); // (2)
| numbers(1);
| | if(1 > 0)--> true :
| | System.out.print(1 + " "); // (3)
| | numbers(-1);
| | System.out.print(1 + " "); // (4)
| System.out.print(3 + " "); // (5)
System.out.print(5 + " "); // (6)
Notice how each number is supposed to be printed twice:
System.out.print(n + " "); // print once
numbers(n-2);
System.out.print(n + " "); // print twice
Remove the final System.out.print(n+" ");
After the recursive numbers call it comes back with the original value for n and prints this again.
It bubbles back from the deepest level where it prints 1 two times up to the call with number 3, which is printed again, and also 5 is printed again.
If you want it to update the value after it is printed the first time you will have to update the variable n by performing n-=2 instead of n-2
5 first system.out then number(5-2)
|
----> 3 first system.out then number(5-2)
|
----->1 first system.out then number(5-2)
(smaller than 0) , returning
|
1 second system.out
|
3<---- second system.out
|
5<--------- second system.out
after n=-1, the recursive call will end and return back to the caller method to continue. first commands it found is print.
If you try to debug with the debugger, you will see how rational it is.
Java maintain method call into stack and as first 5,3,1 gets printed after which method call resume execution for remaining calls and prints 1,3,5 from stack(last call in stack get's picked up first).
Follow the recursion stack.
stack representation with and output flow:
------------------------->
5 3 1
num(5)--> num(3) --> num(1) --> num(-1) --> void
5 3 1
<-------------------------
Now since numbers(-1) does not satisfy the if condition, the program control comes out of the if block, and returns void.
Start popping out the stack now (recursion):
5 3 1 1 3 5. That's what the output you get, and is expected.
I've found out that the results of the SVDecomp function in Java are very different from the results of WolframAlpha.
The input matrix is excactly the same for OpenCV and WolframAlpha
{{0.2229632566816983, 18.15370964847313, 4.87085706173828},
{-14.31728552253419, 2.642676839378287, -33.69501515553716},
{-2.982323803144884, 33.70091859922499, 0.8997452211463326}}
Here are the results from WolframAlpha:
U = (-0.441818862735368 | 0.214800119324567 | -0.871009185525260
-0.245069575462508 | -0.962880608842737 | -0.113145200062862
-0.862981457340684 | 0.163468167704881 | 0.478059789601005)
W = (38.5925763913943 | 0 | 0
0 | 36.8337256561100 | 0
0 | 0 | 3.76859638821616×10^-10)
V = (0.155053443270976 | 0.362336795687042 | 0.919059560758203
-0.978207790691182 | 0.186347267503429 | 0.0915653543928191
0.138086740713550 | 0.913228745925823 | -0.383334461865688)
And here is what OpenCV produces when using SCDecomp:
U: [0.4418188627353685, 0.2148001193245664, -0.8710091855252606;
0.2450695754625076, -0.9628806088427376, -0.113145200062862;
0.8629814573406845, 0.1634681677048805, 0.4780597896010051]
W: [38.59257639139431; 36.83372565611004; 3.768597946996713e-10]
VT:[-0.155053443270976, 0.3623367956870423, 0.9190595607582029;
0.9782077906911818, 0.1863472675034285, 0.09156535439281914;
-0.1380867407135498, 0.9132287459258235, -0.3833344618656882]
To mention: W in OpenCV is not a matrix, as well as the sign of the values are sometimes different.
Is this a bug? Here is my SourceCode
Core.SVDecomp(E, w, u, vt);
I don't think the result are that different:
Both U matrices contain the same vector with the 1st one (1st column of each matrix) being the opposite of the other (no problem here just a sign alteration)
W is the same but in the first case is returned as diagonal matrix and in the second as vector (only the main diagonal is returned).
The V matrices are the same case as the U ones (the first vector is the opposite).
So the results are the same.