public function testFindClosestCentroid()
 {
     $x = array(1, 1, 1, 1);
     $centroids = array(array(2, 2, 2, 2), array(3, 3, 3, 3), array(4, 4, 4, 4), array(5, 5, 5, 5), array(1, 3, 3, 5), array(1, 6, 7, 8), array(9, 9, 9, 9), array(100, 100, 100, 100));
     $this->assertEquals(0, _ll_closest_centroid($x, $centroids));
     for ($i = 0; $i < 100; $i++) {
         shuffle($centroids);
         $expected = array_search(array(2, 2, 2, 2), $centroids);
         $this->assertEquals($expected, _ll_closest_centroid($x, $centroids));
     }
     $x = array(100, 100, 100, 100);
     $expected = array_search(array(100, 100, 100, 100), $centroids);
     $this->assertEquals($expected, _ll_closest_centroid($x, $centroids));
     $x = array(6, 4, 6, 4);
     $expected = array_search(array(5, 5, 5, 5), $centroids);
     $this->assertEquals($expected, _ll_closest_centroid($x, $centroids));
 }
function ll_kmeans($xs, $k)
{
    if ($k > count($xs)) {
        return false;
    }
    $centroids = _ll_init_centroids($xs, $k);
    $belongs_to = array();
    do {
        for ($i = 0; $i < count($xs); $i++) {
            // I reversed the order here (to store the centroids as indexes in the array)
            // for complexity reasons.
            $belongs_to[_ll_closest_centroid($xs[$i], $centroids)][] = $i;
        }
        $old_centroids = $centroids;
        $centroids = _ll_reposition_centroids($centroids, $belongs_to, $xs);
        $continue = $old_centroids == $centroids;
    } while ($continue);
    return $belongs_to;
}