我应该使用哪种类型的稀疏向量?

时间:2019-04-23 20:47:04

标签: c++ data-structures containers sparse-matrix

数据

我有N个不同的(排序的)索引向量(std::vector<unsigned int>)。索引在[0; L-1]。这是有关此数据的两个经验法则:

  • 任何地方仅存在约0.1%到10%的可能指数
  • 如果在给定向量中找到索引,则可能会在其他向量中再次找到索引。

因此,使用N=10向量和L = 200的可能数据集可能是

{45, 110, 119, 145, 170}
{9, 45, 110, 145, 178, 170}
{45, 145}
{45, 178, 183}
{45, 53, 110, 170}
{9, 119, 123, 179}
{9, 45, 119, 130, 131, 170, 190, 199}
{9, 45, 110, 170, 199}
{31, 45, 145}
{9, 178, 183}

目标

我想计算每个索引的频率。我会做类似的事情

std::vector<double> computeFrequencies(std::vector<std::vector<unsigned int>>& data)
{
    assert(data.size() == N);

    std::vector<double> frequencies(L);
    for (unsigned Ni = 0 ; Ni < N ; Ni++)
    {
        for (unsigned i = 0 ; i < data[Ni].size() ; i++)
        {
            assert(data[Ni][i] < L)
            frequencies[data[Ni][i]]++;
        }
    }

    for (unsigned i = 0 ; i < L; i++)
    {
        frequencies[i] /= (double) N;
    }

    return(frequencies);    
}

然后我将再次循环遍历功能computeFrequencies返回的对象一次。

for (unsigned i = 0 ; i < L; i++)
{
    foo(frequencies[i]);
}

问题

对象frequencies包含很多fo零,因此我应该改用稀疏向量。我对稀疏矩阵了解不多。我应该使用哪种类型的稀疏向量?

我正在考虑使用boost::numeric::ublas::coordinate_matrix<double><double>,因为当我遍历所有N向量时,我将不断添加新的非零值,并且我认为坐标矩阵将对此有所帮助。请注意,一般而言,对于此功能,我更担心RAM的使用而不是计算时间。

1 个答案:

答案 0 :(得分:1)

看起来稀疏的矢量表示形式不太适合您的问题。

按照描述的方式完成任务:

  1. 将已排序的向量合并到单个已排序的向量中。时常在这里弹出如何进行有效的K向合并的操作:merging N sorted files using K way merge
  2. 遍历新向量并计算每个条目的重复次数(很容易,因为它们会在一起),以获取您的频率,并在您进行操作时foo

您甚至可以同时执行两个步骤,完全避免了将数据复制到新结构中的必要。