有一个非常难的问题,求解答,高维数据求欧式距离加速

grf9527 2018-03-16 01:43:39
加精
假设有4亿个100维度的点,近似均匀的分布在100维空间中。
现在给定一个点,是100维空间中的一个点,如果才能快速的找到距离给定的点最近的点。

可以提前处理4亿个点。建立类似结构化数据库中的索引。

也可以考虑任何加速措施。


有合适思路和方法的人,本人请吃饭(1000以内),也可提供一份工作。
...全文
6465 47 打赏 收藏 转发到动态 举报
写回复
用AI写文章
47 条回复
切换为时间正序
请发表友善的回复…
发表回复
pywee 2019-05-12
  • 打赏
  • 举报
回复
不对,详细看了一下你的场景,这种不是动态规划,这种是skip-list类似的场景,你搜索跳表法,就知道该如何做了。
pywee 2019-05-12
  • 打赏
  • 举报
回复
你这种应该用动态规划算法去求解了,而不是什么欧式距离海明距离之类的小算法。
flybirding10011 2018-07-25
  • 打赏
  • 举报
回复
引用 12 楼 ypgsh的回复:
先标准化,所有点减去目标点,将问题变成求各个点中离原点(长度)最近的点。 任意取一点,计算其长度,循环剩余点找出点各个维度值都小于该长度点的集合,再到该集合中任意取一点,该点长度小于前一个长度。再迭代找集合,直到找的集合为空,或集合点长度都大于上一个长度
grf9527 2018-07-23
  • 打赏
  • 举报
回复
引用 49 楼 weixin_41582088 的回复:
[quote=引用 40楼流浪小狗 的回复:]可以采用多维立方体编码索引树。一般需要先搞清楚每个维度的散列程度。但由于您说是“均匀分布”的,所以,肯定是散列的,认为是均匀的。
索引生成:
1、把浮点坐标值进行第一次编码(量化),形成整形坐标值。

K = 65536;//可以酌情增减
//这里用for示意一下,其实可能需要磁盘吞吐,因为内存装不下。
for (uinsigned long long i = 0; i < 400000000;++i)
for (unsigned int j = 0; j<100;++j)
N[i][j] = int (x[i][j] / K);

这样的效果,使得坐标成为了以K一个格子的离散坐标。

-192373.384, 2827, 0.28374, 7932736.28374... 383742
->
-3 0 0 121,....,5


2、建立维度索引
维度索引共100组,每个维度1组。每组4亿行,按照本组的坐标值、实际数据行号存储。
比如,第58维度索引如下:

……
val, rowidx
-2, 38374
-1, 292739047
-1 ,2837439
0, 943847274
1, 283
……

也可以用树形结构存储,或者直接进入数据库。

计算:
计算离散坐标的欧式距离,转化为整形坐标的差异。前提是K取得足够大,使得无论定义域内给定一个值,在以2K+1为边长的超立方体内,都有超过1个的向量存在。
假设数据为
38419,-28384,...2834999
1、从第一组索引表中,select 出所有与本维度整数坐标距离小于2的行号

select rowidx from tb_idx1 where val >= 38418 and val <=38420;

2、从第二组索引表中,select 出所有与本维度整数坐标距离小于2的行号

select rowidx from tb_idx2 where val >= -28385 and val <=-28383 and
rowidx in (填写1的结果)
;

3、以此类推,直到100维度为止。

这时,剩下的行号应该不多了,再去直接用浮点计算。
目前最靠谱的答案。没看你的代码,思路是ok的,需要优化。 考虑下各个叶子结点的深度不一样,需要路径上碰到叶节点也考虑进去。[/quote]强烈建议先整理思路,维度爆炸是关键。在维度较小时,这个问题并不严重,多了,才开始严重起来
grf9527 2018-07-23
  • 打赏
  • 举报
回复
引用 34 楼 jiangtao_yuan 的回复:
google搜索试一下
google无解
weixin_41582088 2018-07-11
  • 打赏
  • 举报
回复
引用 40楼流浪小狗 的回复:
可以采用多维立方体编码索引树。一般需要先搞清楚每个维度的散列程度。但由于您说是“均匀分布”的,所以,肯定是散列的,认为是均匀的。 索引生成: 1、把浮点坐标值进行第一次编码(量化),形成整形坐标值。

      K = 65536;//可以酌情增减
      //这里用for示意一下,其实可能需要磁盘吞吐,因为内存装不下。
      for (uinsigned long long i = 0; i < 400000000;++i)
           for (unsigned int j = 0; j<100;++j)
                 N[i][j] = int (x[i][j] / K);
这样的效果,使得坐标成为了以K一个格子的离散坐标。

 -192373.384,  2827, 0.28374, 7932736.28374... 383742 
->
-3	0	0	121,....,5
2、建立维度索引 维度索引共100组,每个维度1组。每组4亿行,按照本组的坐标值、实际数据行号存储。 比如,第58维度索引如下:

   ……
   val, rowidx
   -2, 38374
   -1, 292739047
   -1 ,2837439
   0, 943847274
   1, 283
   ……
也可以用树形结构存储,或者直接进入数据库。 计算: 计算离散坐标的欧式距离,转化为整形坐标的差异。前提是K取得足够大,使得无论定义域内给定一个值,在以2K+1为边长的超立方体内,都有超过1个的向量存在。 假设数据为 38419,-28384,...2834999 1、从第一组索引表中,select 出所有与本维度整数坐标距离小于2的行号

   select rowidx from tb_idx1 where val >= 38418 and val <=38420;
