关联矩阵c++太大

Associative matrix c++ too big

本文关键字:太大 c++ 关联矩阵      更新时间:2023-10-16

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

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

正如我在上面评论的那样,这对我来说非常有效(住在这里):

#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. 当元素的数量小于某个预定义值时,换句话说,数据密度低时,可以使用稀疏矩阵。稀疏矩阵的思想很简单:不保留所有可能的元素;相反,您保留一些大量元素的普通数组,比如1000,类型为struct{int line,row;unsigned char value;}。在一定的数值上,这种数组的内存消耗小于矩阵。但这可能是随机访问的显著开销。可以应用一些优化来减少它
  2. 如果数据密度高,"活动"元素的数量大,则使用压缩矩阵、比特填充可以达到一定的效果。通过记忆,这可能非常有效。在您的示例中,每个值只需要2位,因此int64将在一个"行"中保留32个值。这里需要精细优化的访问方法来减少时间消耗
  3. 您可以在上述解决方案之间切换,以从稀疏矩阵迁移到压缩矩阵

如果数据非常稀疏,那么Massa的方法的开销是每个项目多出一个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;
}

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

您的值范围: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]。

在上面的技术中,您可以通过使用范围来压缩矩阵位置。