PHP - 优化在Array中查找最近点

时间:2016-03-08 12:11:20

标签: php arrays algorithm math voronoi

我创建了一个脚本,它获取了大量的点,然后根据有限的一组选定点找到3D空间中最近的点。它很棒。然而,有时我得到超过200万点与256个项目的数组进行比较,因此超过 5.3亿次计算!这需要相当多的时间和力量(考虑到这将是比较的东西像那几分钟一样。)

我有一组有限的3D坐标:

array (size=XXX) 
0 => 10, 20, 30
1 => 200, 20, 13
2 => 36, 215, 150
3 => ...
4 => ...
... // this is limited to max 256 items

然后我有另一个非常大的组,比方说,随机3D坐标,其大小可以从2,500变化 - >约2,000,000件物品。基本上,我需要做的是遍历每个点并找到最接近的点。要做到这一点,我使用欧几里德距离:

平方((Q <子> 1 -p <子> 1 2 +(Q <子> 2 -p <子> 2 2 +(q <子> 3 -p <子> 3 2

这给了我距离并将其与当前最近距离进行比较,如果距离较近,则替换最近距离,否则继续下一组距离。

我一直在研究如何改变它,所以我不必做那么多计算。我一直在看Voronoi Diagrams然后将点放在该图中,然后查看它属于哪个部分。但是,我不知道如何在PHP中实现这样的东西。

知道如何优化它吗?

1 个答案:

答案 0 :(得分:1)

从臀部快速射击; - )

如果你不将每个点与另一个点相比较,你应该能够获得很好的加速。可以跳过很多点,因为如果只看一个x / y / z坐标,它们已经很远了。

<?php
$coord = array(18,200,15);

$points = array(
    array(10,20,30),
    array(200,20,13),
    array(36,215,150)   
);


$closestPoint = $closestDistance= false;;

foreach($points as $point) {
    list($x,$y,$z) = $point;

    // Not compared yet, use first poit as closest
    if($closestDistance === false) {
        $closestPoint = $point;
        $closestDistance = distance($x,$y,$z,$coord[0],$coord[1],$coord[2]);
        continue;
    }

    // If distance in any direction (x/y/z) is bigger than closest distance so far: skip point
    if(abs($coord[0] - $x) > $closestDistance) continue;
    if(abs($coord[1] - $y) > $closestDistance) continue;
    if(abs($coord[2] - $z) > $closestDistance) continue;

    $newDistance = distance($x,$y,$z,$coord[0],$coord[1],$coord[2]);

    if($newDistance < $closestDistance) {
        $closestPoint = $point;
        $closestDistance = distance($x,$y,$z,$coord[0],$coord[1],$coord[2]);
    }       
}

var_dump($closestPoint);

function distance($x1,$y1,$z1,$x2,$y2,$z2) {
    return sqrt(pow($x1-$x2,2) + pow($y1 - $y2,2) + pow($z1 - $z2,2));
}

可以在http://sandbox.onlinephpfunctions.com/code/8cfda8e7cb4d69bf66afa83b2c6168956e63b51e

找到工作代码示例