动态编程:Bits数组Java
我需要解决一个动态编程:Bits数组Java,java,algorithm,memory,matrix,dynamic-programming,Java,Algorithm,Memory,Matrix,Dynamic Programming,我需要解决一个动态规划问题,我需要在内存中创建一个N*N大小矩阵。如果我确实创建了一个大小为N=100000的byte[][]矩阵然后抛出java.lang.OutOfMemoryError:java堆空间错误 在此矩阵中,我将在特定的ith和jth索引处存储0或1。因此,我的使用仅限于一位,我需要一种方法,使每个矩阵单元只使用1位大小,而不是在一个只需要1位的单元中保留8位的内存溢出 我怎样才能做到这一点 请注意,我关心的不是增加JVM的堆,我只是在寻找一种方法,以最佳方式实现动态问题的解决方
动态规划
问题,我需要在内存中创建一个N*N
大小矩阵。如果我确实创建了一个大小为N=100000的byte[][]
矩阵
然后抛出java.lang.OutOfMemoryError:java堆空间
错误
在此矩阵中,我将在特定的ith
和jth
索引处存储0或1。因此,我的使用仅限于一位,我需要一种方法,使每个矩阵单元只使用1位大小,而不是在一个只需要1位的单元中保留8位的内存溢出
我怎样才能做到这一点
请注意,我关心的不是增加JVM的堆,我只是在寻找一种方法,以最佳方式实现动态问题的解决方案。更新:我只是检查了一下,不幸的是,忘记了
位集
BitSet
的genious 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;
}
}
公共类BetterBitSet{
私有最终长[]值;
公共BetterBitSet(整数维){
值=新长[(int)((长)维度)*维度/8/64+1];
}
公共空集(int i,int j,布尔值){
长指数=指数(i,j);
int arrayIndex=arrayIndex(索引);
如果(值){
值[arrayIndex]=集合(值[arrayIndex],偏移量(索引));
}否则{
值[arrayIndex]=未设置(值[arrayIndex],偏移量(索引));
}
}
公共布尔isSet(int i,int j){
长指数=指数(i,j);
返回isSet(值[arrayIndex(索引)],偏移量(索引));
}
私有布尔isSet(长值,int-bitIndex){
return(value&(1LUpdate:我刚检查过,但实际上忘记了位集
)
BitSet
的genious 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;
}
}
公共类BetterBitSet{
私有最终长[]值;
公共BetterBitSet(整数维){
值=新长[(int)((长)维度)*维度/8/64+1];
}
公共空集(int i,int j,布尔值){
长指数=指数(i,j);
int arrayIndex=arrayIndex(索引);
如果(值){
值[arrayIndex]=集合(值[arrayIndex],偏移量(索引));
}否则{
值[arrayIndex]=未设置(值[arrayIndex],偏移量(索引));
}
}
公共布尔isSet(int i,int j){
长指数=指数(i,j);
返回isSet(值[arrayIndex(索引)],偏移量(索引));
}
私有布尔isSet(长值,int-bitIndex){
return(value&(1LUpdate:我刚检查过,但实际上忘记了位集
)
BitSet
的genious 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;
}
}
公共类BetterBitSet{
私有最终长[]值;
公共BetterBitSet(整数维){
值=新长[(int)((长)维度)*维度/8/64+1];
}
公共空集(int i,int j,布尔值){
长指数=指数(i,j);
int arrayIndex=arrayIndex(索引);
如果(值){
值[arrayIndex]=集合(值[arrayIndex],偏移量(索引));
}否则{
值[arrayIndex]=未设置(值[arrayIndex],偏移量(索引));
}
}
公共布尔isSet(int i,int j){
长指数=指数(i,j);
返回isSet(值[arrayIndex(索引)],偏移量(索引));
}
私有布尔isSet(长值,int-bitIndex){
return(value&(1LUpdate:我刚检查过,但实际上忘记了位集
)
BitSet
的genious 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;
}
}
公共类BetterBitSet{
私有最终长[]值;
公共BetterBitSet(整数维){
值=新长[(int)((长)维度)*维度/8/64+1];
}
公共空集(int i,int j,布尔值){
长指数=指数(i,j);
int arrayIndex=arrayIndex(索引);
如果(值){
值[arrayIndex]=集合(值[arrayIndex],偏移量(索引));
}否则{
值[arrayIndex]=未设置(值[arrayIndex],偏移量(索引));
}
}
公共布尔isSet(int i,int j){
长指数=指数(i,j);
返回isSet(值[arrayIndex(索引)],偏移量(索引));
}
私有布尔isSet(长值,int-bitIndex){
return(value&(1LJava提供了一个名为a的基于位的托管数据结构。我说这是托管的,因为Java没有用于存储位的本机类型,BitSet
将单个位存储为long
的组件,并保持long[]
备份数据集。这是一种非常高效的存储方法,但每64位中保留6位用于“寻址”,仅在原始存储层,这就相当于10%的开销
这意味着您可以通过保持并仔细处理自己的长[]
,在存储上击败位集
,代价是代码的复杂性和风险。除非您的空间非常有限,否则可能不值得为位集
节省约10%的原始开销
上面描述的两种解决方案都是一维位数组,这可能毫无意义。通过将一维数组视为行的串联,您可以轻松地将二维数组转换为一维数组(至少在这种情况下,您似乎假设行宽度相等)。寻址中的特定单元格