SICP読書会第31回
場所
小飼弾さんの家。広い!本がいっぱい。あんな本棚ほしいなぁ。
8クイーン問題
読書会スタート。この時点で、8クイーン問題についてのコードは1文字も書いていない。
問題2.42の8クイーン問題を、色々脱線しながら考える。safe?プロシージャの実装のアイデアを話すものの、その時点で書いたコードはdefine (safe? k positions)
途中であきらめて、queensプロシージャはWebにある回答をコピペして動かして満足する。
問題2.43
ボードサイズをN、ボードサイズがNのときの、最初のn列にn個のクイーンを置く置き方をとする。
色々計算すると、Louisの計算方法では、計算時間が
読書会で"queen-colsが回呼び出されるから、計算量ものオーダーで増える"というような話になっていたけど、うちに帰って考えて、重要なのはqueen-colsの呼び出し回数だけではない、という気がしてきた。SICPに出てきた計算量の例題の、典型的なプロシージャは1回の呼び出しあたりの計算量がほぼ固定だったので、呼び出し回数だけを考えておけばよかった。しかし、queen-colsの場合、引数によってfilterを通す要素の数が変わってくるから、それを考慮しなきゃいけないと思う。ということで、自分なりに仮説を立てて計算した結果が上の式。なぜこの式に辿りついたかは、末尾の"もっと詳しく"を参照。
実際に検証してみると、
- N=7 のとき - 予想:, 実測:
- N=8 のとき - 予想:, 実測:
Nがどんどん大きくなっていけば、近づいていくんじゃないかなぁ、という気がする。
もっと詳しく
Louisの方法について考えてみる。
そもそもあとから気がついたが、queen-colsの呼び出し回数はではなく回だった。なぜなら、
- (queen-cols N) で (queen-cols (- N 1))がN回呼ばれて
- (queen-cols (- N 1)) で (queen-cols (- N 2))がN回呼ばれて
- (queen-cols (- N 2)) で (queen-cols (- N 3))がN回呼ばれて
- ...
- (queen-cols (- N (- N 1))) で (queen-cols 0)がN回呼ばれて
となっているので、(queen-cols k)が呼び出される回数をとするなら、となっている。つまり、(queen-cols k)が呼び出される回数は
である()。つまり、queen-colsが呼び出される回数の総計は
となる。
オーダーとしてはだけども。
さて、queen-cols1回の計算量が固定量なら、queensプロシージャの計算量が増えるオーダーはだが、そうは問屋が卸さない*1。おそらく、queen-colsの1回の計算量を決めるのは、フィルタに通す要素の数だ!と山を張ることにする。
(queen-cols k)でフィルタに通す要素の数は、上で使ったを使って書くなら、個になる。フィルタに要素1個を通すのがの計算量だとすると、(queen-cols k)の計算量はである。
全体の計算量については、(個々の(queen-cols k)の計算量)×(呼び出し回数)の総和をとってやればいいから
となる。
一方、模範的なqueensプロシージャの場合、(queen-cols k)はそれぞれのkについて1回ずつしか呼び出されないので、
となる。
あとは、比をとってやれば謎のが消えてすっきりする。ちなみに、上の方で不等号を使ったのは、queen-colsには他にも色々な処理があるので、Louisの方法だともうすこし遅くなるだろう、という予想を含めて不等号を使った。
NP問題
8クイーン問題は、NP完全ですよ、という話。あとでかく。
JSONP
MeCabをAPI経由で使えるMECAPIを作っているたつをさんからJSONPについての話を聞く。JSONP = JavaScriptのみで、クロスドメインにデータのやり取りをするためのバッドノウハウということでFA?
BASIC
弾さん(というかその場の人達?)に、「未成年のうちはRailsなんて使わず、BASICで茨の道を行け」というありがたいお言葉をwww
弾さんが、DIMになんでもかんでも突っ込めばBASICでもレキシカルスコープが実現できる、みたいなことを言っていたけど、BASICは中学生くらいのときにちょっとかじったくらいだからよくわからんなぁ(´・ω・`)
BASICは一応ISO、ANSI、JISで規格策定されているという初耳情報。
名前がわからない
Web上に写真がある人以外は、顔と名前が一致してないでつ(´д`)次の読書会から徐々に覚えていこう。