请教一个二进制串查询的问题

dbhme 2014-10-28 04:51:49
128位的二进制‘0’、‘1’串,当然也可以看成是一个128位的整数
数量在1G到10G,数据相对稳定,可以对这些数据进行预处理,预处理的结果允许最多到原始数据10倍左右空间,也就是10G*128/8 = 160G
可用内存在8G左右
给定一个128位串,从里面查找完全匹配的串,或K位不匹配其他位匹配的串(1<=k<=4)
怎么样对数据进行预处理才能查询速度快。
...全文
389 27 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
冥王之锤 2014-11-06
  • 打赏
  • 举报
回复
完全匹配: 1.排序之后二分查找,速度很快。 K位不匹配其他位匹配的串(1<=k<=4): 2.可把不配备的位补全,只能是0,1,就变成了第一个完全匹配的问题。由于k很小,最多2^4=16次找全。
绿色夹克衫 2014-11-04
  • 打赏
  • 举报
回复
好久不来csdn了,感谢邀请,我只说我支持Fancymouse的方法,因为前段时间别人问我的时候,我说的方法也是差不多的,建立01的Trie。另外,还有个思路就是对所有数据执行c(128,k),预处理好了(虽然很慢),但后面每次查询就是O(Solution)的了。
FancyMouse 2014-11-04
  • 打赏
  • 举报
回复
>这在128位范围内怎么也达不到平均分布命中覆盖所有分块的地步。 我从来就没有说你全覆盖原数据,我是说你全覆盖C(128,k)个查询。你即使每一次查询都飞快(就假设1个指令),但是你依然要做C(128,k)次这样的操作,我从头开始就是说你慢是慢在这里。 不理解这点不再回。谢谢。
dianyancao 2014-11-04
  • 打赏
  • 举报
回复
c(128,k)是聚类操作?聚类后的Solution的大小和原来的数据量n是什么关系呀?
zhouxiaofeng1021 2014-11-03
  • 打赏
  • 举报
回复
128位的二进制‘0’、‘1’串,当然也可以看成是一个128位的整数 数量在1G到10G,数据相对稳定, 不需要预处理这些数据 可用内存在8G左右 给定一个128位串,从里面查找完全匹配的串,或K位不匹配其他位匹配的串(1<=k<=4) 怎么样对数据进行预处理才能查询速度快。 10G = 10*1024*1024*1024/128 个数据 = 83886080个数据 每次读取512M数据 一边读数据一边异或操作 1.查找查找完全匹配的串用位运算异或 为0即可 2.查找K位不匹配其他位匹配的串用位运算异或 只要计算有多少个1即可,用位移操作与自己进行位运算 O(K) k个1
Tiger_Zhao 2014-11-03
  • 打赏
  • 举报
回复
假定原值是全0好了,K=4就是只有4位1,这在128位范围内怎么也达不到平均分布命中覆盖所有分块的地步。
难道只有二叉树才能剪枝;数组就不能按照分块的最大最小值直接跳过,非得来个全遍历你才满意。
dianyancao 2014-11-01
  • 打赏
  • 举报
回复
引用 20 楼 FancyMouse 的回复:
这数据没有2D结构,你真的要说的话这是个128维的0/1空间。但是K-D树高维就变蠢这是公认的事实。高维大概高到十几就不太行了。
嗯,和平衡二叉树一样呢,就是每次选择一个当前方差最大的维度作为数据的划分基准,用到一定内存后,加载磁盘中的余下对应数据到剩余内存用异或指令加查表来匹配
FancyMouse 2014-11-01
  • 打赏
  • 举报
