Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 稠密数据集4D矢量快速范围搜索的数据结构_C++_Sql_Data Structures_Vector - Fatal编程技术网

C++ 稠密数据集4D矢量快速范围搜索的数据结构

C++ 稠密数据集4D矢量快速范围搜索的数据结构,c++,sql,data-structures,vector,C++,Sql,Data Structures,Vector,我有数百万个与任意值关联的非结构化3D向量,构成了一组4D向量。为了让理解更简单:我有与数十万个3D向量相关联的unixtime戳记。我有很多时间戳,这是一个非常大的数据集;超过3000万只 我需要搜索特定时间戳的特定数据集 假设我有以下数据: 对于时间戳1407633943: (0,24,581407633943) (9,2,591407633943) 对于时间戳1407729456: (40,1,331407729456) (3,5,71407729456) 等等 我想快速提出以

我有数百万个与任意值关联的非结构化3D向量,构成了一组4D向量。为了让理解更简单:我有与数十万个3D向量相关联的unixtime戳记。我有很多时间戳,这是一个非常大的数据集;超过3000万只

我需要搜索特定时间戳的特定数据集

假设我有以下数据:

对于时间戳1407633943:

  • (0,24,581407633943)

  • (9,2,591407633943)

对于时间戳1407729456:

  • (40,1,331407729456)

  • (3,5,71407729456)

等等

我想快速提出以下问题:

查询示例1:

给我向量:

X>4&&X<9&&Y>-29&&Y<100&&Z>0.58&&Z<0.99

给我这些向量的列表,这样我就能找到时间戳了

查询示例2:

给我向量:

X>4&&X<9&&Y>-29&&Y<100&&Z>0.58&&Z<0.99&&W(时间戳)=1407729456

到目前为止,我已经使用SQLite来完成这项任务,但即使在列索引之后,每次查询也需要500毫秒到7秒的时间。我正在寻找每个查询解决方案的速度介于50ms-200ms之间

我可以使用什么样的结构或技术来加速查询


谢谢。

kd树在这里很有用。kd树中的范围搜索是一个众所周知的问题。当然,一个查询的时间复杂度取决于输出大小(在最坏的情况下,如果所有向量都匹配,则将遍历所有树)。但平均来说,它可以运行得相当快。

我会使用。在每个节点中,我将使用时间戳作为键,将向量数组存储在一个数组中


为了进一步提高性能,您可以使用CUDA、OpenCL、OpenACC、OpenMP,并在GPU或多核CPU上实现并行执行的算法

BKaun:请接受我的尝试,让你对眼前的问题有所了解。我想你已经想到了我的每一点,但也许在这里看到它们会有所帮助

不管如何呈现数据,请考虑使用C编程语言,可以减少数据的存储大小,以最小化空间和搜索时间。您将搜索、加载和解析向量的单个位,而不是一个短INT(每个条目有2个字节)或一个更大的FLOAT。据我所知,目标是在给定的数据中搜索给定的X、Y和Z值,然后在优化搜索的同时找到与这3个值关联的时间戳。我的解决方案不涉及搜索,而只是搜索中使用的数据

