【问题标题】:Creating a large 2D array and populating it from a LinkedHashMap of smaller 2D Arrays创建一个大型 2D 数组并从较小的 2D 数组的 LinkedHashMap 填充它
【发布时间】:2016-07-28 13:31:41
【问题描述】:

我正在尝试从 LinkedHashMap 创建一个大型二维数组 int[][],其中包含许多较小的数组,用于我正在研究的 A* Pathfinder。 Pathfinder 使用的Map 以较小的块流式传输到客户端,并转换为 Pathfinder 的简化版本。

Map<Coord, int[][]> pfmapcache = new LinkedHashMap<Coord, int[][]>(9, 0.75f, true);

坐标看起来像这样:Coord(0,0) 或 Coord(-1,0).... 等等,int[][] 总是 int[100][100] 大。

现在我想创建一个新的大 int[][],它将包含所有较小的数组,其中小数组 Coord(0,0) 将位于新的大数组的中心。

int[][] largearray = [-1,1][0,1][1,1]
                     [-1,0][0,0][1,0]
                     [-1,-1][0,-1][1,-1]

所以在这个例子中大数组是int[300][300] big。 2.如果pfmapcache添加了新的小数组,我想扩展新的大数组。

int[][] largearray = [][][1,2]
                     [-1,1][0,1][1,1]
                     [-1,0][0,0][1,0]
                     [-1,-1][0,-1][1,-1]    

我不必在pfmapcache 中存储较小的数组想法如何组合它们并保持它们的相对位置。

第一次在这里发帖,如果我需要澄清一些事情请告诉我。

【问题讨论】:

  • 提示:阅读 Java 编码风格指南。您使用混合大小写作为变量名。而且您了解始终创建新数组和复制值的成本吗?以其他方式:您是否考虑过从“低级”二维数组中“抽象”;这样也许你的算法可以处理它的数据......而不用把所有东西都放在一个大数组中?
  • @GhostCat 我相信 Java 变量命名约定的正确名称是“camelcase”。 :)
  • @Jokab camelCase 会是这样,不是吗 ;-)
  • 是的,我曾考虑在我的探路者中使用“低级”二维数组,但这需要我重写探路者的重要部分。我最终将不得不重写它,但我正在寻找一个临时解决方案来让它同时工作。

标签: java arrays path-finding


【解决方案1】:

您想知道如何将现有的路径查找器算法与分块地图一起使用。

此时您需要在数据表示和数据使用之间放置一个abstraction layer(如Landscape 类)。

问:寻路算法是否需要知道它适用于网格、分块网格、稀疏矩阵或更奇特的表示?
答: 不。探路者只需要知道一件事:“我可以从这里到哪里?”


理想情况

你应该放弃任何关于你的世界是在一个网格上的事实,只使用如下类:

 public interface IdealLandscape {
     Map<Point, Integer> neighbours(Point location); // returns all neighbours, and the cost to get there
 }

简单的选择

但是,我理解您现有的实现“了解”网格,附加值是邻接是隐式的,并且您正在使用 (x, y) 的点。但是,您在引入块时丢失了这一点,因此使用网格不再起作用。因此,让我们尽可能地让抽象变得轻松。这是计划:

1。引入一个 Landscape 类

public interface Landscape {
    public int getHeight(int x, int y); // Assuming you're storing height in your int[][] map?
}

2。重构你的探路者

真的很简单:
只需将map[i][j] 替换为landscape.getHeight(i, j)

3。测试你的重构

使用一个非常简单的 GridLandscape 实现,例如:

public class GridLandscape implements Landscape {
    int[][] map;
    public GridLandscape(...){
        map = // Build it somehow
    }
    @Override
    public int getHeight(int x, int y){
        return map[x][y]; // Maybe check bounds here ?
    }
}

4。使用您的 ChunkedGridLandscape

现在你的地图被抽象出来了,你知道你的探路者在上面工作,你可以用你的分块地图替换它!

public class ChunkedGridLandscape implements Landscape {
    private static final int CHUNK_SIZE = 300;
   Map<Coord, int[][]> mapCache = new LinkedHashMap<>(9, 0.75f, true);
    Coord centerChunkCoord;

    public ChunkedGridLandscape(Map<Coord, int[][]> pfmapcache, Coord centerChunkCoord){
         this.mapCache = pfmapcache;
         this.centerChunkCoord = centerChunkCoord;
    }

    @Override
    public int getHeight(int x, int y){
        // compute chunk coord
        int chunkX = x / CHUNK_SIZE - centerChunkCoord .getX();
        int chunkX = y / CHUNK_SIZE - centerChunkCoord .getY();
        Coord chunkCoord = new Coord(chunkX, chunkY);

        // Now retrieve the correct chunk
        int[][] chunk = mapCache.get(chunkCoord); // Careful: is the chunk already loaded?

        // Now retrieve the height within the chunk
        int xInChunk = (x + chunkX*CHUNK_SIZE) % CHUNK_SIZE; // Made positive again!
        int yInChunk = (y + chunkY*CHUNK_SIZE) % CHUNK_SIZE; // Made positive again!

        // We have everything !
        return chunk[xInChunk][yInChunk];
    }
}

明白了:您的Coord 类需要正确重载equals 和hashCode 方法!

5。它只是工作

这应该可以立即与您的探路者一起使用。享受吧!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-30
    • 2020-11-05
    • 2014-04-25
    • 1970-01-01
    • 1970-01-01
    • 2013-06-26
    • 2017-10-08
    相关资源
    最近更新 更多