我有一个关于多维数组打包的问题。我此刻陷入困境,也许有人可以帮助我,因为我认为这是一项相当简单的任务。我在Fortran编程,但语言在这里非常重要。
在我工作期间,我必须在三元组i,j,k上存储信息,其中i <= j <= k,其中i,j,k从1变为n。
因为我的程序中的内存需求很关键,所以我不想浪费内存并尝试将数组行程(i,j,k)打包到一维数组中。到目前为止,我使用对ij并将它们映射到1d数组(通常用于对称矩阵)并计算1d数组中的索引:
ijpair = i*(i+1)/2+j
具有最大对数
npair = n*(n+1)/2+n
为了合并第三个索引,我生成了n个副本块(对于每个k)。三元组的索引是:
ijktrip = npair*(k-1) + ijpair
以这种方式,内存需求已经减少,但仍然不是最优的,目前我无法弄清楚如何充分利用限制i&lt; = j&lt; = k。
感谢您的提前帮助
答案 0 :(得分:0)
正如您已经注意到的那样,对于特定的k
,您有k*(k+1)/2
个元素。让我们按k
的递增顺序枚举元素,然后增加j
的顺序,然后增加i
的顺序。
对于给定的k
,您已使用sum_{1 <= p < k} p*(p+1)/2
个索引。该总和评估为(见Wolfram alpha)
k*(k-1)*(k+1)/6
在k
- 平面中,您需要对j
执行类似的操作:对于给定的j
您已使用sum_{1 <= p < j} p = j*(j-1)/2
个索引。
在jk
- 行上,您重复此操作:对于给定的i
您已使用i-1
个索引。
这产生总公式:
index(i, j, k) = k*(k-1)*(k+1)/6 + j*(j-1)/2 + i
请注意(再次参见Wolfram alpha)
index(n, n, n) = n*(n-1)*(n+1)/6 + n*(n-1)/2 + n = n*(n+1)*(n+2)/6
这正是您拥有的元素数量,因此不会浪费任何索引。