我有1个源编号设置(或矢量),其中50个整数介于1和100之间 (=具有50个特征在1到100之间的轮廓)
我有1,000,000个目标编号集(或矢量),每个都有50个整数 (= 1M更多此类配置文件)
我想通过与Source集的相似性来订购1,000,000个目标集 (=我想浏览最好到最差的比赛)
我希望例程在< 1秒内返回有序列表(从Web应用程序触发,返回到笔记本电脑和/或移动设备) (=最终用户的性能要求)
即使在针对不同的源编号集同时提交了100个类似的请求时,我希望例程执行此操作 (=支持并发用户)
上述数字用于表示比例。我可能会在集合中添加更多整数(添加新特性)或更多目标集(更多配置文件)或更多并发请求(更多并发用户),但现在这很好
如果有帮助,我很高兴将结果聚集在桶中。即前10,000名成绩排名前1%。接下来10,000个会产生前2%的桶,等等。我不一定关心每个这样的桶中的订单(对于最终用户来说太过细化以保证任何额外的性能投资)。
同样地,因为最终用户永远不会在他们的UI中容纳1,000,000个结果,所以如果算法以某种方式仅返回较小的返回子集(例如 - 仅匹配顶部匹配),我很高兴。但进一步浏览仍应以高效的方式加载列表的其余部分。
实际用例;想象一个约会应用程序,要求最终用户在滑动条上评价它们对它们有多重要的50个特征。应用返回最佳匹配的位置,在您进行修改时更新为“实时”。
哪种技术/类型的算法最适合满足此要求?
初始尝试使用Squared Euclidean Distance,但考虑到数据大小和性能要求,这证明资源过于密集。 理想情况下,给定特征的较大差异确实会带来更多权重(就像使用平方欧几里德距离法时那样)
答案 0 :(得分:0)
如果你真的需要这种表现,我认为你需要放弃一个完整的特征到特征的比较。 2种可能性:
1)首先(或仅)进行所有特征总和比较。这可以很快,因为它可以在您的目标集上预先计算/预先索引。根据我的估计,你可以得到大约200-400个目标,其平均来源的总和相同。 (大约200-400个目标,总和一个更大,200-400个目标,总和少一个,等等)。然后,您可以(可选)查看这些较小的"部分"对于特征的更近/更远的匹配。
2)在这种类型的典型问题中,"并非所有特征都相同"。如果可以的话,考虑一下<<<<<<<2" key"特征,全局或变化的每个查询/用户(或两者中的一些)。同样,目标集可以在那些(或它们的总和)上预先索引以获得速度。
比解决方案更多的建议,但是fwiw ......
答案 1 :(得分:0)
使用曼哈顿距离(而不是欧氏距离平方)和500,000套(而非1mil)我在IE11(客户端)获得约700ms的时间。服务器端我看不出为什么你不能得到第二个处理时间的原因。
JSFiddle http://jsfiddle.net/66mwupqn/
function makeSets(size) {
var result = [];
for(var i=0; i<size; i++) {
var row = []
for(var j=0; j<50; j++) {
row[j] = Math.floor(Math.random() * 100) + 1;
}
result[i] = row;
}
return result;
}
function sortSets(value, collection) {
for(var i=0; i<collection.length; i++) {
var score = 0;
for(var j=0; j<50; j++) {
score += Math.abs(collection[i][j] - value[j]);
}
collection[i].score = score;
}
return collection.sort(function(a,b){return b.score-a.score;});
}
var list = makeSets(500000);
var value = makeSets(1)[0];
var t = Date.now();
var result = sortSets(value, list);
t = Date.now() - t;
alert("Time (ms) : " + t + ", Result (scores) : " + result[0].score + " - " + result[result.length-1].score);
我正在使用性能糟糕的 Array.prototype.sort 。使用就地快速排序我可能会第二次使用客户端JavaScript。
编辑 1100毫秒,每组得分和排序1百万套50个值(1-100),计算每组的曼哈顿距离得分与值,JSFiddle http://jsfiddle.net/5gc37jmb/在i5 5200U处理器(不是电源芯片)上进行快速排序。
如果低功耗笔记本电脑上的JavaScript可以做到这一点,我就看不出为什么服务器会有任何问题