Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8753697
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 13, 20262026-06-13T13:28:33+00:00 2026-06-13T13:28:33+00:00

I am looking for a solution to 8-puzzle problem using the A* Algorithm .

  • 0

I am looking for a solution to 8-puzzle problem using the A* Algorithm. I found this project on the internet. Please see the files – proj1 and EightPuzzle. The proj1 contains the entry point for the program(the main() function) and EightPuzzle describes a particular state of the puzzle. Each state is an object of the 8-puzzle.
I feel that there is nothing wrong in the logic. But it loops forever for these two inputs that I have tried : {8,2,7,5,1,6,3,0,4} and {3,1,6,8,4,5,7,2,0}. Both of them are valid input states. What is wrong with the code?


Note

  • For better viewing copy the code in a Notepad++ or some other text
    editor(which has the capability to recognize java source file)
    because there are lot of comments in the code.
  • Since A* requires a heuristic, they have provided the option of using
    manhattan distance and a heuristic that calculates the number of
    misplaced tiles. And to ensure that the best heuristic is executed
    first, they have implemented a PriorityQueue. The compareTo()
    function is implemented in the EightPuzzle class.
  • The input to the program can be changed by changing the value of p1d in the main() function of proj1 class.
  • The reason I am telling that there exists solution for the two my above inputs is because the applet here solves them. Please ensure that you select 8-puzzle from the options in the applet.

    EDIT1
    I gave this input {0,5,7,6,8,1,2,4,3}. It took about 10 seconds and gave a result with 26 moves. But the applet gave a result with 24 moves in 0.0001 seconds with A*.

    EDIT2
    While debugging I noticed that as nodes are expanded, the new nodes, after sometime, all have a heuristic – f_n as 11 or 12. They never seem to decrease. So after sometime all the states in the PriorityQueue(openset) have a heuristic of 11 or 12. So there is not much to choose from, to which node to expand. As the least is 11 and the highest is 12. Is this normal?

    EDIT3
    This is the snippet(in proj1-astar()) where the infinite looping happening. openset is the PriorityQueue containing unexpanded nodes and closedset is the LinkedList containing expanded nodes.

while(openset.size() > 0){

                    EightPuzzle x = openset.peek();


                    if(x.mapEquals(goal))
                    {

                             Stack<EightPuzzle> toDisplay = reconstruct(x);
                             System.out.println("Printing solution... ");
                             System.out.println(start.toString());
                             print(toDisplay);
                             return;
                             
                    }          
                    closedset.add(openset.poll());
                    LinkedList <EightPuzzle> neighbor = x.getChildren();              
                    while(neighbor.size() > 0)
                    {
                            EightPuzzle y = neighbor.removeFirst();
                            if(closedset.contains(y)){
                                    continue;
                            }          
                            if(!closedset.contains(y)){
                                    openset.add(y);
                            }              
                    }
               
            }


EDIT4

I have got the cause of this infinite loop. See my answer. But it takes about 25-30 seconds to execute, which is quite a long time. A* should do much faster than this. the applet does this in 0.003 seconds. I will award the bounty for improving the performance.


For quick reference I have pasted the the two classes without the comments :