2、从第二组索引表中,select 出所有与本维度整数坐标距离小于2的行号

   select rowidx from tb_idx2 where val >= -28385 and val <=-28383 and 
         rowidx in (填写1的结果)
        ;
3、以此类推,直到100维度为止。 这时,剩下的行号应该不多了,再去直接用浮点计算。
目前最靠谱的答案。没看你的代码,思路是ok的,需要优化。 考虑下各个叶子结点的深度不一样,需要路径上碰到叶节点也考虑进去。
长安一片月噢 2018-07-03
  • 打赏
  • 举报
回复
格理论?格中最近向量问题?
l_0_f 2018-06-23
  • 打赏
  • 举报
回复
大神膜拜,表示不懂啊。
NinjaYinJey 2018-06-23
  • 打赏
  • 举报
回复
想获取所有最近点,只需将s矩阵转置即可。转置请参考《线性代数》。
NinjaYinJey 2018-06-23
  • 打赏
  • 举报
回复


var s = [4B][1H],i = 0,t = 1,x = 0,c = 1H,r = 4B,j = [c],k = [c];

function g(d) {
for(i = 0; i < c; i++) {
j[i] = t / d;
}
i = 0;
}

function f() {
for(x = 0; x < c; x++) {
for(i = 0 i < r; i++) {
k[x] += j[x] * s[r][x];
}
}
x = 0;
return k;
}

g(1K);f();

shiter 2018-06-01
  • 打赏
  • 举报
回复
引用 42 楼 grf9527 的回复:
大家继续发言,我相信很多人自己已经知道自己的设计有问题了。
高手来指点一下
grf9527 2018-05-31
  • 打赏
  • 举报
回复
大家继续发言,我相信很多人自己已经知道自己的设计有问题了。
丁劲犇 2018-05-05
  • 打赏
  • 举报
回复
其实,如果把离散坐标存储到一个表里: rowidx val1 val2 ... val100 就可以直接利用数据库的查询语句 select rowidx from indextable where val1>= 38418 and val1 <=38420 and val2 >= -28385 and val2 <=-28383 and ... and val100 >=2834998 and val100<=2835000 选取的。 4亿条,其实就是 400MB个记录,其实不大的。可以用 postgresql 按照val1分区存储,非常的快。
丁劲犇 2018-05-05
  • 打赏
  • 举报
回复
可以采用多维立方体编码索引树。一般需要先搞清楚每个维度的散列程度。但由于您说是“均匀分布”的,所以,肯定是散列的,认为是均匀的。 索引生成: 1、把浮点坐标值进行第一次编码(量化),形成整形坐标值。

      K = 65536;//可以酌情增减
      //这里用for示意一下,其实可能需要磁盘吞吐,因为内存装不下。
      for (uinsigned long long i = 0; i < 400000000;++i)
           for (unsigned int j = 0; j<100;++j)
                 N[i][j] = int (x[i][j] / K);
这样的效果,使得坐标成为了以K一个格子的离散坐标。

 -192373.384,  2827, 0.28374, 7932736.28374... 383742 
->
-3	0	0	121,....,5
2、建立维度索引 维度索引共100组,每个维度1组。每组4亿行,按照本组的坐标值、实际数据行号存储。 比如,第58维度索引如下:

   ……
   val, rowidx
   -2, 38374
   -1, 292739047
   -1 ,2837439
   0, 943847274
   1, 283
   ……
也可以用树形结构存储,或者直接进入数据库。 计算: 计算离散坐标的欧式距离,转化为整形坐标的差异。前提是K取得足够大,使得无论定义域内给定一个值,在以2K+1为边长的超立方体内,都有超过1个的向量存在。 假设数据为 38419,-28384,...2834999 1、从第一组索引表中,select 出所有与本维度整数坐标距离小于2的行号

   select rowidx from tb_idx1 where val >= 38418 and val <=38420;
2、从第二组索引表中,select 出所有与本维度整数坐标距离小于2的行号

   select rowidx from tb_idx2 where val >= -28385 and val <=-28383 and 
         rowidx in (填写1的结果)
        ;
3、以此类推,直到100维度为止。 这时,剩下的行号应该不多了,再去直接用浮点计算。
worldy 2018-05-03
  • 打赏
  • 举报
回复
引用 37 楼 shiyanbo_1006 的回复:
叫蚂蚁自己趴着去纽约,叫蚂蚁做A380去纽约
可能可以通过虫洞爬过去呢?
跟随我 2018-05-03
  • 打赏
  • 举报
回复
我只想说,牛牛牛
待续_1006 2018-05-02
  • 打赏
  • 举报
回复
叫蚂蚁自己趴着去纽约,叫蚂蚁做A380去纽约
AHTY 2018-04-30
  • 打赏
  • 举报
回复
这问题,只要能再二维数组上解决,就能通样在100维组上解决,这只是计算量的问题,是量变 普通单个CPU可能需要几十年,但是用超级计算机,只要几分钟
jiangtao_yuan 2018-04-27
  • 打赏
  • 举报
回复
google搜索试一下
qq_42078393 2018-04-26
  • 打赏
  • 举报
回复
找银河二号算吧
加载更多回复(27)

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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