public List<Node> compute(Node start, Node end) {
        List<Node> openset = new ArrayList<Node>();
        openset.add(start);

        start.g = 0.0;
        start.h = h(start, end);
        start.f = start.g + start.h;

        List<Node> closedset = new ArrayList<Node>();

        while (!openset.isEmpty()) {
            Node x = bestNode(openset, end);
            if (isGoal(x, end)) {
                List<Node> list = new ArrayList<Node>();
                list.add(0, x);
                while (x != null) {
                    list.add(0, x.parent);
                    x = x.parent;
                }
                return list;

            }

            openset.remove(x);
            closedset.add(x);

            for (Node y : generateSuccessors(x)) {
                if (contains(closedset, y)) {
                    continue;
                }

                Double tentative_g_score = g(x) + h(x, y);
                boolean tentative_is_better;
                if (!contains(openset, y)) {
                    openset.add(y);
                    tentative_is_better = true;
                } else if (tentative_g_score < g(y)) {
                    tentative_is_better = true;
                } else {
                    tentative_is_better = false;
                }

                if (tentative_is_better) {
                    y.parent = x;
                    y.g = tentative_g_score;
                    y.h = h(y, end);
                    y.f = g(y) + h(y, end);
                }
            }
        }


        return null;

    }