关联矩阵c ++太大了

时间:2014-04-10 17:46:34

标签: c++ arrays matrix 2d

哪种方法可以减少矩阵的大小? (x2阵列) 例如,我只需要将数据(0,1,2)存储到数组中 但元素可高达25万。? 有没有办法存储价值观,比如字典..?

const int MAX = 250000;
short data[MAX][MAX] = {};//wont compile..

4 个答案:

答案 0 :(得分:2)

这对我来说非常合适,正如我上面评论的那样(live here):

#include <iostream>
#include <unordered_map>

std::unordered_map<unsigned int, std::unordered_map<unsigned int, unsigned char>> data;

int main() {
  std::cout << "oi" << std::endl;

    data[232432][234234] = 2;
    data[2][2] = 1;
    std::cout << int(data[232432][234234]) << std::endl;
    std::cout << int(data[3][3]) << std::endl;
    std::cout << int(data[232432][1]) << std::endl;
    std::cout << int(data[2][2]) << std::endl;
}

答案 1 :(得分:1)

我记得静态变量的sizeof有一些限制。使用动态内存。 您可以根据元素数量和内存限制使用不同类型的存储。

  1. 当元素的数量小于某个预定义值时,可以使用稀疏矩阵,换句话说,数据密度低。 稀疏矩阵的想法很简单:你没有保留所有可能的元素;相反,你保持一些大量元素的简单数组,比如说,类型为struct {int line,row; unsigned char值;}。高达某个值,这种数组的内存消耗小于矩阵。但它可能是随机访问的重大开销。可以应用一些优化来减少它。
  2. 如果数据密度高,“活动”元素的数量很大,使用压缩矩阵,比特打包可以实现一些效果。这可能是非常有效的记忆。在您的示例中,每个值只需要2位,因此int64将在“行”中保留32个值。这里需要精细优化的访问方法来减少时间消耗。
  3. 您可以在上述解决方案之间切换,以便从稀疏矩阵迁移到压缩矩阵。

答案 2 :(得分:1)

如果数据非常稀疏,则Massa's approach每个项目的额外费用unordered_map。较低的开销解决方案是使用对索引无序映射:

#include <iostream>
#include <unordered_map>

/// Hash specialization for a pair of unsigned ints
template<> struct std::hash<std::pair<unsigned int, unsigned int>>
{
  typedef std::pair<unsigned int, unsigned int> argument_type;
  typedef std::size_t value_type;
  value_type operator()(argument_type const& s) const
  {
    value_type const h1 ( std::hash<unsigned int>()(s.first) );
    value_type const h2 ( std::hash<unsigned int>()(s.second) );
    return h1 ^ (h2 << 1);
  }
};

std::unordered_map<std::pair<unsigned int, unsigned int>, unsigned char> data;

int main() {
  using std::make_pair;
  data[make_pair(232432u, 234234u)] = 2;
  data[make_pair(2u, 3u)] = 1;
  std::cout << int(data[make_pair(232432u, 234234u)]) << std::endl;
  std::cout << int(data[make_pair(3u, 3u)]) << std::endl;
  std::cout << int(data[make_pair(232432u, 1u)]) << std::endl;
  std::cout << int(data[make_pair(2u, 3u)]) << std::endl;
}

答案 3 :(得分:0)

<强>压缩
您可以压缩数据值,这将节省您的内存,但会增加访问时间。

您的值范围:0,1,2,占用2位来表示。因此,一个8位的uint8_t变量可以容纳4列值:

 3  2  1  0  
+--+--+--+--+  
|xx|xx|xx|xx|  
+--+--+--+--+  

要访问这些值,您需要执行一些二进制算术:

value of column 0 == (byte & 0x03); /* >> 0 */
value of column 1 == (byte & 0x0c) >> 2;  
value of column 2 == (byte & 0x30) >> 4;
value of column 3 == (byte & 0xC0) >> 6;

该字节可以通过以下方式访问:(index / 4)

观点变更
由于您只有3个值,因此可以将坐标存储在数组的列表中。您将在数组中搜索坐标。

Data        row   col       row   col
+---+     +-----+----+     +-----+---+   
| 0 | --> | 115 | 25 | --> |20961| 4 |  
+---+     +-----+----+     +-----+---+  
| 1 |  
+---+  
| 2 |  
+---+  

在上图中,矩阵位置[115] [25]包含零,以及[20961] [4]。

在上述技术中,您可以使用范围压缩矩阵位置。