EightPuzzle

 import java.util.*;
    
    public class EightPuzzle implements Comparable <Object> {
           
           
            int[] puzzle = new int[9];
            int h_n= 0;
            int hueristic_type = 0;
            int g_n = 0;
            int f_n = 0;
            EightPuzzle parent = null;
    
           
            public EightPuzzle(int[] p, int h_type, int cost)
            {
                    this.puzzle = p;
                    this.hueristic_type = h_type;
                    this.h_n = (h_type == 1) ?  h1(p) : h2(p);
                    this.g_n = cost;
                    this.f_n = h_n + g_n;
            }
            public int getF_n()
            {
                    return f_n;
            }
            public void setParent(EightPuzzle input)
            {
                    this.parent = input;
            }
            public EightPuzzle getParent()
            {
                    return this.parent;
            }
    
            public int inversions()
            {
                    /*
                     * Definition: For any other configuration besides the goal,
                     * whenever a tile with a greater number on it precedes a
                     * tile with a smaller number, the two tiles are said to be inverted
                     */
                    int inversion = 0;
                    for(int i = 0; i < this.puzzle.length; i++ )
                    {
                            for(int j = 0; j < i; j++)
                            {
                                    if(this.puzzle[i] != 0 && this.puzzle[j] != 0)
                                    {
                                    if(this.puzzle[i] < this.puzzle[j])
                                            inversion++;
                                    }
                            }
    
                    }
                    return inversion;
                   
            }
            public int h1(int[] list)
            // h1 = the number of misplaced tiles
            {
                    int gn = 0;
                    for(int i = 0; i < list.length; i++)
                    {
                            if(list[i] != i && list[i] != 0)
                                    gn++;
                    }
                    return gn;
            }
            public LinkedList<EightPuzzle> getChildren()
            {
                    LinkedList<EightPuzzle> children = new LinkedList<EightPuzzle>();
                    int loc = 0;
            int temparray[] = new int[this.puzzle.length];
            EightPuzzle rightP, upP, downP, leftP;
                    while(this.puzzle[loc] != 0)
                    {
                            loc++;
                    }
                    if(loc % 3 == 0){
                            temparray = this.puzzle.clone();
                            temparray[loc] = temparray[loc + 1];
                            temparray[loc + 1] = 0;
                            rightP = new EightPuzzle(temparray, this.hueristic_type, this.g_n + 1);
                            rightP.setParent(this);
                            children.add(rightP);
    
                    }else if(loc % 3 == 1){
                    //add one child swaps with right
                            temparray = this.puzzle.clone();
                            temparray[loc] = temparray[loc + 1];
                            temparray[loc + 1] = 0;
                           
                            rightP = new EightPuzzle(temparray, this.hueristic_type, this.g_n + 1);
                            rightP.setParent(this);
                            children.add(rightP);
                            //add one child swaps with left
                            temparray = this.puzzle.clone();
                            temparray[loc] = temparray[loc - 1];
                            temparray[loc - 1] = 0;
                           
                            leftP = new EightPuzzle(temparray, this.hueristic_type, this.g_n + 1);
                            leftP.setParent(this);
                            children.add(leftP);
                    }else if(loc % 3 == 2){
                    // add one child swaps with left
                            temparray = this.puzzle.clone();
                            temparray[loc] = temparray[loc - 1];
                            temparray[loc - 1] = 0;
                           
                            leftP = new EightPuzzle(temparray, this.hueristic_type, this.g_n + 1);
                            leftP.setParent(this);
                            children.add(leftP);
                    }              
                   
                    if(loc / 3 == 0){
                    //add one child swaps with lower
                            temparray = this.puzzle.clone();
                            temparray[loc] = temparray[loc + 3];
                            temparray[loc + 3] = 0;
                           
                            downP = new EightPuzzle(temparray, this.hueristic_type, this.g_n + 1);
    
                            downP.setParent(this);
    
                            children.add(downP);
                   
                           
                    }else if(loc / 3 == 1 ){
                            //add one child, swap with upper
                            temparray = this.puzzle.clone();
                            temparray[loc] = temparray[loc - 3];
                            temparray[loc - 3] = 0;
                           
                            upP = new EightPuzzle(temparray, this.hueristic_type, this.g_n + 1);
                            upP.setParent(this);
    
                            children.add(upP);
                            //add one child, swap with lower
                            temparray = this.puzzle.clone();
                            temparray[loc] = temparray[loc + 3];
                            temparray[loc + 3] = 0;
                           
                            downP = new EightPuzzle(temparray, this.hueristic_type, this.g_n + 1);
                            downP.setParent(this);
    
                            children.add(downP);
                    }else if (loc / 3 == 2 ){
                            //add one child, swap with upper
                            temparray = this.puzzle.clone();
                            temparray[loc] = temparray[loc - 3];
                            temparray[loc - 3] = 0;
                           
                            upP = new EightPuzzle(temparray, this.hueristic_type, this.g_n + 1);
                            upP.setParent(this);
    
                            children.add(upP);
                    }
    
                    return children;
            }
            public int h2(int[] list)
            // h2 = the sum of the distances of the tiles from their goal positions
            // for each item find its goal position
            // calculate how many positions it needs to move to get into that position
            {
                    int gn = 0;
                    int row = 0;
                    int col = 0;
                    for(int i = 0; i < list.length; i++)
                    {
                            if(list[i] != 0)
                            {
                                    row = list[i] / 3;
                                    col = list[i] % 3;
                                    row = Math.abs(row - (i / 3));
                                    col = Math.abs(col - (i % 3));
                                    gn += row;
                                    gn += col;
                            }
                           
                    }
                    return gn;
            }
    
            public String toString()
            {
                    String x = "";
                    for(int i = 0; i < this.puzzle.length; i++){
                            x += puzzle[i] + " ";
                            if((i + 1) % 3 == 0)
                                    x += "\n";
                    }
                    return x;
            }
            public int compareTo(Object input) {
                   
                   
                    if (this.f_n < ((EightPuzzle) input).getF_n())
                            return -1;
                    else if (this.f_n > ((EightPuzzle) input).getF_n())
                            return 1;
                    return 0;
            }
           
            public boolean equals(EightPuzzle test){
                    if(this.f_n != test.getF_n())
                            return false;
                    for(int i = 0 ; i < this.puzzle.length; i++)
                    {
                            if(this.puzzle[i] != test.puzzle[i])
                                    return false;
                    }
                    return true;
            }
            public boolean mapEquals(EightPuzzle test){
                    for(int i = 0 ; i < this.puzzle.length; i++)
                    {
                            if(this.puzzle[i] != test.puzzle[i])
                                    return false;
                    }
                    return true;
            }
    
    }

