如何使用“指针数组”间接将2D矩阵条目映射到1D数组?

时间:2012-08-26 21:09:15

标签: algorithm sparse-matrix adjacency-matrix

注意:我已使用Keith RandallChiyou的有用反馈修改了此问题。

我有一个想法是使用一维数组来缓存特定处理环境中最常用的2D NxM矩阵条目。问题是,是否已经存在一系列工作,从哪里获得洞察力,或者只有人知道。我将首先概述腿部工作,然后再提出问题。作为补充说明,Chiyou已经提出了space filling curves,从概念上讲,这是我追求的事情,但不会轻易回答我的具体问题(即我找不到可以做的曲线)我在追求什么。)

腿部工作: 目前,最常用的条目被定义为循环和特殊pointer_array的组合(参见下面的代码),它们组合产生最常用矩阵元素的索引。 pointer_array包含数字in range [0,max(N,M)] (参见上面定义为NxM的矩阵维度)。

代码的目的是产生一个合适的(在程序的上下文中)索引组合来处理一些矩阵条目。可能N = M,即方阵。遍历矩阵的代码(C ++)如下所示

for(int i = 0; i < N; i++)
{        
    for(int j = i + 1; j < M; j++)
    {
        auto pointer1 = pointer_array[i];
        auto pointer2 = pointer_array[i + 1];
        auto pointer3 = pointer_array[j];
        auto pointer4 = pointer_array[j + 1];

        auto entry1 = some_matrix[pointer1][pointer3];
        auto entry2 = some_matrix[pointer2][pointer4];
        auto entry3 = some_matrix[pointer3][pointer4];
        auto entry4 = some_matrix[pointer1][pointer2];

        //Computing with the entries...
    }
}

有些事情值得单独说明:

  1. 为了使这个缓存值得,我认为它应该是密集的。也就是说,可以随机访问并在内存中连续布局的东西。即没有空间“浪费”(除非有许多单独的块),复杂性在O(1)中。这意味着缓存不能是与1D行/列主要有序数组完整相同的2D矩阵。我认为它应该适合长度 max(N,M)的数组(参见上面的矩阵维度定义)。

  2. 循环期间将忽略some_matrix中的许多条目。

  3. pointer_array排序记录通过矩阵的路线,所以它也在其他地方使用。

  4. 我在各种场合遇到过这种需求,但这次我写了一个2-opt算法,内存访问模式,我正在寻求改进。我知道还有其他方法来编写算法(但是看到其他设置我已经遇到过这个问题,我现在想知道是否有一般解决方案。)

  5. 在盒子外面思考的是产生一种类似的索引组合,这种组合在概念上就像访问2D矩阵,但只是更聪明。一种选择是在循环期间缓存矩阵行/列。

  6. 由于条目将被大量使用,因此通过缓存some_matrix调用替换pointer_array间接更为理想,以便获取循环中的entry*值更快,即从预加载的缓存而不是可能相当大的矩阵。这里的另一点是它可以节省存储空间,这反过来意味着经常使用的值可以很好地适应更快的缓存。

  7. 问题:是否可以设置索引方案,以便矩阵索引基本上成为

    //Load the 2D matrix entries to some_1d_cache using the pointer_array
    //so that the loop indices can be used directly...
    
    for (int i = 0; i < N; i++)
    {        
        for (int j = i + 1; j < M; j++)
        {           
            //The some_1d_cache((x, y) call will calculate an index to the 1D cache array...
            auto entry1 = some_1d_cache(i, j);
            auto entry2 = some_1d_cache(i + 1, j + 1);
            auto entry3 = some_1d_cache(j, j + 1);
            auto entry4 = some_1d_cache(i, i + 1);
    
            //Computing with the entries...
        }
    }
    

    或许像下面这样的事情也会这样做

    for (int i = 0; i < N; i++)
    {        
        for (int j = i + 1; j < M; j++)
        {            
            auto pointer1 = pointer_array[i];
            auto pointer2 = pointer_array[i + 1];
            auto pointer3 = pointer_array[j];
            auto pointer4 = pointer_array[j + 1];
    
            //The some_1d_cache((x, y) call will calculate an index to the 1D cache array...
            auto entry1 = some_1d_cache(pointer1, pointer3);
            auto entry2 = some_1d_cache(pointer2, pointer4);
            auto entry3 = some_1d_cache(pointer3, pointer4);
            auto entry4 = some_1d_cache(pointer1, pointer2);
    
            //Computing with the entries...
        }
    }
    

1 个答案:

答案 0 :(得分:1)

您可以使用1d空间填充曲线索引2d矩阵。数学上它是H(x,y)=(h(x)* h(y))。它们也很有用,因为它们基本上可以细分,存储一些地点信息并重新排序飞机。