Pertimbangkan daftar yang hanya terhubung sendiri dalam pengaturan fungsional murni. Pujiannya telah dinyanyikan dari puncak gunung dan akan terus dinyanyikan. Di sini saya akan membahas satu di antara banyak kekuatannya dan pertanyaan tentang bagaimana ia dapat diperluas ke kelas yang lebih luas dari rangkaian fungsional murni berdasarkan pohon.
Masalahnya adalah sebagai berikut: Anda ingin menguji kesetaraan struktural yang hampir pasti dalam waktu O (1) dengan hashing yang kuat. Jika fungsi hash secara struktural bersifat rekursif, yaitu hash (x: xs) = mix x (hash xs), maka Anda dapat secara tembolok meng-cache nilai hash pada daftar dan memperbaruinya dalam waktu O (1) ketika sebuah elemen dimasukkan ke dalam daftar yang ada . Sebagian besar algoritma untuk daftar hashing secara struktural bersifat rekursif, sehingga pendekatan ini sangat dapat digunakan dalam praktiknya.
Tetapi anggaplah alih-alih daftar yang terhubung secara tunggal Anda memiliki urutan berbasis pohon yang mendukung gabungan dua urutan panjang O (n) dalam waktu O (log n). Agar caching hash berfungsi di sini, fungsi pencampuran hash harus asosiatif untuk menghormati derajat kebebasan yang dimiliki pohon dalam merepresentasikan urutan linier yang sama. Mixer harus mengambil nilai hash dari sub pohon dan menghitung nilai hash dari seluruh pohon.
Di sinilah saya enam bulan lalu ketika saya menghabiskan satu hari untuk merenungkan dan meneliti masalah ini. Tampaknya tidak mendapat perhatian dalam literatur tentang struktur data. Saya memang menemukan algoritma hashing Tillich-Zemor dari kriptografi. Ini bergantung pada perkalian matriks 2x2 (yang asosiatif) di mana bit 0 dan 1 sesuai dengan dua generator subalgebra dengan entri dalam bidang Galois.
Pertanyaan saya adalah, apa yang saya lewatkan? Pasti ada makalah yang relevan dalam literatur tentang kriptografi dan struktur data yang gagal saya temukan dalam pencarian saya. Setiap komentar tentang masalah ini dan tempat yang mungkin untuk dijelajahi akan sangat dihargai.
Sunting: Saya tertarik dengan pertanyaan ini tentang ujung spektrum yang lembut dan kuat secara kriptografis. Di sisi yang lebih lunak dapat digunakan untuk tabel hash di mana tabrakan harus dihindari tetapi tidak menimbulkan bencana. Di sisi yang lebih kuat dapat digunakan untuk pengujian kesetaraan.
Keluarga fungsi hash yang hampir universal
memiliki properti yang bagus di sini: , di mana " ∘ " menunjukkan penggabungan. Jika Anda cache pada akar setiap pohon kedua nilai hash dan sebuah | → x | , Anda dapat menghitung hash dari gabungan dari dua pohon di O ( 1 ) operasi pada Z p .ha(x⃗ )+a|x⃗ |ha(y⃗ )=ha(x⃗ ∘y⃗ ) ∘ a|x⃗ | O(1) Zp
Ini asosiatif dan cukup cepat. Probabilitas tabrakan adalah O ( min ( | → x | , | → y | ) / p ) . Lihat CLRS atau Dietzfelbinger et al. Dalam "Fungsi Polinomial Hash Handal".x⃗ ≠y⃗ O(min(|x⃗ |,|y⃗ |)/p)
sumber
Salah satu solusinya adalah dengan menggunakan hashing Merkle. Gunakan struktur data pohon biner abadi / persisten. Beri anotasi pada setiap simpul daun dengan hash data yang terkandung di dalam daun itu. Beri anotasi pada setiap simpul internal dengan hash hash pada kedua anaknya. Dengan kata lain, jika adalah simpul internal dengan anak-anak n ′ , n ″ , dan mereka telah dijelaskan dengan nilai hash y ′n n′,n′′ , maka Anda harus membuat anotasi simpul internal n dengan nilai hash y = H ( y ′ , Y ″ ) , di mana Hy′,y′′ n y=H(y′,y′′) H adalah fungsi hash. Ini menambahkan hanya kerja ekstra per node yang dibuat untuk semua operasi pohon. Misalnya, Anda dapat mendukung penggabungan dua pohon dalam waktu O ( lg n ) .O(1) O(lgn)
Pendekatan lain adalah dengan menggunakan hash komutatif, asosiatif. Beri label akar pohon denganH(x1,…,xm) x1,…,xm m
sumber