我正在重新设计一个创建了6D数组的代码。这是Cplex线性计算所必需的。
现在,有一些API可以支持cplex中的1D或int变量,因此拥有6维数组并不重要。 只有映射对于从另一个方法检索变量时需要的变量很重要。
有没有办法更换6D阵列。这也有助于简化代码的复杂性。
- >我能以某种方式替换6D数组并将变量存储在1D数组或int变量中。 - >我尝试使用键作为列表的HashMap和值作为整数的值,但最终它花费更多的时间,因为HashMap内部使用数组。
示例代码为:
int [][][][][][] testVariable = new int [2][2][3][5][2][2];
HashMap<List<Integer>, Integer> mapping = new HashMap<List<Integer>, Integer>();
int[] arrayAdd = new int[11111];
for (int a =0; a <= 2; a++) {
for (int l = 0; l < 2; l++) {
for (int y = 0; y < 3; y++) {
for (int r = 0; r < 5; r++) {
for(int oc=0; oc< 2; oc++){
for(int c=0; c< 2; c++){
// usual array of 6D
testVariable[a][l][y][r][oc][c]=count;
// FIRST METHOD ( Takes more time then Array)
LinkedList<Integer> listAdd = new LinkedList<Integer>();
listAdd.add(a);
listAdd.add(l);
listAdd.add(y);
listAdd.add(r);
listAdd.add(oc);
listAdd.add(c);
mapping.put(listAdd, count);
// second method .. this i am still testing but it doesnt make much sense)
arrayAdd[a + l + y + r + oc + c] = count;
// Arrays.fill(arrayAdd, count);
//System.out.println("Value of list is " + listAdd);
count ++;
}
}
}
}
}
}
答案 0 :(得分:3)
如果您知道每个尺寸的长度都不会改变,那么您可以使用1D阵列模拟6D阵列。诀窍是将除最后一个索引c
之外的所有索引的索引乘以足够高的数字,以便在映射到相同1D索引的不同6D索引集之间不会发生任何冲突。
int[] oneDArray = new int[2*2*3*5*2*2];
用于计算1D指数,使用6个6D指数。在每个特定的6D指数之后乘以所有维度长度的乘积将避免碰撞。
int oneDIndex = 2*3*5*2*2 * a // last 5 dimensions' lengths
+ 3*5*2*2 * l // last 4 dimensions' lengths; variable letter l
+ 5*2*2 * y // last 3 dimensions' lengths
+ 2*2 * r // last 2 dimensions' lengths
+ 2 * oc // last dimension's length only
+ c; // no multiplier necessary for last index
最好在这里使用每个尺寸长度的常量,以减少硬编码。
答案 1 :(得分:0)
只是我的意见,但假设我想要一个非稀疏的超矩形,我会使用一维Java数组,并自己做索引算法。
,例如,对于包含3行和5列的2D数组:
final int num_rows = 3;
final int num_cols = 5;
final T[] storage = new T[num_rows * num_cols];
T get(int row, int col) {
assert(row >= 0);
assert(row < num_rows);
assert(col >= 0);
assert(col < num_cols);
return storage[row*num_cols + col];
}
你可以想象这将如何推广到两个以上的维度。
提示:我会将num_rows和num_cols替换为一个名为&#39; dimension&#39;的有效不可变数组。维度数组的长度将是呈现给客户端的维度数。存储阵列的长度将是维度数组的所有成员的乘积,依此类推。
答案 2 :(得分:0)
扩展rgettman的答案并证明更一般的方式从6D-> 1D转换,反之亦然。
将6D数组转换为1D数组:
int[] sixDArrayToOneDArray(final int[][][][][][] sixDArray) {
int dim1Length = sixDArray.length;
int dim2Length = sixDArray[0].length;
int dim3Length = sixDArray[0][0].length;
int dim4Length = sixDArray[0][0][0].length;
int dim5Length = sixDArray[0][0][0][0].length;
int dim6Length = sixDArray[0][0][0][0][0].length;
int[] result = new int[dim1Length * dim2Length * dim3Length * dim4Length * dim5Length * dim6Length];
for (int i1 = 0; i1 < dim1Length; i1++)
for (int i2 = 0; i2 < dim2Length; i2++)
for (int i3 = 0; i3 < dim3Length; i3++)
for (int i4 = 0; i4 < dim4Length; i4++)
for (int i5 = 0; i5 < dim5Length; i5++)
for (int i6 = 0; i6 < dim6Length; i6++) {
int oneDIndex = i1 * dim2Length * dim3Length * dim4Length * dim5Length * dim6Length
+ i2 * dim3Length * dim4Length * dim5Length * dim6Length + i3 * dim4Length * dim5Length * dim6Length
+ i4 * dim5Length * dim6Length
+ i5 * dim6Length
+ i6;
result[oneDIndex] = sixDArray[i1][i2][i3][i4][i5][i6];
}
return result;
}
将1D数组转换为6D数组:
int[][][][][][] oneDArrayToSixDArray(int[] oneDArray, int dim1Length, int dim2Length, int dim3Length, int dim4Length, int dim5Length, int dim6Length) {
if (oneDArray.length != dim1Length * dim2Length * dim3Length * dim4Length * dim5Length * dim6Length) {
throw new IllegalArgumentException(String.format("One dimension array length [%s] does not match to six dimensions array lengths [%s, %s, %s, %s, %s, %s]", dim1Length, dim2Length, dim3Length, dim4Length, dim5Length, dim6Length));
}
int[][][][][][] result = new int[dim1Length][dim2Length][dim3Length][dim4Length][dim5Length][dim6Length];
for (int i = 0; i < oneDArray.length; i++) {
int i1 = i / (dim2Length * dim3Length * dim4Length * dim5Length * dim6Length);
int i2 = (i % (dim2Length * dim3Length * dim4Length * dim5Length * dim6Length)) / (dim3Length * dim4Length * dim5Length * dim6Length);
int i3 = (i % (dim3Length * dim4Length * dim5Length * dim6Length)) / (dim4Length * dim5Length * dim6Length);
int i4 = (i % (dim4Length * dim5Length * dim6Length)) / (dim5Length * dim6Length);
int i5 = (i % (dim5Length * dim6Length)) / dim6Length;
int i6 = i % dim6Length;
result[i1][i2][i3][i4][i5][i6] = oneDArray[i];
}
return result;
}