proj1

import java.util.*;

public class proj1 {

        /**
         * @param args
         */
       
        public static void main(String[] args) {
               
               
                int[] p1d = {1, 4, 2, 3, 0, 5, 6, 7, 8};
                int hueristic = 2;
                EightPuzzle start = new EightPuzzle(p1d, hueristic, 0);
                int[] win = { 0, 1, 2,
                                          3, 4, 5,
                                          6, 7, 8};
                EightPuzzle goal = new EightPuzzle(win, hueristic, 0);
               
                astar(start, goal);

               

        }
       
        public static void astar(EightPuzzle start, EightPuzzle goal)
        {
                if(start.inversions() % 2 == 1)
                {
                        System.out.println("Unsolvable");
                        return;
                }
//              function A*(start,goal)
//           closedset := the empty set                 // The set of nodes already evaluated.
                LinkedList<EightPuzzle> closedset = new LinkedList<EightPuzzle>();
//           openset := set containing the initial node // The set of tentative nodes to be evaluated. priority queue
                PriorityQueue<EightPuzzle> openset = new PriorityQueue<EightPuzzle>();

                openset.add(start);
               

                while(openset.size() > 0){
//               x := the node in openset having the lowest f_score[] value
                        EightPuzzle x = openset.peek();

//               if x = goal
                        if(x.mapEquals(goal))
                        {
//                   return reconstruct_path(came_from, came_from[goal])
                                 Stack<EightPuzzle> toDisplay = reconstruct(x);
                                 System.out.println("Printing solution... ");
                                 System.out.println(start.toString());
                                 print(toDisplay);
                                 return;
                                 
                        }
//               remove x from openset
//               add x to closedset
                        closedset.add(openset.poll());
                        LinkedList <EightPuzzle> neighbor = x.getChildren();
//               foreach y in neighbor_nodes(x)                
                        while(neighbor.size() > 0)
                        {
                                EightPuzzle y = neighbor.removeFirst();
//                   if y in closedset
                                if(closedset.contains(y)){
//                       continue
                                        continue;
                                }
//                   tentative_g_score := g_score[x] + dist_between(x,y)
//      
//                   if y not in openset
                                if(!closedset.contains(y)){
//                       add y to openset
                                        openset.add(y);
//                      
                                }
//                 
                        }
//               
                }
        }

