「組合せ型の最小完全ハッシュ関数」の逆関数
Posted feedbacks - Prolog
hashは問題のハッシュ関数そのままの実装です。 ?- hash(5, 2, [0, 1, 0, 1, 0], X). X = 4 Prologのパターンマッチとバックトラックにより 逆関数としても使えます。 ?- hash(5, 2, L, 4). L = [0, 1, 0, 1, 0] これはこれで面白いのですが 結局のところ順列を作りつつ調べていくので n, mが大きくなると使い物になりません。 その点unhashは双方向ではありませんが combを考えなければ計算量は線形です。 あと、combは一応メモ化してますが、 たぶん計算方法が良くないです。
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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | %% comb(+N, +K, ?C)
:- dynamic comb/3.
comb(_, 0, 1) :- !.
comb(N, K, X) :-
N0 is N - 1,
K0 is K - 1,
comb(N0, K0, X0),
X is X0 * N / K,
asserta(comb(N, K, X) :- !).
%% hash(+N, +M, ?BitList, ?Hash)
hash(0, 0, [], 0) :- !.
hash(N, M, [1|Bs], H) :-
succ(M0, M),
succ(N0, N),
comb(N0, M, C),
hash(N0, M0, Bs, H0),
H is C + H0.
hash(N, M, [0|Bs], H) :-
succ(N0, N),
hash(N0, M, Bs, H).
%% unhash(+N, +M, +Hash, ?BitList)
unhash(0, 0, _, []) :- !.
unhash(N, M, H, [B|Bs]) :-
N0 is N - 1,
( N > 0,
comb(N0, M, C),
H >= C
-> B = 1,
H0 is H - C,
M0 is M - 1,
unhash(N0, M0, H0, Bs)
; B = 0,
unhash(N0, M, H, Bs)
).
|

shuyo
#3392()
Rating0/0=0.00
「組み合わせ型の最小完全ハッシュ関数」とは 下のような「n個の値のうちm個が1で残りが0であるようなデータ」と整数とを対応づける関数です。下の例ではn=5でm=2になっています。 (「0以上n未満の整数から重複しないm個を選んだ組み合わせ」もデータとしては同じです)
「ハッシュ関数」というとデータが文字列であるものを連想しやすいですが、 ここで扱う対象データは文字列ではありません。(ちなみに文字列のハッシュ関数は、異なる文字列が同じハッシュ値になることがあるので「完全」ではありません。)
さて、ここからが本題です。 組み合わせのデータを与えると整数を返すのがこのハッシュ関数でした。 この逆の関数、「整数xを与えると、hash(data) == xになるような組み合わせのデータdataを返す関数」を作ってください。
このお題はshuyoさんの提案を元に作成しました。ありがとうございました。
[ reply ]