計算幾何学

Download Report

Transcript 計算幾何学

計算幾何学
・ 線分交差列挙
・ 凸包
・ アレンジメント
・ ボロノイ図
線分交差判定
・ 線分交差列挙
計算幾何学とは
・ 幾何学的な問題を計算で解く方法
・ 人間の場合、補助線を引く、定規・コンパスを使う、といった
紙を使う解法が多いが、コンピュータではこれらは使えない
・ 目で見て大観を得るようなこともできない
・ 全てを、数値データとして扱わなければならないのがポイント
線分交差判定
・ 例えば、2つの線分が交わるかどうか判定する
 人間は、図があればぱっと答えられる
・ 数値で与えられる場合、線分の端点の座標が与えられる
・ ここから何かを計算して、代数的に判定しなければいけない
・ 赤い線・青い線が乗っている直線の方程式を計算して、
端点が直線のどちら側にあるか判定(これは代入して大小比較)
・ 相手の端点が両側にある、
という条件が、両方に
成り立つときのみ交わる
線分交差列挙問題
・ n 本の線分があるとき、どれとどれがどこで交わっているの
か知りたい
 人間ならば、図を書いて端からチェックして、簡単
 先の交差判定を用いれば、O(n2) 時間でできる
・ 全部交わっていたらO(n2) 時間はしかたないが、交わってい
るものが少ないときに、もう少し速くできないだろうか
・ 人間と同じように、
端からチェックしてみよう
同一要素判定問題の帰着
・ 線分交差列挙問題には、同一要素判定問題が帰着できる
・ 同一要素判定問題を解くには、少なくとも n log n 時間かかるこ
とが知られている
 線分交差列挙問題を解くには少なくとも n log n 時間かかる
同一要素判定問題:
入力した数 a1,…, an の中に、同じ値のものがあるか
各 ai に対して、 x 座標が ai である
場所に縦線を置く(わずかに垂直
から異なる角度ずらす)
・ 交点がある  同一要素がある
a1
a4 a3
a2
a5
線分交差判定問題
・ まず、一番左に垂直な線を立て、それを右に動かしていく
ほんとに書くのではなくて、仮想的に考えるだけ
1. 垂直線と各線分の交点を見つけ、垂直方向にソートする
2. 各線分の右端、新しい線分の左端、上下に隣り合う線分の
交点(これらをイベントという)をヒープに入れる
3. ヒープから最小のものを取り出し、そこに移動
線分交差判定問題
2. 各線分の右端、新しい線分の左端、上下に隣り合う線分の交
点(これらをイベントという)をヒープに入れる
3. ヒープから最小のものを取り出し、そこに移動
・ 交点  出力。線の順番を入替え、新たな交点をヒープに挿入
・ 線の右端  線を消し、線の交点をヒープから消し、隣り合う
線の交点を挿入
・ 線の左端  線を挿入し、
隣の線との交点をヒープに挿入
一回の操作は O(log n) 時間
全部で O((n+K)logn) 時間
交点の数
凸包構成
・ 行進法
・ グラハムスキャン
・ マージハル
・ クイックハル
凸包構成問題
・ 平面上にある n 点を包む極小な領域を考える
(ただし、へこみはつくらない)こういうものを凸包という
・凸包の辺を求める問題を凸包構成問題という
凸包の難しさ
・ 凸包の計算を使って n 個の数値のソートができる
 O(n log n) 時間はかかる
-a1,…,an をソートしたい
-点集合 (a1, a12), (a2, a22),…, (an, an2) の凸包を求める
-ソートした順番に (a1, a12), (a2, a22),…, (an, an2) に枝が張られる
行進法
・ 品物をくるむときのように、1つずつ枝を張って端からくるもう
1.一番 x 座標が小さい点 v を見つける。複数あったら、 y が最
小のものを選ぶ。凸包の内側の方向を見つける
2. v から見て時計回り順で一番大きい頂点 v' を見つける
(凸包の内側の中で)
3. v と v' の間に枝をはる。 v' が最初の点でなければ、 v= v'
として2 に戻る
一回の操作は O(n) 時間
全部で O(K n) 時間
辺の数
グラハムスキャン法
・ くるむときに、効率良く接線を求める方法
1.凸包の中の点 o を見つける
2. o から見た時計回り順で全ての点をソートする
3. 時計回り順に v と、今までの点の間に接線を張る。接線を作
る頂点を2分探索で見つける
1つ消すと O(log n) 時間
全部で O(nlogn) 時間
ソートとの関連
・ 凸包はソートが帰着できることもあり、ソート的な要因を持って
いる
・ そのためか、ソート用のアイディアがけっこう使える
 行進法は挿入ソート
 グラハムスキャンは角度順の挿入ソート+2分探索