为了简单地说明我的提示,我认为数据由4个向量组成:

  • X介于-2和7之间
  • Y介于0.17和3.08之间
  • Z介于0和50之间
  • 时间戳(许多大小相同-10位)
  • 为了优化,考虑每个向量中可以有多少个不同的数字: 1.X只能是10个数字(包括0) 2.Y可以是3.08减去0.17=2.91 x 100=291个数字 3.Z可以是51个数字 4.时间戳可以很多(但在这种情况下, 你不是在寻找某一个人)

    考虑如何将每个变量存储为二进制: 1.向量X中的每个条目可以存储在4位中,使用第一位=1表示 负号: 7="0111" 6="0110" 5="0101" 4="0100" 3="0011" 2="0010" 1="0001" 0="0000" -1="1001" -2=“1010”

  • 向量Y中的每个条目可以存储在9位中(不需要额外的符号位) 1和0可以存储(实际上是访问)在两个部分中 (十位,小数点后两位)。 第1部分可以是0、1、2或3(4个2位,从“00”到“11”) 但是,如果整个Y数据集的范围为0到10, 第1部分可以是0、1、…9、10(即11个4位 从“0000”到“1010” 第2部分可以是00,01,…98,99(100个7位,从“0000000”到“1100100” 向量Y项的总存储位为11+7=18位 范围为00.00至10.99 为了在00.00到10.99范围内进行搜索,有1089个不同的Y向量 可通过(11x99)(?)搜索的条目

  • 向量Z中0到50范围内的每个条目可以存储在6位中 (“000000”至“110010”)。 同样,实际数据范围可能是7位长(为了简单起见) 0至64(“0000000”至“1000000”)

    为了在0到64的范围内进行搜索,有65个不同的Z向量条目 可以搜索


  • 考虑到您将以这种优化的格式存储数据,在一个 位序列:

    X=4位+2个范围位=6位 +Y=4位第1部分和7位第2部分=11位 +Z=7位

    +时间戳(10个数字-每个数字从0到9(“0000”到“1001”)4位,每个=40位) =总位:6+11+7+40=每个4D矢量的64个存储位


    搜索:

    输入xx、yy、zz以在数组X、Y和Z(以二进制形式存储)中搜索 根据上述优化格式,将xx、yy和zz更改为二进制位字符串

    功能(xx、yy、zz)


    我担心vector 4D的标题,我想到的是
    vector
    ,而实际上它是
    vector
    T
    一个有4个字段的类。
         However, the original data that you are searching through may range 
            from -10 to 20!
         Therefore, adding another 2 bits gives you a table like this:  
                -10="101010"
                 -9="101001" ...
                 ...
                 -2="100010"
                 -1="100001" ...
                 ...
                  8="001000"
                  9="001001" ...
                 ...
                 19="001001"
                 20="010100"
    
        And that's only 6 bits to store each X vector entry for integers from -10 to 20
        For search purposes on a range of -10 to 20, there are 21 different X Vector entries
            possible to search through.
    
        Search for X first, since it has 21 possible outcomes (range is -10 to 10) 
           - the lowest number of any array
        First search for positive targets (there are 8 of them and better chance 
            of finding one)
             These all start with "000" 
                 7="000111"
                 6="000110"
                 5="000101"
                 4="000100"
                 3="000011"
                 2="000010"
                 1="000001"
                 0="000000"
              So you can check if the first 3 bits = "000".  If so, you have a number
              between 0 and 7.
                 Found: search for Z
                    Else search for xx=-2 or -1: does X = -2="100010" or -1="100001" ? 
                      (do second because there are only 2 of them)
                         Found: Search for Z
              NotFound: next X
    
        Search for Z after X is Found: (Z second, since it has 65 possible outcomes 
         - range is 0 to 64)
              You are searching for 6 bits of a 7 bit binary number
                   ("0000000" to "1000000")  If bits 1,2,3,4,5,6 are all "0", analyze bit 0.  
                     If it is "1" (it's 64), next Z
                         Else begin searching 6 bits ("000000" to "110010") with LSB first
                            Found: Search for Y 
                            NotFound: Next X
    
        Search for Y (Y last, since it has 1089 possible outcomes - range is 0.00 to 10.99)
               Search for Part 1 (decimal place) bits (you are searching for 
                "0000", "0001" or "0011" only, so use yyPt1=YPt1)
                    Found: Search for Part 2 ("0000000" to "1100100") using yyPt2=YPt2 
                    (direct comparison)
                        Found:  Print out X, Y, Z, and timestamp
                    NotFound: Search criteria for X, Y, and Z not found in data.  
                        Print X,Y,Z,"timestamp not found". Ask for new X, Y, Z. New search.