1

I'm trying to make a program that goes through all squares of a chessboard (size doesn't really matter, but for now it's 6x6) with a knight, called a "Knight's Tour" check it out on wiki.

The tour is supposed to be closed, which means the knight on the last visited square can "attack" the square he started at. The code works fine for some squares, for example, input 'traverse(1,1,1)' in main generates output that shows not only is he traversing but backtracking and going back to traversing towards the goal successfully. However, would I input 'traverse(1,0,0)' instead, I get a StackOverflowError. Since it is successful sometimes, backtracking and traversing, I know the code works, I just have no idea how to get rid of the errors. I assume I'm making too many calls, but I have no idea how to get around that, there's alot of squares to visit :) Edited out the code, mostly because the teacher could find it an say I cheated.

false
  • 10,264
  • 13
  • 101
  • 209
XistenZ
  • 309
  • 1
  • 4
  • 14
  • Maybe I've had too many Chocobos today, but it looks like `traverse(1, 0, 0)` should immediately return. – David Harkness Mar 05 '11 at 01:57
  • Which algorithm do you implement? I highly suggest you to read the solutions proposed on same wiki page you provided. The divide and conquer one works using polynomial time. – UmNyobe Jan 30 '12 at 12:24

1 Answers1

4

You are trying to solve an exponential complexity problem with recursion. That's not going to work outside of very small inputs. The stack size grows way faster than the size of the problem. It will not take a very large problem size to blow through the stack.

You are not going to get StackOverflowErrors to go away. You need to re-think your algorithm to be loop-based instead of recursion based.

Konstantin Komissarchik
  • 28,879
  • 6
  • 61
  • 61
  • That sounds like a method that should take tremendous amount of time, you mean that when one is to solve a problem with recursion, there is a maximum amount of choices before it's simply labeled "impossible to solve with recursion" and forced to use loops instead? – XistenZ Mar 05 '11 at 14:54
  • That is correct. Each stack frame costs resources. You cannot allocate an overly large number of stack frames to solve a problem as you will run out of your system resources very quickly. With an exponential complexity problem, you cannot even enable a recursive solution with more hardware as number of stack frames needed grows exponentially faster than the problem size. A loop, by comparison doesn't require additional resources for every iteration. – Konstantin Komissarchik Mar 05 '11 at 16:43
  • @user645621: In Java, yes, but it's not an inherent problem with recursion. As far as I can see, the recursion in your algorithm consists entirely of tail calls (i.e. your functions end with a function call). *If* the JVM did Tail Call Optimization, this particular solution would consume no more stack space than a looping one, as the compiler would convert the tail calls into jumps. In other words, if you rewrote it in Scheme (or Erlang, or some other language with TCO), it would run. – molbdnilo Mar 05 '11 at 21:07
  • @molbdnilo How do I go about changing my code so that my methods don't end with function calls? I've tried to read up on recursion and tail calls, to no big surprise, the world wants to keep the information about what it really is away from me. But from what I could tell the ones that work is loaded with returns, so I remade my methods to 'public static boolean' and at every 'traverse' and 'backtrack'-call I added a return in front of them (return traverse(), etc). Is that the right way to go? I just don't know. – XistenZ Mar 06 '11 at 00:05
  • @user645621: No, you don't need to do that. Those function calls your functions end with kind of are returns, it's just that you're not allowed to return a `void`. The function calls are fine, the point is that the last thing a function does is call another (or the same) function. As I said, Java doesn't do tail call optimization, so unfortunately you can't improve the situation without switching languages. – molbdnilo Mar 06 '11 at 07:20
  • Wohoo! I finally made it work, it's still in Java, but using loops instead. It was a little tricky, but I thought of and wrote an algorithm down step-by-step, then made it into code. Thanks for your help! – XistenZ Mar 06 '11 at 21:26