・ マージソートや、クイックソートのアイディアも使える
- マージソート  マージハル、分割法
- クイックソート  クイックハル
分割法
・ 点集合を x 軸に平行な直線でほぼ2つにわけ、それぞれの凸
法を再帰的に求めた後、全体の凸法を求める
1.点集合 P を x 座標の小さい順にソートする
2.P を x 座標で P0 と P1 、ほぼ同じ大きさの2つに分割
3.P0、P1 のについて再帰呼び出しし、P0 と P1 の凸法を求める
4.P1 と P0 の凸法の接線2つを求め、全体の凸法を作る
・ 接線は2つ求める
だけでいいことに注意
分割法の計算時間
1.点集合 P を x 座標の小さい順にソート  O(log n)
2.P を x 座標で P0 と P1 に分割  O(1)
4.P1 と P0 の凸法の接線2つを求め、全体の凸法を作る
- 接線を求める時間は O(logn)
- 頂点・枝リストのつげ替えは O(1)
・ 1反復の計算時間は O(logn)
・ 結局、ソートの時間が一番
長く、全体の計算時間は
O(n logn)
マージハル
・ 点集合を分割してそれぞれの凸法を再帰的に求めるところは分
割法と同じだが、分割する際に、適当な2つの点集合に分割す
る (ソートしない)
2.P を P0 と P1 、ほぼ同じ大きさの2つに分割
3.P0、P1 のについて再帰呼び出しし、P0 と P1 の凸法を求める
4.P1 と P0 の凸法の接線を求め、全体の凸法を作る
・ ソートが必要なく
なったが、接線を2つ
以上見つけなければ
ならない
接線の求め方
・ 接線は2分探索で1つ求められるが、最悪接線は n 本になる
 ざっくりいって、O(n log n) の時間が必要
・ 工夫すると線形時間でできる
1.P0 の凸包と P1 の凸包、両者に含まれる点 o を見つける
2.そのような点がなければ、接線は2つしかない。それを求める
3. o から見て時計回り順に P0、P1 の点を見て、凸包を作る
(グラハムスキャンと同じ)
・ 1つの点は2回しかアクセス
されず、線形時間となる
 全体で O(n log n) 時間
クイックハル
・ クイックソートのように、最悪の場合は悪くとも、もっとざっくりと
平均的に速く計算できるようデザインしたアルゴリズムもある
1. 最も右、最も左にある点を線で結び、点集合を2つに分ける
2. 各領域について、分割線の法線方向に最も遠い点を見つける
点が1つもなかったら、その分割線は凸包の辺
3. その点と分割線の両端点を結び、2つの分割線と領域を作成、
再帰的に分割線を求める
・ 平均的には、凸包
内部の点がざっくり
消えるので高速
・ 最悪は O(n2) 時間
多次元の場合
・ 3次元以上の高次の次元で、凸包アルゴリズムはどうなるか?
・ まず、接線が接平面になる
 2つの凸包の接平面は、2つとは限らない
・ グラハムスキャンや行進法で使う「時計回り」という概念がない
・ 点を逐次追加し、その点を含む接平面を追加する
・ 3次元なら、2つの凸包の接平面をくるむように求められるので、
分割法は動く
ボロノイ図
・ 逐次追加
・ 分割統治
ボロノイ図
・ 平面に点(母点)がちらばっているとき、平面を、一番近い点が
どこか、で領域分割したのがボロノイ図
・ ボロノイ図にはいろいろな性質がある
- ボロノイ図の各辺は、どれか2点の垂直二等分線
- 垂直二等分線の、ボロノイ図の辺になる部分は連続してる
- ボロノイ図の各領域は凸多角形
- 各領域は母点を1つだけ含む
- 各領域の辺は、含む 母点
と他の点の垂直二等分線
・ 与えられた点からどこの点が
一番近いか調べるときなどに使う
ボロノイ図の作り方
・ 点が2個しか無ければ簡単
 単に垂直二等分線を引けばよい
