C++ 稠密数据集4D矢量快速范围搜索的数据结构
我有数百万个与任意值关联的非结构化3D向量,构成了一组4D向量。为了让理解更简单:我有与数十万个3D向量相关联的unixtime戳记。我有很多时间戳,这是一个非常大的数据集;超过3000万只 我需要搜索特定时间戳的特定数据集 假设我有以下数据: 对于时间戳1407633943: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) 等等 我想快速提出以
- (0,24,581407633943)
- (9,2,591407633943)
- (40,1,331407729456)
- (3,5,71407729456)
谢谢。kd树在这里很有用。kd树中的范围搜索是一个众所周知的问题。当然,一个查询的时间复杂度取决于输出大小(在最坏的情况下,如果所有向量都匹配,则将遍历所有树)。但平均来说,它可以运行得相当快。我会使用。在每个节点中,我将使用时间戳作为键,将向量数组存储在一个数组中
为了进一步提高性能,您可以使用CUDA、OpenCL、OpenACC、OpenMP,并在GPU或多核CPU上实现并行执行的算法 BKaun:请接受我的尝试,让你对眼前的问题有所了解。我想你已经想到了我的每一点,但也许在这里看到它们会有所帮助
不管如何呈现数据,请考虑使用C编程语言,可以减少数据的存储大小,以最小化空间和搜索时间。您将搜索、加载和解析向量的单个位,而不是一个短INT(每个条目有2个字节)或一个更大的FLOAT。据我所知,目标是在给定的数据中搜索给定的X、Y和Z值,然后在优化搜索的同时找到与这3个值关联的时间戳。我的解决方案不涉及搜索,而只是搜索中使用的数据
为了简单地说明我的提示,我认为数据由4个向量组成:考虑到您将以这种优化的格式存储数据,在一个 位序列: 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.