        public static void print(Stack<EightPuzzle> x)
        {
                while(!x.isEmpty())
                {
                        EightPuzzle temp = x.pop();
                        System.out.println(temp.toString());
                }
        }

        public static Stack<EightPuzzle> reconstruct(EightPuzzle winner)
        {
                Stack<EightPuzzle> correctOutput = new Stack<EightPuzzle>();
               
                while(winner.getParent() != null)
                {
                correctOutput.add(winner);
                winner = winner.getParent();
                }

                return correctOutput;
        }
       
        }
   
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-13T13:28:34+00:00Added an answer on June 13, 2026 at 1:28 pm

    Here is a proposal. My timer reports 0 ms for your example. On the harder puzzle given here, which needs 31 moves to complete, it takes 96 ms.

    A HashSet makes much more sense for the closed set than your linked list. It has O(1) time insert and membership test, where your linked list requires time proportional to the length of the list, which is constantly growing.

    You are using extra data structures and code that make your program more complex and slower than needed. Think more, code less, and study others’ good code to overcome this. Mine is not perfect (no code ever is), but it’s a place to start.

    I used as the heuristic the max of Manhattan distances from each tile’s currrent position to its goal. The choice of heuristic does not affect the number of steps in the solution, but it will affect run time enormously. For example, h=0 will produce brute force breadth first search.

    Note that for A* to provide an optimal solution, the heuristic can never over-estimate the actual minimum number of steps to the goal. If it does so, the solution is finds might not be the shortest possible. I’m not positive the “inversions” hueristic has this property.

    package eightpuzzle;
    
    import java.util.Arrays;
    import java.util.Comparator;
    import java.util.HashSet;
    import java.util.PriorityQueue;
    
    public class EightPuzzle {
    
        // Tiles for successfully completed puzzle.
        static final byte [] goalTiles = { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
    
        // A* priority queue.
        final PriorityQueue <State> queue = new PriorityQueue<State>(100, new Comparator<State>() {
            @Override
            public int compare(State a, State b) { 
                return a.priority() - b.priority();
            }
        });
    
        // The closed state set.
        final HashSet <State> closed = new HashSet <State>();
    
        // State of the puzzle including its priority and chain to start state.
        class State {
            final byte [] tiles;    // Tiles left to right, top to bottom.
            final int spaceIndex;   // Index of space (zero) in tiles  
            final int g;            // Number of moves from start.
            final int h;            // Heuristic value (difference from goal)
            final State prev;       // Previous state in solution chain.
    
            // A* priority function (often called F in books).
            int priority() {
                return g + h;
            }
    
            // Build a start state.
            State(byte [] initial) {
                tiles = initial;
                spaceIndex = index(tiles, 0);
                g = 0;
                h = heuristic(tiles);
                prev = null;
            }
    
            // Build a successor to prev by sliding tile from given index.
            State(State prev, int slideFromIndex) {
                tiles = Arrays.copyOf(prev.tiles, prev.tiles.length);
                tiles[prev.spaceIndex] = tiles[slideFromIndex];
                tiles[slideFromIndex] = 0;
                spaceIndex = slideFromIndex;
                g = prev.g + 1;
                h = heuristic(tiles);
                this.prev = prev;
            }
    
            // Return true iif this is the goal state.
            boolean isGoal() {
                return Arrays.equals(tiles, goalTiles);
            }
    
            // Successor states due to south, north, west, and east moves.
            State moveS() { return spaceIndex > 2 ? new State(this, spaceIndex - 3) : null; }       
            State moveN() { return spaceIndex < 6 ? new State(this, spaceIndex + 3) : null; }       
            State moveE() { return spaceIndex % 3 > 0 ? new State(this, spaceIndex - 1) : null; }       
            State moveW() { return spaceIndex % 3 < 2 ? new State(this, spaceIndex + 1) : null; }
    
            // Print this state.
            void print() {
                System.out.println("p = " + priority() + " = g+h = " + g + "+" + h);
                for (int i = 0; i < 9; i += 3)
                    System.out.println(tiles[i] + " " + tiles[i+1] + " " + tiles[i+2]);
            }
    
            // Print the solution chain with start state first.
            void printAll() {
                if (prev != null) prev.printAll();
                System.out.println();
                print();
            }
    
            @Override
            public boolean equals(Object obj) {
                if (obj instanceof State) {
                    State other = (State)obj;
                    return Arrays.equals(tiles, other.tiles);
                }
                return false;
            }
    
            @Override
            public int hashCode() {
                return Arrays.hashCode(tiles);
            }
        }
    
        // Add a valid (non-null and not closed) successor to the A* queue.
        void addSuccessor(State successor) {
            if (successor != null && !closed.contains(successor)) 
                queue.add(successor);
        }
    
        // Run the solver.
        void solve(byte [] initial) {
    
            queue.clear();
            closed.clear();
    
            // Click the stopwatch.
            long start = System.currentTimeMillis();
    
            // Add initial state to queue.
            queue.add(new State(initial));
    
            while (!queue.isEmpty()) {
    
                // Get the lowest priority state.
                State state = queue.poll();
    
                // If it's the goal, we're done.
                if (state.isGoal()) {
                    long elapsed = System.currentTimeMillis() - start;
                    state.printAll();
                    System.out.println("elapsed (ms) = " + elapsed);
                    return;
                }
    
                // Make sure we don't revisit this state.
                closed.add(state);
    
                // Add successors to the queue.
                addSuccessor(state.moveS());
                addSuccessor(state.moveN());
                addSuccessor(state.moveW());
                addSuccessor(state.moveE());
            }
        }
    
        // Return the index of val in given byte array or -1 if none found.
        static int index(byte [] a, int val) {
            for (int i = 0; i < a.length; i++)
                if (a[i] == val) return i;
            return -1;
        }
    
        // Return the Manhatten distance between tiles with indices a and b.
        static int manhattanDistance(int a, int b) {
            return Math.abs(a / 3 - b / 3) + Math.abs(a % 3 - b % 3);
        }
    
        // For our A* heuristic, we just use max of Manhatten distances of all tiles.
        static int heuristic(byte [] tiles) {
            int h = 0;
            for (int i = 0; i < tiles.length; i++)
                if (tiles[i] != 0)
                    h = Math.max(h, manhattanDistance(i, tiles[i]));
            return h;
        }
    
        public static void main(String[] args) {
    
            // This is a harder puzzle than the SO example
            byte [] initial = { 8, 0, 6, 5, 4, 7, 2, 3, 1 };
    
            // This is taken from the SO example.
            //byte [] initial = { 1, 4, 2, 3, 0, 5, 6, 7, 8 };
    
            new EightPuzzle().solve(initial);
        }
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm looking for solution to extract some node from large xml file (using xmlstarlet
I'm looking for solution to get time to click on element using implicitlyWait in
I'm looking for solution for a in memory script cache, using Zend_Cache and zend
I am trying to create a decent looking solution for a problem I have.
Im looking for solution how can I upload some file using http request. I
Looking for solution to extract content from a PDF file (using console tool or
I have been looking for a solution but I don't think this is possible
Edit: I'm looking for solution for this question now also with other programming languages.
Possible Duplicate: Algorithm to compare two images I am looking for solution to find
I am looking at solution for the set bit count problem (given a binary

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.