Java sudoku backtracking recursive keeps giving StackOverflow - java

I implemented a SuDoku backtracking algorithm, but it keeps giving me StackOverflow Error. Any other methods or algorithms to avoid this, because I can't get my head around forming a loop for this.
public boolean guess(int istart){
int i=istart, j=0; boolean found=false;
for(i=istart; i<9; i++){//find first empty cell
for(j=0; j<9; j++){
if(get(i,j)==0) {found=true; break;}
}
if(found) break;
}
boolean[] pos=pos_copy;//pos_copy is a length-9 boolean array with all elements set to true
for(int n=0; n<9; n++){//store all possible numbers in pos[]
if(get(i,n)!=0) pos[get(i,n)-1]=false;
if(get(n,j)!=0) pos[get(n,j)-1]=false;
if(get(start[i]+n/3, start[j]+n%3)!=0) pos[get(start[i]+n/3, start[j]+n%3)-1]=false;
}
for(int n=0; n<9; n++) if(pos[n]) {
set(i,j,n+1);
if(i==8 && j==8) return true;
if(guess(i)) return true;//recurse; gives Stackoverflow at this line
}
set(i,j,0);
return false;
}

There is no (realistic) way to put this in a loop, but you can circumvent the recursion using a Dequeue approach (in the form of a stack).
First create a class that holds the current state of numbers entered into the Sodoku-field. Then instead of calling set(...) create a copy of that field and set the value in that copy. Then put that copy in a Dequeue and terminate the function.
Your search loop then becomes:
SodokuField field;
while (((field = dequeue.pollLast()) != null) && (field.isComplete() == false)) {
guess(field);
}
if (field != null) {
showSolution(field);
}
This approach has two benefits: first you won't get any StackOverflowException anymore, and second: you can easily put the code part above in the run() method of a Runnable and have multiple threads wait on a ConcurrentLinkedDeque.
Note: it is important to work stack-based, as otherwise you would create every possible combination of fields before finding the solution and therefore very soon run into memory issues.

Related

Simple flood fill method causes StackOverFlow error

My flood fill method:
public void fillNeighbours(int x, int y) {
for(int i = -1; i < 2; i++) {
for(int j = -1; j < 2; j++) {
try {
visible[x+i][y+j] = true;
if(num[x+i][y+j] == 0) {
fillNeighbours(x+i, y+j);
}
} catch (ArrayIndexOutOfBoundsException ignored) {}
}
}
}
That catch (ArrayIndexOutOfBoundsException ignored) {} is there for avoiding x and/or y position from going outside of the array. Array size is 30 by 30. I'm making minesweeper like game. So you may know why I need this method and how it should work. If u don't know what minesweeper is then here is quick video about that game: Introduction to minesweeper
The code revisits fields which are set to visible already.
Try something like
if(!visible[x+i][y+j]){
visible[x+i][y+j] = true;
if(num[x+i][y+j] == 0) {
fillNeighbours(x+i, y+j);
}
}
It looks like you're recursively calling fillNeighbours without any break out clause (base case) so the calls fill the stack.
From
Wikistack
The tree laws of recursion are
A recursive algorithm must have a base case.
A recursive algorithm
must change its state and move toward the base case.
A recursive
algorithm must call itself, recursively.
Once fillNeighbours finds a cell and calls itself, the next loop will always call another when i and j are equal to zero. So it will never exit, and crash once the stack is full.
Aside from that, it will produce a very deep tree as it is not keeping track of which cells have been recursed, and will call fillNeighbours on the same cell multiple times.

Java: Optimizing algorithm in game

