java - 动态规划 : Bits Array Java

标签 java algorithm memory matrix dynamic-programming

我需要解决一个动态编程 问题,为此我需要在内存中创建一个N*N 大小的矩阵。如果我确实创建了一个大小为 N = 100000;byte[][] 矩阵,那么它会抛出 java.lang.OutOfMemoryError: Java heap space 错误。

在这个矩阵中,我将在特定的 ith<​​jth 索引处存储 0 或 1。所以我的使用仅限于一点,我需要一种方法,这样我就可以只使用每个矩阵单元的 1 位大小,而不是过度淹没内存,在一个只需要 1 位的单元中保留 8 位。

我怎样才能做到这一点?

请注意,我关心的不是增加 JVM 堆,我只是在寻找一种方法来最佳地实现动态问题的解决方案。

最佳答案

更新:我刚刚检查了一下,不幸的是,忘记了 BitSet

BitSet 的巧妙 API 建立在 int 索引之上。 N * N 的整数范围超出了您的范围。因此,您需要自己实现一些东西。一个建议:

public class BetterBitSet {

  private final long[] values;

  public BetterBitSet(int dimension) {
    values = new long[(int) ((long) dimension) * dimension / 8 / 64 + 1];
  }

  public void set(int i, int j, boolean value) {
    long index = index(i, j);
    int arrayIndex = arrayIndex(index);
    if (value) {
        values[arrayIndex] = set(values[arrayIndex], offset(index));
    } else {
        values[arrayIndex] = unset(values[arrayIndex], offset(index));
    }
  }

  public boolean isSet(int i, int j) {
    long index = index(i, j);
    return isSet(values[arrayIndex(index)], offset(index));
  }

  private boolean isSet(long value, int bitIndex) {
    return (value & (1L << bitIndex)) != 0;
  }

  private long set(long value, int bitIndex) {
    return value | (1L << bitIndex);
  }

  private long unset(long value, int bitIndex) {
    return value & ~(1L << bitIndex);
  }

  private long index(int i, int j) {
    return j * 8L + i;
  }

  private int arrayIndex(long index) {
    return (int) index / 64;
  }

  private int offset(long index) {
    return (int) index % 64;
  }
}

如有疑问,请查看 BitSet 的源代码并尝试类似的操作。

旧答案:问题是 byte[][] 的每个索引都需要 8 位,而您只存储大约 1 位的信息。这已经需要 9,536 MB 用于在堆上分配此数组,因此空间不足。这个内存量对于您的机器来说很可能太多了。然而,对于存储位,您仍然需要 1,192 MB。 (不考虑 BitSet 造成的任何开销。)这仍然是一个很高的数字,因此请确保您的机器提供足够的空间,您必须额外分配给您的 JVM 实例。

关于java - 动态规划 : Bits Array Java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20356807/

相关文章:

java - 如何在运行时从类序列化中排除字段?

java - 在继承层次结构中使用不同的泛型类型两次实现泛型接口(interface)

algorithm - 获取满足所有键的最少数量的值

java - 需要帮助理解算法的逻辑

C/实时用不同类型的数据初始化内存

java - Java 中的首选项

java - 正则表达式;反向引用字符集中不匹配的字符

algorithm - 将 URL 编码(和解码)为一串字母

java - 为什么我不能在 eclipse.ini 中将 -Xmx 设置为 1024m?

c++ - 访问冲突读取位置 0xcdcdcdcd。 C++