I want to find a path to goal from start node using iterative depth first search using this maze represented in graph. It is a text file containing only pair of numbers like a pairwise connection a.k.a edges/arcs. Like this:
11 3
2 3
0 3
1 4
5 4
5 7
6 7
7 8
8 9
9 10
0 5
Then my code is like this:
private void performIterativeDFS(MazeGraph G, int node, int goal) {
ArrayBasedStack arrayStack = new ArrayBasedStack();
ArrayBasedStack pathStack = new ArrayBasedStack();
arrayStack.push(node);
visited[node] = true;
while (!arrayStack.isEmpty()) {
int newNode = arrayStack.pop();
if (newNode == 0) {
out.print("Starting at " + newNode + " ");
}
pathStack.push(newNode);
if (newNode == goal) {
out.println("Path if goal found: " + pathStack.toString());
}
for (int arc : G.getAdjacencyList(newNode)) {
if (!visited[arc]) {
visited[arc] = true;
arrayStack.push(arc);
}
}
}
}
I have input 0 as a starting node and goal node is 1. Then the path that output is 0,5,7,8,9,10,6,4,1. Unfortunately, that's not like a proper solution where you can go 0,5,4,1 instead. Does iterative depth first search randomly selects which nodes to go next before reaching the goal?
I tried modifying my code to do that but I can't make the path to print like 0,5,4,1. I want to keep it simple as possible so it is for everyone to understand. Any suggestions or advice?
You won't get a different answer from your search without changing your algorithm(which would not make it a dfs) or (map which would be a waste of time if you were trying to make it for anything besides this specific data set). you could try implementing a sort of backtrace after the code has found a path to reduces the number of nodes traversed, but that wouldn't be the simple answer you're looking for.
Short answer: no, that's not really how DFS works.
EDIT: missed a bit of your question, there's nothing in your code that makes it random. if, rather than
for (int arc : G.getAdjacencyList(newNode)) {
if (!visited[arc]) {
visited[arc] = true;
arrayStack.push(arc);
}
you randomly sampled G, then you would have a chance of getting the a different outcome, but as it is there is no random element to it.
Related
I know that lowkey it does 1 + 2 + 3 + 4 = 10, but I want to know how exactly it does that
public class Main {
public static int sum(int n) {
if(n == 0) return 0;
return sum(n - 1) + n;
}
public static void main(String[] args) {
System.out.println(sum(4));
}//main
}//class
public static int sum(int n) {
if(n == 0) return 0;
return sum(n - 1) + n;
}
When you call sum(4), the compiler does the following steps:
sum(4) = sum(3) + 4, sum(3) then calls sum(int n) and go to next step
sum(3) = sum(2) + 3, sum(2) then calls sum(int n) and go to next step
sum(2) = sum(1) + 2, sum(1) then calls sum(int n) and go to next step
sum(1) = sum(0) + 1, sum(0) then calls sum(int n) and go to next step
sum(0) = 0, return the value and bring it to previous step.
Then with backtracking, the compiler brings the value of sum(0) to the formula sum(0) + 1, so the value of sum(1) is 1. And so on, finally we get sum(4) is 10.
The key to understanding how this recursion work is the ability to see what is happening at each recursive step. Consider a call sum(4):
return
sum(3) + 4
sum(2) + 3
sum(1) + 2
sum(0) + 1
return 0 in next recursive call
It should be clear how a sum of 10 is obtained for sum(4), and may generalize to any other input.
Okay so lets understand it :
you call the method from main method passing the argument as 4.
It goes to method , the very first thing it checks is called as base condition in recursion . Here base condition is if n == 0 return 0.
We skipped the base condition since n is not yet zero . we go to return sum(n-1)+n that is sum(4-1)+4 . So addition will not happen , because you made the recursive call again to sum method by decrementing the n value to n-1 , in this case it is 3.
You again entered the method with n =3, check the base condition which is not valid since 3 != 0 , so we go to return sum (n-1)+3 , which is sum(3-1)+3
Next recursive call where n = 2 , base condition is not valid 2!=0 , so we return sum(n-1)+2that is sum(2-1)+2.
Next call with n = 1 , base condition is not valid , we go to return sum(n-1)+1 that is sum(1-1)+1.
Next recursive call with n = 0 , so now base condition is met , means it is time to stop the recursion and keep going back to from where we came to get the desired result. So this time we returned 0.
Lets go back to step 6 , with 0 we got and compute the addition part of sum(1-1)+1 . You got sum(1-1) => sum(0) = . So sum(1-1)+1 will be equal to 0+1=1
One more step back with 1 as value to step 5 , where we have sum(2-1)+2 = sum(1)+2 , sum(1) you know , which is 1 , so we will return 1+2=3 from this recursive call.
One step back with value as 3 , to step 4 , sum(3-1)+3 = sum (2)+3 = 3+3 =6 .
Going one step back with 6 as value to step 3 , sum(4-1)+4 = sum(3)+4 = 6+4 = 10 . And that is where we started from . You got the result as 10.
Recursion itself is very easy to understand.
From a mathematical point of view, it is just a simple function call, such as your code:
public static int sum(int n) {
if(n == 0) return 0;
return sum(n - 1) + n;
}
/*
sum(0) = 0
sum(1) = 1
sum(n) = n + sum(n-1)
*/
In fact, the concept of recursion has been introduced in high school. It is the "mathematical construction method" that is often used to prove sequence problems. The characteristics are obvious: the structure is simple and the proof is crude. As long as you build the framework, you can prove it in conclusion. So what is a recursive "simple structure" framework?
Initial conditions: sum(0) = 0
Recursive expression: sum(n) = sum(n-1) + n
And in fact about the sum() function, every calculation starts from sum(0), and it is natural. Even if you are asked to calculate sum(1000), all you need is paper, pen, and time, so recursion itself is not difficult.
So why recursion give people an incomprehensible impression? That's because "recursive realization" is difficult to understand, especially using computer language to realize recursion. Because the realization is the reverse, not to let you push from the initial conditions, but to push back to the initial conditions, and the initial conditions become the exit conditions.
In order to be able to reverse the calculation, the computer must use the stack to store the data generated during the entire recursion process, so writing recursion will encounter stack overflow problems. In order to achieve recursion, the human brain has to simulate the entire recursive process. Unfortunately, the human brain has limited storage, and two-parameter three-layer recursion can basically make you overflow.
Therefore, the most direct way is to use paper to record the stacks in your head. It is very mechanically painful and takes patience, but problems can often be found in the process.
Or, go back to the definition of recursion itself.
First write the architecture and then fill it in. Define the exit conditions and define the expression.
Second implement the code strictly according to the architecture. Recursive code is generally simple enough, so it is not easy to make mistakes in implementation. Once there is a problem with the program result, the first should not be to check the code, but to check your own definition.
Meeting Infinite loop? The initial conditions are wrong or missing; wrong result? There is a problem with recursion. Find out the problem, and then change the code according to the new architecture. Don't implement it without clearly defining the problem.
Of course, it really doesn't work. There is only one last resort: paper and pen.
So my code works for basic 8 Puzzle problems, but when I test it with harder puzzle configurations it runs into an infinite loop. Can someone please edit my code to prevent this from happening. Note that I have included code that prevents the loops or cycles. I tried including the the iterative depth first search technique, but that too did not work. Can someone please review my code.
/** Implementation for the Depth first search algorithm */
static boolean depthFirstSearch(String start, String out ){
LinkedList<String> open = new LinkedList<String>();
open.add(start);
Set<String> visitedStates = new HashSet<String>(); // to prevent the cyle or loop
LinkedList<String> closed = new LinkedList<String>();
boolean isGoalState= false;
while((!open.isEmpty()) && (isGoalState != true) ){
String x = open.removeFirst();
System.out.println(printPuzzle(x)+"\n\n");
jtr.append(printPuzzle(x) +"\n\n");
if(x.equals(out)){ // if x is the goal
isGoalState = true;
break;
}
else{
// generate children of x
LinkedList<String> children = getChildren(x);
closed.add(x); // put x on closed
open.remove(x); // since x is now in closed, take it out from open
//eliminate the children of X if its on open or closed ?
for(int i=0; i< children.size(); i++){
if(open.contains(children.get(i))){
children.remove(children.get(i));
}
else if(closed.contains(children.get(i))){
children.remove(children.get(i));
}
}
// put remaining children on left end of open
for(int i= children.size()-1 ; i>=0 ; i--){
if ( !visitedStates.contains(children.get(i))) { // check if state already visited
open.addFirst(children.get(i)); // add last child first, and so on
visitedStates.add(children.get(i));
}
}
}
}
return true;
}
I would suggest putting the positions that you are considering into a https://docs.oracle.com/javase/7/docs/api/java/util/PriorityQueue.html with a priority based on how close they are to being solved.
So what you do is take the closest position off of the queue, and add in all of the one move options from there that haven't yet been processed. Then repeat. You'll spent most of your time exploring possibilities that are close to solved instead of just moving randomly forever.
Now your question is "how close are we to solving it". One approach is to take the sum of all of the taxicab distances between where squares are and where they need to be. A better heuristic may be to give more weight to getting squares away from the corner in place first. If you get it right, changing your heuristic should be easy.
I'm trying to create a program that reads a sudoku board from a txt file and finds possible solution(s) to the board.
I've created objects of each square and added them to a 2d-array:
(This board have 28 different solutions)
001003
000000
000020
260000
000300
300102
I have successfully added the squares to corresponding column, row and box. But I'm having trouble with my recursive method that tries to find possible solution(s) of the board and add each solutions to a container in a different class that uses nodes to keep track of all the solutions. The method in my container class should take Square[][] squares as parameters.
I start the recursive method off with:
squares[0][0].fillInRemainingOfBoard();
from another class called Board.
My recursive method that is supposed to check all the squares looks like this:
protected void fillInRemainingOfBoard() {
// If Square is not '0' in the txt file it goes in here
if(this instanceof SquareDone) {
// If next != null it goes in here.
if(next != null) {
next.fillInRemainingOfBoard();
}
// If the square is empty it goes in here
} else if(this instanceof SquareEmpty) {
if(next != null) {
// Searching for possible numbers for square
// Rows, Column and Box have the same length;
//thats why row.getLength() in for-loop
for(int i=1; i<=row.getLength(); i++) {
// Set new value to square if this is true,
// then move on to next square
if(row.getLegal(i) && column.getLegal(i) && box.getLegal(i)) {
setNewValue(i);
next.fillInRemainingOfBoard();
}
}
} else {
for(int i=1; i<=row.get(); i++) {
if(row.getLegal(i) && column.getLegal(i) && box.getLegal(i)) {
setNewValue(i);
// No next.fillInRemainingOfBoard() here because it's the last square
}
}
}
}
}
I have a super-class for the rows, columns and boxes which holds the variables and methods for the subclasses. The method that checks for legal values looks like this:
public boolean getLegal(int square) {
for(int i=0; i<rkb.length; i++) {
if(rute == rkb[i].getVerdi()) {
return false;
}
}
return true;
}
My output of this looks like this
4 2 1 5 6 3
5 3 6 2 1 4
1 4 3 6 2 5
2 6 5 4 3 1
6 1 4 3 5 0
3 0 0 1 0 2
So my question is: Why is my code not adding values to each square and how can I save a solution and send them to another class, then start over and check for more solutions?
The reason why its not adding value to each square, is because the algorithm is incorrect. As you can see from position [5][4] of your array, value by line 2 and value by column should be 6. Meaning the algorithm messed up previous values and cannot find further ones.
I suspect this happens because in part of your code bellow, setNewValue(i) is set for the last solution found, but the if statement may find multiple solutions in the beginning of the program, as not many squares are filled, and not always the last solution is the good one.
if(next != null) {
for(int i=1; i<=row.getLength(); i++) {
if(row.getLegal(i) && column.getLegal(i) && box.getLegal(i)) {
setNewValue(i);
next.fillInRemainingOfBoard();
}
}
To solve this, you should store all values that match the if statement and figure out how to use them later. (maybe skip the current cell if it has more then 1 solution and come back to it later)
This is just my hypothesis, but you can use a debugger to see if this is truly the problem
Here is a fast implementation of Sudoku Solver which I implemented a couple of years back.
https://gist.github.com/dapurv5/e636c85a5a85cd848ca2
You might want to read about Minimum Remaining Value heuristic. This is one of the standard ways to solve a CSP (Constraint Satisfaction Problem)
I'm looking into depth first search and the examples I found are looking for a particular answer, lets say the number 10.
It goes through the tree discarding every node that isn't 10 and stop when it finds 10.
Is it possible to use depth first search or another algorithm to search every branch of the tree? I would like it to run a scenario and come up with a value and store that into a variable possibly named highestValue.
It would then search the next branch and get a value and store that into a variable possibly named Value. Then it would compare highestValue to Value and if (Value > highestValue) highestValue = Value.
It would repeat the process until it is finished running every possible scenario. Any ideas? I should mention I'm writing this in Java.
DFS is easiest if we want to visit every node in the graph. However, if we have a very large tree and want to be prepared to quit when we get too far from the original node, DFS can search thousands of ancestors of the node but never search all of the nodes children.
Strictly speaking, it depends on how the data in your graph is organize. Source
Since you're still wondering how it might work, this piece of code might help you figure that out. This works for graphs, take a look. It DFSes every node, but stops when it reaches the node we want to find.
To get the highest value, just store the max value into an int variable, and continue searching and comparing each node's data to the current max inside the int variable.
public static boolean search(Graph g, Node start, Node end) {
LinkedList<Node> stack = new LinkedList<Node>();
for (Node u : g.getNodes()) {
u.state = State.Unvisited;
}
start.state = State.Visiting;
stack.add(start);
Node u;
while (!stack.isEmpty()) {
u = stack.removeFirst();
if (u != null) {
for ( Node v : u.getAdjacent() ) {
if (v.state == State.Unvisited) {
if (v == end) {
return true;
}
else {
v.state = State.Visiting;
stack.add(v);
}
}
}
u.state = State.Visited;
}
}
return false;
}
I am programming an AI for a chess-like game, based on two types of pieces on a 8 x 8 grid.
I want to build a kind of minmax tree, which represents each possible move in a game, played by white players in first, and by black players in second.
I have this generate() method which is call recursively. I need to be able to display about 8 levels of possible moves. Without optimization, this three has 8^8 leafs.
I implemented a simple system which determinate if a grid has actually ever been calculated and if its the case, system just points a child to the ever-calculated child reference.
I don't know if my explanations are clear, I will join a part of code that you should be able to understand.
The problem is that actually, I am able to generate about 3 or 4 levels of all possibilities. I am far of 8.
I would like to be able to calculate it in less than 5 seconds..
So guys, do you see a solution for optimize my algorithm ?
This is the generate function:
leftDiagonalMove(), rightDiagonalMove() and frontMove() return false if a move is illegal or move the piece in the grid and return true, if the move is legal.
clone() creates a new instance with the same properties of it's "parent" and backMove() just step back to last Move.
public void generate(Node root, boolean white, int index) {
Grid grid = root.getGrid();
Stack<Piece> whitePieces = grid.getPiecesByColor(WHITE);
Stack<Piece> blackPieces = grid.getPiecesByColor(BLACK);
Node node;
String serial = "";
// white loop
for (int i = 0; i < whitePieces.size() && white; i++) {
Piece wPiece = whitePieces.get(i);
if (grid.leftDiagonalMove(wPiece)) {
serial = grid.getSerial();
if(!allGrids.containsKey(serial)){
node = new Node(grid.clone());
node.setMove(grid.getLastMove());
root.addChild(node); // add modified grid
allGrids.put(serial, node);
//actualGrid.display();
if (index < 5 && grid.getPosition(wPiece).x > 0)
generate(node, !white, index + 1);
actualGrid.backMove(); // back step to initial grid
}
else{
root.addChild(allGrids.get(serial));
}
}
if (grid.frontMove(wPiece)) {
// same code as leftMove
}
if (grid.rightDiagonalMove(wPiece)) {
// same code as leftMove
}
}
// black loop
for (int i = 0; i < blackPieces.size() && !white; i++) {
Piece bPiece = blackPieces.get(i);
if (grid.leftDiagonalMove(bPiece)) {
// same code as white loop and replacing wPiece by bPiece
}
if (grid.frontMove(bPiece)) {
// same code as white loop and replacing wPiece by bPiece
}
if (grid.rightDiagonalMove(bPiece)) {
// same code as white loop and replacing wPiece by bPiece
}
}
}
You need to use something called AlphaBeta pruning on your generated MinMax trees of moves. More on this here:
http://en.wikipedia.org/wiki/Alpha-beta_pruning
http://www.progtools.org/games/tutorials/ai_contest/minmax_contest.pdf
Basically you do one level of branches and then using pruning you eliminate bad branches early. Then from the non eliminated branches you calculate (for each) another level. You prune again until you reach a desired depth.
Here are a few more links for you to read up on minmax:
1. http://en.wikipedia.org/wiki/Minimax
2. MinMax trees - when Min can win in two steps
This one is on optimizing pruning for chess games:
1. http://en.wikipedia.org/wiki/Alpha-beta_pruning#Heuristic_improvements
2. http://en.wikipedia.org/wiki/Refutation_table#Related_techniques
I don't understand why you are using Stacks when you are doing random access to the elements. A a low level you would get an improvement by using a Piece[] array instead.