有没有办法优化这种搜索方法?
for (var i=0;i<dots.length;i++) {
var blist = [];
for (var n=0;n<dots.length;n++) {
if (dots[n][1]>(dots[i][1]-90)
&& dots[n][1]<(dots[i][1]+90)
&& dots[n][2]>(dots[i][2]-90)
&& dots[n][2]<(dots[i][2]+90)) {
if (!(n === i)) blist.push(n);
}
}
dots[x][1]
是x坐标,dots[x][2]
是y坐标。
我有1000个点,需要找到每个点周围的点,以便产生
if (dots[n][1]>(dots[i][1]-90)
&& dots[n][1]<(dots[i][1]+90)
&& dots[n][2]>(dots[i][2]-90)
&& dots[n][2]<(dots[i][2]+90))
每秒运行一百万次,有没有办法对此进行优化?
答案 0 :(得分:1)
也许尝试使用像这样的点数据结构
var Dot = function(){
var x = 0;
var y = 0;
var Up;
var Right;
var Left;
var Down;
function init(xVal,yVal)
{
x = xVal;
y = yVal;
}
function GetUp()
{
return Up;
}
function SetUp(UpDot)
{
Up = UpDot;
}
return
{
init: init,
GetUp: GetUp,
SetUp: SetUp
};
};
然后像这样使用它
var Dots = [];
var firstDot = new Dot();
Dots.push(firstDot);
var secondDot = new Dot();
secondDot.init(0,90);
secondDot.SetUp(firstDot);
Dots.push(secondDot);
显然,需要添加和配置更多以匹配您的情况。然而,这将允许你做的是迭代点,然后检查天气存在一个近点,使时间O(n)而不是O(n ^ 2),从而节省你900,000支票。
答案 1 :(得分:0)
将时间缩短一半的一种方法是不要仔细检查每一对:
for (var i = 0, len = dots.length; i < len - 1; i++) {
var blist = [];
for (var n = i + 1; n < len; n++) {
if (dots[n][1]>(dots[i][1]-90)
&& dots[n][1]<(dots[i][1]+90)
&& dots[n][2]>(dots[i][2]-90)
&& dots[n][2]<(dots[i][2]+90)) {
blist.push(i);
blist.push(n);
}
}
}
注意循环边界的变化。这允许我只检查每对,并跳过(n === i)
检查。
我也会缓存dot.length
,这可能不是什么大问题,但值得做一个紧凑的循环。
不过,这应该是超过50%的改善。虽然这可能有所帮助,但这并不是这类问题可能需要的数量级变化。
答案 2 :(得分:0)
这是一个解决方案的草图。这可能与TravisJ建议的想法相同,尽管我不清楚。它实际上只是一个草图,并将采用重要的代码来实现。
如果将空间划分为90个单位x 90个单位区域,则特定区域中的点只能足够接近该区域中的点或该区域的八个邻居之一中的点。这可以显着减少您需要比较的对数。成本当然是算法的复杂性:
Math.floor(something / 90)
操作。我没有测试过这个,除了在我脑海里。它应该工作,但我没有尝试编写任何代码。代码不会是微不足道的。我不认为这是几个星期的工作,但也不是几分钟内鞭打在一起的东西。
我相信它可以显着提高速度,但这取决于有多少匹配,有多少个点相对于部分的数量。