I'm creating a game (Java) with scene2d.
I wrote function for collision detection but I think it's bad function. It looks bad.
How can I optimize it? Make faster and more beautiful.
private void deleteEnemies()
{
for(int i = 0; i < getActors().size - 1; i++)
{
if(getActors().get(i) != null && getActors().get(i) instanceof Enemy)
{
////////////////
for (int j = 0; j < getActors().size - 1; j++)
{
if(getActors().get(j) != null && getActors().get(j) instanceof Ball)
{
if (actorsIntersecting(getActors().get(i), getActors().get(j)))
{
getActors().get(i).remove();
getActors().get(j).remove();
}
}
}
//////////////
}
}
}
Put getActors().get(i) in a variable, dont call it twice in the outer if
Same for getActors().get(j) in the inner if
use these variable in the most inner if's condition and body
save the size in a variable because now the .size function is being called on every iteration when the for condition is checked
You shouldn't use a size that can dynamically change during the loop for the loop condition (because you are removing items as you go) which brings us back to #4.
Other than that its pretty much ok coding style perspective and I doubt you can make it more efficient than with what I told you (Other than using threads)
Since you will do this frequently, consider storing the Enemies and Balls in their own structures (List or Set or whatever works). That prevents you from looping through actors you don't need, and avoids the instanceof checks.
Well, my first idea was to check only "nearest" enemies and not all of them. Somehow try to decrease size of that list.
2. Second one - please check your and conditions in and one by one - now you are checking 2 conditions always. Try to put "heavier" if later, for example:
from:
if(getActors().get(i) != null && getActors().get(i) instanceof Enemy)
to:
if(getActors().get(i) != null) {
if(getActors().get(i) instanceof Enemy) {
.....
}
}
3. call your getActors().get(i) one time - save to variable.
4. I'm thinking why is it necessary to check if an actor is null, maybe just remove nulls from list or keep uninitialized actors on another list. Also try this with Balls and Enemies, please don't keep every actor on a single list.
I would rewrite the models a bit, so they can test the intersection itself and then do the delete like that (probably it can still be improved)
private void deleteEnemies () {
List<Actor> actors = getActors();
List<Actor> toRemove = new ArrayList<Actor>();
int actorsSize = actors.size();
Actor first = null, second = null;
for(int i = 0; i < actorsSize; ++i) {
first = actors.get(i);
for(int j = 0; j < actorsSize; ++j) {
if(i == j) continue;
second = actors.get(j);
if(first.intersects(second)) {
toRemove.add(first);
toRemove.add(second);
}
}
}
actors.removeAll(toRemove);
}
Don't use size(), define a variable
Try not to cast. Try not to uae instanceof.
Maybe, sort lists by zsort or the like so u can, sometimes, start and or stop the loops sooner??
Adding to the (very good) suggestions of the other participant: cache the enemies and projectiles in separate structures, so you don't have to check what they are at all.
Use the time vs space trade-off as much as you can: the standard approach, as hinted by Tomek, in this kind of situations is to reduce the number of checks (=iterations) by pruning the enemies and projectiles that cannot possibly collide within the current frame (they are way to far).
Anyway, a word of advice: go on with the game, complete as much as you can so that it will run correctly (if slowly), and only then go for the optimization.
That because
by optimizing preemptively in this way you will never finish it
you don't know how the final game really will be, perhaps: maybe after finishing 90% of it, you will see some easy chances for optimization.
As others have said, the real improvement to speed would be two collections, one with balls and the other with enemies. As for making it look nicer, you could something like this:
for (Actor enemy : getActors()) {
if (enemy != null && enemy instanceof Enemy) {
for (Actor ball : getActors()) {
if (ball != null && ball instanceof Ball && actorsIntersecting(enemy, ball)) {
ball.remove();
enemy.remove();
}
}
}
}

Sudoku solver Recurrence stack with try and fail technique

