kb84tkhrのブログ

何を書こうか考え中です あ、あと組織とは関係ないってやつです 個人的なやつ

DSL_2_C: Range Search (kD Tree) (続き4)

で自作データでやってたらバグが見つかったという
境界となる点を求めるのにこんな関数を使っていたんだけれども

def find_mid(points, indices, dir):
    return points[indices[len(indices) // 2]][dir]

これだとたとえば3つの点のx座標が2,2,3だったとき、境界が2になって
境界で分けたときに[]と[2,2,3]に分かれてしまう
これはよくない
ていうか運が悪くてy座標も2,2,3だったりすると無限ループ

えーとちゃんとやるにはと
ユニークな値だけ集めてから境界値?
こう?

def find_mid(points, indices, dir):
    s = sorted(set(points[x][dir] for x in indices))
    return s[len(s)//2]

これでまた遅くなるわけだな
Case #12が04.28sに(涙

いやそもそも
同一座標の点がふたつあったらそれで無限ループになってしまうな
そう思って読み直すと同じ座標の点が含まれてないとは書いてない

・・・判定入れてもいいけどそこって大事じゃない気がするな
同一の点は含まないことにしておこう

それより、indicesをソートしたりユニークな値を拾ったりと
手間をかけて真ん中を探すっていうのが方向違いなのかも知れない
クイックソートだって先頭から取ってる例が多いし
ただ今回は適当にやると無限ループになるからそこは考慮しないといけない
ということでランダムな要素を選ぶことに(てきとう
検索には時間がかかるようになると思うけど
前処理がうんと速くなればペイするかも

def find_mid(points, indices, dir):
    return points[indices[randrange(len(indices))]][dir]

だめでした #12で3.64s

プロファイルはこんな感じ
前処理が期待したほど速くなってないなあ
検索がほぼ2倍時間かかるように

         15162931 function calls (8418353 primitive calls) in 17.954 seconds

   Ordered by: cumulative time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000   17.848   17.848 DSL_2_C.py:144(main)
        1    0.127    0.127   11.780   11.780 DSL_2_C.py:133(process_queries)
    10000    0.013    0.000    9.964    0.001 DSL_2_C.py:102(find_points)
6499980/10000    9.377    0.000    9.435    0.001 DSL_2_C.py:106(rec)
        1    0.004    0.004    5.740    5.740 DSL_2_C.py:87(make_area_tree)
 254556/1    0.600    0.000    5.736    5.736 DSL_2_C.py:57(divide_area)
   254555    1.296    0.000    3.252    0.000 copy.py:66(copy)
    20000    1.634    0.000    1.634    0.000 {built-in method builtins.print}
   154566    0.964    0.000    1.256    0.000 DSL_2_C.py:46(partition)
   254555    0.521    0.000    1.187    0.000 copy.py:268(_reconstruct)
   154566    0.139    0.000    0.585    0.000 DSL_2_C.py:40(find_mid)
    10000    0.515    0.000    0.515    0.000 {method 'sort' of 'list' objects}
   154566    0.148    0.000    0.425    0.000 random.py:173(randrange)
  3020410    0.364    0.000    0.364    0.000 {method 'append' of 'list' objects}
        1    0.143    0.143    0.328    0.328 DSL_2_C.py:25(read_points)