2

先月、私はフォトモザイクのWebサイトに取り組んでいます。私はすべてをPHPで構築し、それをうまく機能させました。私が嫌いなのは実行時間だけです。線形比較検索のため、これは長すぎると思います。それで、私は検索時間を改善する方法について尋ねてきました、そしてほとんどの人は私をKDツリーの方向に向けました。それはk最近傍をはるかに速くします。

だから私はKDツリーを調べていて、そのようなツリーを手動で構築する方法を理解しています。もちろん、これをコーディングしたいのですが、C++とJavaのライブラリしか見つかりませんでした。私はPHPに精通しているだけなので、自分でPHPを作成しようとしていますが、これは思ったほど簡単ではありません。

•私が直面している問題は、すべてをどのように保存するかです。すべてのポイントを含む最初の配列を取得したら、それを3つに分割します。左ブランチ、ノード、右ブランチ。もちろん、分割できなくなるまで左のブランチでも同じことを行います。もちろん、軸(XYZ)を循環します。しかし、すべての正しいブランチをどのように格納しますか?それらを配列のままにしますか?または、使用する準備ができたら、もう一度計算しますか?

•私が疑問に思っていたもう1つのことは、PHPがこの仕事に適した言語ではないため、なぜPHPKDツリースクリプトがないのかということです。

これは私がこれまでに得たものです。

この関数は、残りをテストするために使用するランダムカラー(RGB)を計算します。

<?php
function randomiser($number){

    if($number <= 0){ 
        echo 'Error: The input of randomiser() is less than or equal to zero !!';
        return FALSE;         
    }else{ 
        $R = array();
        $G = array();
        $B = array();

        for($x = 1; $x <= $number; $x++){
            $r = rand(1, 255);
            $g = rand(1, 255);
            $b = rand(1, 255);

            $rgb['pic ' . $x]['R'] = $r;
            $rgb['pic ' . $x]['G'] = $g;
            $rgb['pic ' . $x]['B'] = $b;    
        }  
    }
return $rgb;
}
?>

この関数は、特定のキーで多次元配列を並べ替えます(デフォルトはR)

<?php
function sorter(&$array, $key = 'R'){

    if(!is_array($array)){ 
        echo 'Error: The input of sorter() is not an array !!<br>';
        return FALSE;         
    }else{ 
        uasort($array, function ($a, $b) use ($key){
            return strnatcmp($a[$key], $b[$key]);
        }); 
    }
}
?>

このクラスは、配列を左ブランチ、ノード、および右ブランチに分割します。

<?php
class splitting {

    public $left;
    public $node;
    public $right;

    function __construct($array){

        if(!is_array($array)){ 
            echo 'Error: The input of splitter() is not an array !!<br>';
            return FALSE;         
        }else{ 
            $number = count($array);
            $median = round($number / 2) - 1; 

            $this->left = array_slice($array, 0, $median);
            $this->node = array_slice($array, $median, 1);
            $this->right = array_slice($array, $median+1);
        }
    }
}
?>
4

1 に答える 1

0
  1. ツリーへのポインターを $left および $right 変数に格納する必要があります。配列や操作する必要のある変数ではありません。kd ツリーが複雑すぎる場合は、r ツリーも調べます。r-tree は平面を 4 つのエッジに分割します。つまり、真の 2 ユークリッド次元であり、kd-tree は単なるバイナリ ツリーです。次に、中央値をバックアップする変数 $payload または何かが必要です。
  2. いいえ。php ツリーの例も見つけることができます。以下に例を示します: http://blog.sandfox.co.uk/2012/09/10/php-kdtree/。php で私のカート トライ実装を探すこともできます。OO とノードとエッジ クラスも使用します。http://www.blackpawn.com/texts/lightmaps/default.htmlからライトマップを kd ツリーにパックするスクリプトを次に示します。

     struct Node
    {
         Node* child[2]
         Rectangle rc
          int imageID
     }
    
    Node* Node::Insert(const Image& img)
          if we're not a leaf then
          (try inserting into first child)
           newNode = child[0]->Insert( img )
          if newNode != NULL return newNode
    
     (no room, insert into second)
          return child[1]->Insert( img )
      else
    (if there's already a lightmap here, return)
    if imageID != NULL return NULL
    
    (if we're too small, return)
    if img doesn't fit in pnode->rect
        return NULL
    
    (if we're just right, accept)
    if img fits perfectly in pnode->rect
        return pnode
    
    (otherwise, gotta split this node and create some kids)
    pnode->child[0] = new Node
    pnode->child[1] = new Node
    
    (decide which way to split)
    dw = rc.width - img.width
    dh = rc.height - img.height
    
    if dw > dh then
        child[0]->rect = Rectangle(rc.left, rc.top, 
                                   rc.left+width-1, rc.bottom)
        child[1]->rect = Rectangle(rc.left+width, rc.top, 
                                   rc.right, rc.bottom)
    else
        child[0]->rect = Rectangle(rc.left, rc.top, 
                                   rc.right, rc.top+height-1)
        child[1]->rect = Rectangle(rc.left, rc.top+height, 
                                   rc.right, rc.bottom)
    
    (insert into first child we created)
    return Insert( img, pnode->child[0] )
    
于 2012-12-18T12:17:01.740 に答える