I am building a Sudoku solver that use the Try and Fail technique to solve any problem. My algorithm is:
1)Update (method that remove any possible value that already given as a final value to element in the same Row, column or squar)
2)Get the minimum element that has minimum number of possible values
3)start solve assuming the first possible value is the final value
4)save the current sate into a stack
5)Try to solve
5-a)If solved, return
5-b)if not solved and with invalid Sudoku, then Pop previous state
6)Repeat step 3) for all possible vaues (9)
7)Repeat step 2) until the puzzel is solved
This is my code
Stack<Element[][]> myStack= new Stack<>();
private Element[][] mySudoku;
public void solve(){
update();//remove all final values from all possible values for each element
if(isSudokuSolved(mySudoku)){
return;
}
//find a cell that is not confirmed and has the minimal candidates
int celli=-1,cellj=-1, p=10;
for(int i=0;i<9;i++){
for(int j=0;j<9;j++){
if(mySudoku[i][j].getValue()==0){
if(mySudoku[i][j].getPossibleValues().size()<p){
celli=i;
cellj=j;
p=mySudoku[i][j].getPossibleValues().size();
}
}
}
}
try {
for (int c = 0; c < mySudoku[celli][cellj].getPossibleValues().size() - 1; c++) {
//save state
Element[][] copy=deepCopy(mySudoku);//copy the current state
myStack.push(copy);
//apply candidate to cell
mySudoku[celli][cellj].setValue(mySudoku[celli][cellj].getPossibleValues().get(c));
update();//check is solved
if(checkValidInputSudoku(mySudoku)){
solve();
}else{
try {
mySudoku = myStack.pop();
} catch (EmptyStackException est) {
//do nothing
}
}
}
} catch (Exception e) {
}
//if we have reached here then we are at the last possible value for the candidates so confirm candidate in cell
if(celli!=-1 && cellj!=-1 && p!=10) {//Some problems happen here "out of Boundry -1 Error"
mySudoku[celli][cellj].setValue(mySudoku[celli][cellj].getPossibleValues().get(mySudoku[celli][cellj].getPossibleValues().size()-1));
}
}//end of solve method
I have spent more than 6 hours trying to find out the problem. I have checked for the Update() method, deepCopy() method and checkValidInputSudoku() method. They all works fine. Thank you in Advance
I can see one problem in your code. You have a loop that is sawing off the branch it sits on:
for(int c = 0; c < mySudoku[celli][cellj].getPossibleValues().size() - 1; c++) {
...
mySudoku[celli][cellj].setValue(mySudoku[celli]cellj].getPossibleValues().get(c));
...
}
Apart from that, you are missing one of the values, it should be for(c=0; c!=size; ++c), i.e. not size - 1. Also, calling getPossibleValues() just once would make this code much more readable. Lastly, catching and ignoring a stack underflow is just stupid, because it hides errors in your algorithm, as far as I can tell. If you don't know how to handle an error, don't just silence it. Since java requires you to catch it, put it in the outermost place possible or at least abort or do something, but don't ignore it!
One more thing: You are recursing and passing the context data via mySodoku and myStack. This is completely missing the point of recursion (or at least the way it's typically used), because the function call stack is the only stack you need. Using these to pass parameters only makes things more complicated than necessary. Instead, the function should return a partial sodoku puzzle and return either the fully solved puzzle or null. Using is easier to distinguish than the exception you're using now, and it's a regular and expected thing, not really exceptional. Then, when trying different choices, you set the cell to the values in turn and recurse, until the call doesn't return null. If none of the choices returns a solution, you clear the cell and return null yourself.
solve(sodoku):
if sodoku is solved:
return true
if sodoku is invalid:
return false
c = some empty cell
for v in 1...9:
// set to a value and recurse
c = v
if solve(sodoku):
// found a solution
return true
// no solution found, clear cell and return failure
c = null
return false
BTW: This strategy is called "backtracking". Using a cell with the least amount of possible values is called "pruning", which allows you to cut off whole branches from the search tree. Actually determining the possible values also helps avoiding a few futile attempts.

Another way to break a for loop with java?

is there any other way to break this loop without using the actual break statement?
the thing is for some reason my professor doesn't like that we use break in any other place that in the switch
i am having troubles in my method adding an object into the array of objects in the next empty space in the array
this is my code: (any other way to do it?)
public void add(Employee employeeObj)throws ArrayIndexOutOfBoundsException{
try{
for(int i= 0; i<MAX; i++){
if(listEmployee[i] == null){
listEmployee[i] = employeeObj;
break;
}
}
}catch(ArrayIndexOutOfBoundsException e){
throw new ArrayIndexOutOfBoundsException("ERROR!");
}
}
the method just need to add the employeObj into the array and if the case, thows an exception.
thanks for your help
try this:
for(int i= 0; i<MAX; i++){
if(listEmployee[i] == null){
listEmployee[i] = employeeObj;
i=MAX;
}
but I see no problem with using breaks. There will always be circumstances where you want to stop processing a loop, and using a break; makes much more sense (and makes it more readable!) than setting your loop counter up to a value that would make your loop stop at the next iteration.
You can simply do i = MAX or use a boolean flag if you don't have such a trivial situation.
As a personal note forbidding the usage of break outside switch statements doesn't make any sense.
Since your method is doing nothing else in this case, you can just use return instead of break:
public void add(Employee employeeObj)throws ArrayIndexOutOfBoundsException {
try{
for (int i= 0; i<MAX; i++) {
if (listEmployee[i] == null) {
listEmployee[i] = employeeObj;
return;
}
}
} catch(ArrayIndexOutOfBoundsException e) {
throw new ArrayIndexOutOfBoundsException("ERROR!");
}
}
But in general the other answers here are more applicable. That said, I would ask your professor to explain why break shouldn't be used - IMHO alternatives are often much less readable.
i am having troubles in my method adding an object into the array of objects in the next empty space in the array
I would suggest simply finding out the length of the array and inserting the object in the next location. No need to iterate the complete length of arrray.
public void add(Employee employeeObj){
int n = listEmployee.length;
listEmployee[n] = employeeObj;
}
}
Alternatively you could do it as
int i = Arrays.asList(listEmployee).indexOf(null);
if (i >= 0) {
listEmployee[i] = employeeObj;
}
note that Arrays.asList creates a view over array, not a new List

How can I remove the while(true) from my loop in Java?

I've heard that using while(true) is a bad programming practice.
So, I've written the following code to get some numbers from a user (with default values). However, if the user happens to type in -1, then it will quit the program for them.
How should this be written then without a while(true)? I can think of a condition to make the while loop go off that will get caught right away without continuing on until the next iteration?
Here is how I have it now:
public static void main(String[] args)
{
System.out.println("QuickSelect!");
while (true)
{
System.out.println("Enter \"-1\" to quit.");
int arraySize = 10;
System.out.print("Enter the size of the array (10): ");
String line = input.nextLine();
if (line.matches("\\d+"))
{
arraySize = Integer.valueOf(line);
}
if (arraySize == -1) break;
int k = 1;
System.out.print("Enter the kth smallest element you desire (1): ");
line = input.nextLine();
if (line.matches("\\d+"))
{
k = Integer.valueOf(k);
}
if (k == -1) break;
List<Integer> randomData = generateRandomData(arraySize, 1, 100);
quickSelect(randomData, k);
}
}
while (true) is fine. Keep it.
If you had a more natural termination condition, I'd say to use it, but in this case, as the other answers prove, getting rid of while (true) makes the code harder to understand.
There is a Single Entry Single Exit (SESE) school of thought that suggests that you should not use break, continue or abuse exceptions to do the same for some value of abuse). I believe the idea here is not that you should use some auxiliary flag variable, but to clearly state the postcondition of the loop. This makes it tractable to formerly reason about the loop. Obviously use the stands-to-reason form of reasoning, so it is unpopular with the unwashed masses (such as myself).
public static void main(String[] args) {
...
do {
...
if (arraySize == -1) {
...
if (k != -1) {
...
}
}
} while (arraySze == -1 || k == -1);
...
}
Real code would be more complex and you would naturally(!) separate out the inputing, outputting and core "business" logic, which would make it easier to see what is going on.
bool exit = false;
while (!exit) {
...
...
if (k == -1) {
exit = true;
}
else {
List <Integer> ....;
quickselect(.......);
}
}
But as has been said before, your while loop is a valid usage in this situation. The other options would simply build upon the if statements to check for the boolean and exit.
While having a loop like this is not technically wrong, some people will argue that it is not as readable as the following:
bool complete = false;
while (!complete)
{
if (arraySize == -1)
{
complete = true;
break;
}
}
Additionally, it is sometimes a good idea to have a safety loop counter that checks to make sure the loop has not gone through, say, 100 million iterations, or some number much larger than you would expect for the loop body. This is a secure way of making sure bugs don't cause your program to 'hang'. Instead, you can give the user a friendly "We're sorry but you've discovered a bug.. program will now quit.." where you set 'complete' to true and you end the program or do additional error handling. I've seen this in production code, and may or may not be something you would use.
while ( true ) is perfectly fine here, since the condition is really "while the user doesn't want to quit"!
Alternatively you could prompt for both the inputs on one line to simplify the logic, and use "q" for quit: this allows you to refactor the loop to "while ( !line.equals("q") )".
The problem is that you're doing an awful lot in that loop, rather than separating the functionality into simple methods.
If you want to stick to a procedural approach, you could move the reading of the array size and k into separate methods, and use the fact that the result of an assignment is the assigned value:
for (int arraySize; ( arraySize = readArraySize ( input ) ) != -1;) {
final int k = readKthSmallestElement ( input );
List<Integer> randomData = generateRandomData(arraySize, 1, 100);
quickSelect(randomData, k);
}
However that's still a bit ugly, and not well encapsulated. So instead of having the two != -1 tests on separate variables, encapsulate arraySize, k and randomData in an object, and create a method which reads the data from the input, and returns either a QuickSelect object or null if the user quits:
for ( QuickSelect select; ( select = readQuickSelect ( input ) ) != null; ) {
select.generateRandomData();
select.quickSelect();
}
You might even want to go to the next stage of creating a sequence of QuickSelect objects from the input, each of which encapsulate the data for one iteration:
for ( QuickSelect select : new QuickSelectReader ( input ) ) {
select.generateRandomData();
select.quickSelect();
}
where QuickSelectReader implements Iterable and the iterator has the logic to create a QuickSelect object which encapsulates arraySize, k, the list and the quick select operation. But that ends up being quite a lot more code than the procedural variants.
I'd only do that if I wanted to reuse it somewhere else; it's not worth the effort just to make main() pretty.
Also note that "-1" doesn't match the regex "\\d+", so you really do have an infinite loop.
If you really don't like while(true) you can always go for for(;;). I prefer the latter because it seems less redundant.

Categories

Resources