・ ここに1点追加すると、単なる直線ではなくなる
 3本の垂直二等分線の一部からなる図形
・ 交点は、3点から等距離にあるところ
・ 4点目以降はどうなるだろうか?
1点追加すると
・ 一般に、母点を1つ追加すると、その点を含む領域が新しくできる
・ それ以外の領域の形は変化しない
 できる領域の形かわかれば、ボロノイ図を更新できる
・ 追加した母点を v、v が入る領域にある母点を u とする
 v を含む領域が新たにできる
 領域の辺の1つは、u と v の
垂直二等分線を含む
・ この二等分線は、他の辺と
交わるところまで伸びる
 領域の端点は必ず二等分線の交点
垂直二等分線が交わると
・ 垂直二等分線を、領域の辺にくるまで伸ばす
・ 領域の辺は、領域の母点と他の点 w の垂直二等分線なので、そ
こから向こう側は他の点が一番近い母点になる
 垂直二等分線が作る辺はそこでおしまい
・ 新しくできる領域の辺は、そこから v と w の垂直二等分線になる
 また、 w の領域の他の辺にぶつかるまで進む
 そこで、その向こう側の
領域の母点との垂直二等
分線を求める...と進む
・ いつか、最初の二等分線と
ぶつかるので、そこで終了
計算量の解析
・ アルゴリズムは、以下の計算の反復
- 現在いる領域の母点と追加した母点の垂直二等分線を求める
- その垂直二等分線と領域がもう一回交わる点を見つける
・ 垂直二等分線の計算は O(1) 時間
・ 領域との交点を見つけるのには
二分探索が使える O(log n) 時間
・ 領域は n の定数倍の辺を
持ちうるので、O(nlog n) 時間
・ 全領域合計で O(n2log n) 時間
分割統治法
・ ボロノイ図の構成法、実際のところは領域がそれほど多くの辺を
含むことはないので、実用上は短時間。O(n log n) 時間程度
・ しかし、分割統治法を使えば、最悪 O(n log n) 時間にできる
・ 母点を、x 座標の小さいものと大きなもの、およそ半分に分割
・ 分割した母点のボロノイ図を、再帰的に求める
分割統治法
・ ボロノイ図の構成法、実際のところは領域がそれほど多くの辺を
含むことはないので、実用上は短時間。O(n log n) 時間程度
・ しかし、分割統治法を使えば、最悪 O(n log n) 時間にできる
・ 母点を、x 座標の小さいものと大きなもの、およそ半分に分割
・ 分割した母点のボロノイ図を、再帰的に求める
分割統治法
・ 母点を、x 座標の小さいものと大きなもの、およそ半分に分割
・ 分割した母点のボロノイ図を、再帰的に求める
・ できたボロノイ図を合わせて一つのボロノイ図を作る
・ まず、右の領域と左の領域、それぞれの中でもっとも下にある母
点を求める。無限遠では、この2点の垂直二等分線が辺になる
・ 次に、それが交わる辺を見つける。
交わった辺により、どちらかの
母点を捨て、次の領域の母点と
の垂直二等分線を求める
計算量の解析
・ n 点のボロノイ図を求めるのに、n/2 の大きさの問題を2つ解く
・ 計算結果をマージするのには、O(n) 時間
 二等分線と領域の交点を見つけるときに、領域の全ての辺と
の交わりをチェックするようにする
・ n 点のボロノイ図の辺は O(n) 本であることを使うと、こういう単
純なやり方でも O(n) 時間ですむ
・ よって、再帰式を作ると、
T(n) = cn + 2T(n/2)
となり、計算時間は
O(n log n) となる
多次元の場合
・ 3次元以上の高次の次元で、凸包アルゴリズムはどうなるか?
・ ボロノイ領域は凸多面体になる
・ やはり「時計回り」という概念がない
・ 点を逐次追加し、その点を含む領域を構成するには、凸多面体
領域の面を求める問題になる
まとめ
・ 線分交差列挙
- 端から走査線をスイープし、線分の上下関係を更新
・ 凸包
- ソートに使うアイディアが有効
- 分割統治法がうまく働く
- 行進法、グラハムスキャン、マージハル、クイックハル
・ ボロノイ図
- 逐次追加
- 分割法