回复
>(k=4时占160M以上),把这些反转数排序,逐个去查找。 这不是你自己说的吗?160M以上逐个去查找。你这160M的查找你只有两种选择,1是逐个在原表里精确查找,2是用类似归并的办法和原表进行一次全表扫描。无论怎么做,160M的数据每一个都要看一遍是逃不掉的。这本身就奇慢无比,你再怎么改也改不了的。 但是实际上128位k值<=4的每次查询能有几个?输入数据均匀随机的时候绝大多数情况下都只有1个解。二叉树分支一砍剩下几千个解都算多了。从几千个里找对比160M哪个快? >我#1自认为应该是描述清楚了的 >原来#1写了没人看的! 我自始自终都在说你k>=1的解法奇慢。k=0精确匹配那个随便怎么做都一样,所以#1精确匹配那块我的确没看。 >你在对8*16的二值图像分类,为什么不用K-D树来做呢? 这数据没有2D结构,你真的要说的话这是个128维的0/1空间。但是K-D树高维就变蠢这是公认的事实。高维大概高到十几就不太行了。
dianyancao 2014-10-31
  • 打赏
  • 举报
回复
你在对8*16的二值图像分类,为什么不用K-D树来做呢?
Tiger_Zhao 2014-10-31
  • 打赏
  • 举报
回复
我#1自认为应该是描述清楚了的:
有序数组,切块,每块的最大最小在内存中有索引。
找一个数先搜索引确定块号,再在对应块号中搜,最多只需加载一块啊!

树是要分多层搜子树的,加载的不止一个子树啊!
Tiger_Zhao 2014-10-31
  • 打赏
  • 举报
回复
原来#1写了没人看的!
K4的数先排序再搜索。
FancyMouse 2014-10-31
  • 打赏
  • 举报
回复
k=1,查询是0000开头的时候,那二叉树下去就只会搜0000 0001 0010 0100 1000开头的子树。其他所有子树看都不看。这个暴力能比?做二叉树的要点就是不会搜所有数据。如果数据全部可以进入内存的话,那甚至不会有额外开销:不是解的数据根本就不会搜到。鉴于需求一般是输出数据远小于全体数据,这个比暴力提升的不是一两个数量级的事。
FancyMouse 2014-10-31
  • 打赏
  • 举报
回复
k=4你打算C(128,4)大约1kw次查询?只支持精确查询的结构一开始就淘汰了。
Tiger_Zhao 2014-10-30
  • 打赏
  • 举报
回复
问题是子树的个数太多了啊!划分越细索引就越大。
如何给不定划分的子树定一个KEY?
做缓存时又如何判断某个子树是否在缓存中?
FancyMouse 2014-10-30
  • 打赏
  • 举报
回复
又没说二叉树全放内存。子树大小在几百个数量级的时候直接存磁盘上基本就够了。这么灵活的数据结构,内存限制怎么可能是问题。
dbhme 2014-10-30
  • 打赏
  • 举报
回复
直接128层搞成个二叉树,内存怕是不够用
Tiger_Zhao 2014-10-30
  • 打赏
  • 举报
回复
二叉树一个节点两指针,64位下就是16字节。
而数据 10G / 16 ≈ 6.7亿个叶子。
这个二叉树该怎么缓存、查找?
FancyMouse 2014-10-30
  • 打赏
  • 举报
回复
与其4层不如直接128层搞成个二叉树。每一层下去就能把k超过的那些分支全砍掉,剩下的就都是需要的。
Tiger_Zhao 2014-10-30
  • 打赏
  • 举报
回复
无规则分布的数,你没法用缩减34bit来表示。
如此稀疏的数,可能10G内容就全在一个子段中,如何加载?

所以按数量平均切段,记下每段的最大最小值做索引,应该是比较合理的。
我现在是一层索引,也可以做成多层索引,让块更小、缓存的块数更多,适合同时有多个匹配请求的情况。
dbhme 2014-10-30
  • 打赏
  • 举报
回复
引用 4 楼 Tiger_Zhao 的回复:
你算错了吧! 3层就是 96 位,如果用 BitMap 索引, 2^96 / 8 / (1024^4) ≈ 9E15 G,这个怎么“载入内存”? 我最初也是考虑用 BitMap 匹配的,但是一算数据量,只能放弃了。
128bit对应到10G数据,应该是很稀疏的,10G数据相当于34bit长,平均下来每个表有9bit也就是512大,当然实际上有些表会大很多。 所以每层的32bit数据总数也不会太多,每层的表不会占很多的,这个32bit值可以在表中排序存放,因为在内存中,二分查找也很快的。
加载更多回复(7)

33,027

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