stern-brocot 木
Stern-Brocot 木の「親」の値は数直線の区間です。
頂点の親「根」の値は
0〜∞
左端が0で、右は無限大です。
それを分数で0/1、1/0とそれぞれ表します。
さらにHaskellではタプルで
(0,1) ,(1,0)
と表します。
つまりHaskellでStern-Brocot 木の根はタプルのタプルで
((0,1) ,(1,0))
と表せます。
親はいつでも自動で左の子、右の子を生成することができます。
Haskellで書くとこのような関数になります。
sb ((x,y),(z,w)) = (a,b) where a = ((x,y),c) ; b = (c,(z,w)); c = (z+x,y+w)
aが左の子bが右の子です。左の子の右端と右の子の左端は同じです。分割点になります。
main = do
let a = (0,1)
let b = (1,0)
let r = (a,b)
print r
print $ sb r
((0,1),(1,0))
(((0,1),(1,1)),((1,1),(1,0)))
数直線の区間
0〜∞
を
0〜1
と
1〜∞
の2つの区間に分割したのと同じです。
もう一世代増やしてみましょう。
main = do
let a = (0,1)
let b = (1,0)
let r = (a,b)
let (a,b) = sb r
print $ sb a
print $ sb b
(((0,1),(1,2)),((1,2),(1,1)))
(((1,1),(2,1)),((2,1),(1,0)))
これは
数直線の区間
0〜1
を
0〜0.5
と
0.5〜1
に
1〜∞
を
1〜2
と
2〜∞
に分割したのと同じです。
これを繰り返せば数直線を無限に分割できます。
Stern-Brocot 木の木構造としての性質等は
Spaghetti Source - Stern-Brocot 木
http://www.prefield.com/algorithm/math/stern_brocot_tree.html
を参照してください。
さてStern-Brocot木を2分探索してゆけば全ての少数を分数に変換できるのですが、
そのためにはStern-Brocot木を前もって作成しておく必要はありません。
与えられた少数と分割点とを比較しながら片側の子のみを辿ってゆけばよい。
この辺はコードにしたほうがわかりやすい。
実行結果
245850922 % 78256779
2017年10月26日木曜日
登録:
コメントの投稿 (Atom)
myPlayer
-- pipe.hs import System.Process import System.Environment main :: IO () a:_ IO [FilePath] randomize lst = do let c = length lst ...
-
この画像(IMGP2850.JPG)を表示します。 ただこのやり方だと元画像の大きさそのままで表示されます。 サイズを変更して表示するには一旦Pixbufのインスタンスをつくってから Buttonに貼り付けます。 かんたんな画像のビューアーをつくり...
-
上のコードをコピペして実行する。 $ runghc a.hs a.hs:3:11: error: Variable not in scope: n たぶんこのようなエラーになるはずです。 最初はなぜエラーになるのか理解できませんでした。 Vim上ではまったく...
-
pbmファイルでシェルピンスキーのギャスケットを描きます。 まずパスカルの三角形をつくります。 $ runghc -XParallelListComp pascal.hs 3 [1] [1,1] [1,2,1] [1,3,3,1] [1,4,6,4,1...
0 件のコメント:
コメントを投稿