Problems with with A* algorithm

Posted by V_Programmer on Stack Overflow See other posts from Stack Overflow or by V_Programmer
Published on 2014-08-25T15:17:43Z Indexed on 2014/08/25 16:20 UTC
Read the original article Hit count: 216

I'm trying to implement the A* algorithm in Java. I followed this tutorial,in particular, this pseudocode: http://theory.stanford.edu/~amitp/GameProgramming/ImplementationNotes.html

The problem is my code doesn't work. It goes into an infinite loop. I really don't know why this happens... I suspect that the problem are in F = G + H function implemented in Graph constructors. I suspect I am not calculate the neighbor F correclty.

Here's my code:

List<Graph> open;
    List<Graph> close;

    private void createRouteAStar(Unit u)
    {
        open = new ArrayList<Graph>();
        close = new ArrayList<Graph>();

        u.ai_route_endX = 11;
        u.ai_route_endY = 5;

        List<Graph> neigh;

        int index;
        int i;
        boolean finish = false;

        Graph current;
        int cost;
        Graph start = new Graph(u.xMap, u.yMap, 0, ManhattanDistance(u.xMap, u.yMap, u.ai_route_endX, u.ai_route_endY));

        open.add(start);
        current = start;
        while(!finish)
        {
            index = findLowerF();
            current = new Graph(open, index);
            System.out.println(current.x);
            System.out.println(current.y);
            if (current.x == u.ai_route_endX && current.y == u.ai_route_endY)
            {
                finish = true;
            }
            else
            {
                close.add(current);
                neigh = current.getNeighbors();
                for (i = 0; i < neigh.size(); i++)
                {
                    cost = current.g + ManhattanDistance(current.x, current.y, neigh.get(i).x, neigh.get(i).y);

                    if (open.contains(neigh.get(i)) && cost < neigh.get(i).g)
                    {
                        open.remove(open.indexOf(neigh));
                    } 
                    else if (close.contains(neigh.get(i)) && cost < neigh.get(i).g)
                    {
                        close.remove(close.indexOf(neigh));
                    }
                    else if (!open.contains(neigh.get(i)) && !close.contains(neigh.get(i)))
                    {
                        neigh.get(i).g = cost;
                        neigh.get(i).f = cost + ManhattanDistance(neigh.get(i).x, neigh.get(i).y, u.ai_route_endX, u.ai_route_endY);
                        neigh.get(i).setParent(current);
                        open.add(neigh.get(i));
                    }
                }
            }

        }

        System.out.println("step");
        for (i=0; i < close.size(); i++)
        {
            if (close.get(i).parent != null)
            {
                System.out.println(i);
                System.out.println(close.get(i).parent.x);
                System.out.println(close.get(i).parent.y);
            }
        }
    }

    private int findLowerF()
    {
        int i;
        int min = 10000;
        int minIndex = -1;
        for (i=0; i < open.size(); i++)
        {
            if (open.get(i).f < min)
            {
                min = open.get(i).f;
                minIndex = i;
                System.out.println("min");
                System.out.println(min);
            }
        }
        return minIndex;
    }


    private int ManhattanDistance(int ax, int ay, int bx, int by)
    {
        return Math.abs(ax-bx) + Math.abs(ay-by);
    }

And, as I've said. I suspect that the Graph class has the main problem. However I've not been able to detect and fix it.

public class Graph {

    int x, y;
    int f,g,h;
    Graph parent;

    public Graph(int x, int y, int g, int h)
    {
        this.x = x;
        this.y = y;
        this.g = g;
        this.h = h;
        this.f = g + h;
    }

    public Graph(List<Graph> list, int index)
    {
        this.x = list.get(index).x;
        this.y = list.get(index).y;
        this.g = list.get(index).g;
        this.h = list.get(index).h;
        this.f = list.get(index).f;
        this.parent = list.get(index).parent;
    }

    public Graph(Graph gp)
    {
        this.x = gp.x;
        this.y = gp.y;
        this.g = gp.g;
        this.h = gp.h;
        this.f = gp.f;
    }

    public Graph(Graph gp, Graph parent)
    {
        this.x = gp.x;
        this.y = gp.y;
        this.g = gp.g;
        this.h = gp.h;
        this.f = g + h;
        this.parent = parent;
    }

    public List<Graph> getNeighbors()
    {
        List<Graph> aux = new ArrayList<Graph>();
        aux.add(new Graph(x+1, y, g,h));
        aux.add(new Graph(x-1, y, g,h));
        aux.add(new Graph(x, y+1, g,h));
        aux.add(new Graph(x, y-1, g,h));
        return aux;
    }

    public void setParent(Graph g)
    {
        parent = g;
    }

}

Little Edit:

Using the System.out and the Debugger I discovered that the program ALWAYS is check the same "current" graph, (15,8) which is the (u.xMap, u.yMap) position. Looks like it keeps forever in the first step.

© Stack Overflow or respective owner

Related posts about java

Related posts about algorithm