Comment detail
「組合せ型の最小完全ハッシュ関数」の逆関数 (Nested Flatten)メモ化をちょっと試してみた。 単純にnCrの引数だけでメモ化するのはあまり効果が無い。 同じ(n,r)の組み合わせは1回しか使わないから (上のrev-hashの コードでは手抜きで2回使われる箇所もあるけど)。 nCr = n-1Cr + n-1Cr-1 を使えば、最初のnCrの計算で その後に使う組み合わせは全て計算してしまうのでメモ化の 効果は出る。ただ、これは要するにpascalのテーブルを最初に (ほぼ)全部計算するってことだから、まだ無駄なことをしている 感じはある。 gosh> (time (begin ((rev-hash-test nCr-memo) (expt 10 599) 2000 1000) (values))) ;(time (begin ((rev-hash-test nCr-memo) (expt 10 599) 2000 1000) (values))) ; real 7.703 ; user 7.470 ; sys 0.210 gosh> (time (begin ((rev-hash-test nCr) (expt 10 599) 2000 1000) (values))) ;(time (begin ((rev-hash-test nCr) (expt 10 599) 2000 1000) (values))) ; real 35.341 ; user 34.710 ; sys 0.500 もちろん2度目からはメモ化版は激速だけど。 gosh> (time (begin ((rev-hash-test nCr-memo) (expt 10 599) 2000 1000) (values))) ;(time (begin ((rev-hash-test nCr-memo) (expt 10 599) 2000 1000) (values))) ; real 0.014 ; user 0.010 ; sys 0.000 テストコードを貼り付けておく。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | (define (nCr n r)
(define (! n k) (if (<= n k) 1 (* n (! (- n 1) k))))
(/ (! n (- n r)) (! r 0)))
(define nCr-memo
(let1 tab (make-hash-table 'equal?)
(define (memo n r v) (hash-table-put! tab (cons n r) v) v)
(lambda (n r)
(cond [(or (= n r) (= r 0)) 1]
[(hash-table-get tab (cons n r) #f)]
[(> r (quotient n 2)) (nCr-memo n (- n r))]
[else (memo n r (+ (nCr-memo (- n 1) (- r 1))
(nCr-memo (- n 1) r)))]))))
(define (rev-hash-test nCr)
(define (rev-hash k n m)
(cond [(= m 0) (make-list n 0)]
[(= n m) (make-list n 1)]
[(<= (nCr (- n 1) m) k)
(cons 1 (rev-hash (- k (nCr (- n 1) m)) (- n 1) (- m 1)))]
[else
(cons 0 (rev-hash k (- n 1) m))]))
rev-hash)
|
そうか,n=kを見れば別に末端まで再帰する必要は無いな. おれはまだまだ修行が足りなかったようだ. 下に自分のコードを書き直してみた,エンバグしてなきゃいいけど.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | def fact( n )
if n == 0
1
else
n * fact( n - 1 )
end
end
def comb( n, k )
fact( n ) / ( fact( k ) * fact( n - k ) )
end
def inv_comb_hash( x, n, k )
if n == 0
return []
elsif n == k
return [1] * n
end
nCk = comb( n - 1, k )
if x >= nCk
[1] + inv_comb_hash( x - nCk, n - 1, k - 1 )
else
[0] + inv_comb_hash( x, n - 1, k )
end
end
|
う~ん,どうやら「どうかく.org」自体を参考URLに挙げることはできないようですね. 書き直したコードというのは,#1672です.






shiro
#1670()
[
Scheme
]
Rating4/4=1.00
Rating4/4=1.00-0+
2 replies [ reply ]