当前位置: 首页 > 知识库问答 >
问题:

当在2D ArrayList中搜索深度优先时,如何解决“OutofMemoryError:Java堆空间”?

邢博文
2023-03-14

我正在用Java编写一个人工智能游戏。我有一个(2D)arraylist表示GridWorld。在gridworld中有随机放置的对象。对象由黑色方块表示(您不能越过黑色方块)。

public class DepthFirstAI {
  private int nodeCounter = 0;

  // run this function for each move
  private Node<ArrayList<ArrayList<Color>>> buildTree(Node<ArrayList<ArrayList<Color>>> tree) {
        if(nodeCounter > 0) {
            leaves.clear();
            getLeaves(tree);

            for(Node<ArrayList<ArrayList<Color>>> child : leaves) {
                child.addChild(bla(child).getData()); // add new childs (based on the possible directions) to the node
            }
        } else {
            tree = bla(tree);
        }

        nodeCounter++;
        return tree;
    }

    public Node<ArrayList<ArrayList<Color>>> bla(Node<ArrayList<ArrayList<Color>>> node) {
        ArrayList<ArrayList<Color>> grid = node.getData().getValue();

        int roboX = roomGUI.player.x; // x location of player
        int roboY = roomGUI.player.y; // y location of player


        // Add possible directions (top, left, right, bottom) to directionsList
        .......

            Directions[] directions = directionsList.toArray(new Directions[0]);
            for (Directions d : directions) { // Create new child for each possible direction with the new grid + the name of the direction
                switch (d) {
                    case TOP: {
                        ArrayList<ArrayList<Color>> tempGrid = grid;
                        // Color squares visited by player
                        .....

                        Pair<Directions, ArrayList<ArrayList<Color>>> child = new Pair<>(Directions.TOP, tempGrid);
                        node.addChild(child);
                        break;
                    }
                    case BOTTOM: {
                        ...
                        break;
                    }
                    case RIGHT: {
                        ...
                        break;
                    }
                    case LEFT: {
                        ...
                        break;
                    }
                }
            }
        }
        return tree;
    }

public class Node<T> {
        private ArrayList<Node<T>> children = new ArrayList<Node<T>>();
        private Node<T> parent = null;
        private Pair<Directions, ArrayList<ArrayList<Color>>> data = null;

        public Node(Pair<Directions, ArrayList<ArrayList<Color>>> data) {
            this.data = data;
        }

        public Node(Pair<Directions, ArrayList<ArrayList<Color>>> data, Node<T> parent) {
            this.data = data;
            this.parent = parent;
        }

        public ArrayList<Node<T>> getChildren() {
            return children;
        }

        public boolean hasChildren() {
            return children.size() > 0;
        }

        public void setParent(Node<T> parent) {
            this.parent = parent;
        }

        public void addChild(Pair<Directions, ArrayList<ArrayList<Color>>> data) {
            Node<T> child = new Node<T>(data);
            this.children.add(child);
        }

        public Pair<Directions, ArrayList<ArrayList<Color>>> getData() {
            return this.data;
        }

        public void setData(Pair<Directions, ArrayList<ArrayList<Color>>> data) {
            this.data = data;
        }

        public boolean isRoot() {
            return (this.parent == null);
        }

        public boolean isLeaf() {
            return this.children.size() == 0;
        }

        public void removeParent() {
            this.parent = null;
        }
    }
}

我如何能够创建一个具有所有可能选项的树来找到最短路径?

共有1个答案

邹海超
2023-03-14

不是看你的代码,而是看一般的问题,你想看看使用部分扩展的思想。(例如部分扩展a*-pea*)其思想是,在每次移动时生成所有后继,但随后丢弃它们以节省内存,只保留当前后继的索引。(为了节省时间,你可以保留多个。)然后,当你想探索下一个孩子的时候,你就再生继任者并继续下去。

当您有很多继任者时,这有可能解决内存问题。(假设您的问题实际上不是由垃圾收集或代码中的其他bug引起的。)但是,请注意,即使解决了空间问题,树也可能太大,无法有效地搜索。许多DFS问题随着树的深度呈指数增长,所以在真正小的问题上尝试一下,以确保它首先工作。

 类似资料:
  • 主要内容:深度优先搜索(简称“深搜”或DFS),广度优先搜索,总结前边介绍了有关图的 4 种存储方式,本节介绍如何对存储的图中的顶点进行遍历。常用的遍历方式有两种: 深度优先搜索和 广度优先搜索。 深度优先搜索(简称“深搜”或DFS) 图 1 无向图 深度优先搜索的过程类似于树的先序遍历,首先从例子中体会深度优先搜索。例如图 1 是一个无向图,采用深度优先算法遍历这个图的过程为: 首先任意找一个未被遍历过的顶点,例如从 V1 开始,由于 V1 率先访问过了,所以

  • 我已经查看了其他各种StackOverflow答案,它们都与我的讲师在幻灯片中写的不同。 深度优先搜索的时间复杂度为O(b^m),其中b是搜索树的最大分支因子,m是状态空间的最大深度。如果m比d大得多,这很糟糕,但如果搜索树“浓密”,则可能比广度优先搜索快得多。 他接着说。。 空间复杂度为O(bm),即动作序列长度的空间线性!只需要存储从根到叶节点的单个路径,以及路径上每个节点的剩余未扩展兄弟节点

  • 本文向大家介绍深度优先搜索,包括了深度优先搜索的使用技巧和注意事项,需要的朋友参考一下 图遍历是按某种系统顺序访问图的所有顶点的问题。遍历图主要有两种方法。 广度优先搜索 深度优先搜索 深度优先搜索(DFS)算法从顶点v开始,然后遍历到之前未访问过的相邻顶点(例如x),并将其标记为“已访问”,然后继续处理x的相邻顶点,依此类推。 如果在任何一个顶点上遇到所有相邻顶点都被访问过,则它将回溯直到找到具

  • 3. 深度优先搜索 现在我们用堆栈解决一个有意思的问题,定义一个二维数组: int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, }; 它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的路线

  • 我有一个无向连通图。我使用邻接矩阵实现了它,它是一个2维数组。 据我所知,DFS在兄弟节点之前访问子节点。BFS先于孩子探望兄弟姐妹。 这两个我是这样实现的: 如果让我执行一个从D到E的DFS,是D、C、a、E还是D、E。我以为DFS和BFS必须访问每个节点,在这种情况下B不能访问。我不知道我应该如何改变我目前的方法来满足这些要求。

  • 本文向大家介绍什么是深度优先搜索?相关面试题,主要包含被问及什么是深度优先搜索?时的应答技巧和注意事项,需要的朋友参考一下 如算法名称那样,深度优先搜索所遵循的搜索策略是尽可能“深”地搜索树。它的基本思想是:为了求得问题的解,先选择某一种可能情况向前(子结点)探索,在探索过程中,一旦发现原来的选择不符合要求,就回溯至父亲结点重新选择另一结点,继续向前探索,如此反复进行,直至求得最优解。深度优先搜索