Memahami kompresi / pengkodean dalam waktu linier

8

Saya membaca makalah NJ Larsson, A. Moffat: Offline Dictionary-Based Compression , yang menjelaskan algoritma kompresi yang, jika saya memahaminya dengan benar, sangat mirip dengan pengkodean pasangan byte .

Diberikan string dengan panjang , saya mencoba memahami bagaimana seseorang dapat memampatkannya dalam linear, , waktu dengan metode kompresi ini. Bagaimana tepatnya hal ini dilakukan? Saya sudah membaca makalah, tetapi saya masih tidak mengerti bagaimana mereka mencapai waktu linier, jadi mungkin saya akan memahaminya menjelaskan dengan cara yang berbeda.SnO(n)

Kebingungan pertama saya muncul pada langkah pertama dalam algoritma, di mana kami menemukan pasangan yang paling umum, misalnya dalam abcababcabcpasangan yang paling umum abakan digantikan oleh simbol baru, katakanlah XcXXcXc. Saya tidak mengerti bagaimana kita dapat menemukan pasangan yang paling umum dengan cukup cepat. Pendekatan naif saya adalah melihat pertama pada pasangan pertama abdan kemudian menghitung jumlah kemunculan, kemudian melihat pasangan berikutnya bcdan menghitung jumlah kemunculan, dll. Namun ini sudah memberikan hanya untuk menemukan pasangan paling umum satu kali .O(n2)

Selanjutnya, bahkan jika saya mengerti bagaimana menemukan pasangan paling umum dalam waktu . Masalah saya berikutnya adalah, bukankah kita harus menemukan pasangan paling umum hingga kali? Dan karenanya ini akan memberikan total waktu ?O(n)O(n)O(n2)

Eff
sumber
Anda harus mengajukan pertanyaan yang lebih spesifik. Mengulangi makalah dengan kata-kata yang berbeda tampaknya luas untuk situs ini. Di mana di koran apakah penulis kehilangan Anda?
adrianN
@adrianN Saya sudah menulis sedikit lebih banyak tentang apa yang secara khusus saya bingung.
Eff
Makalah ini membuat asumsi bahwa ia akan menggunakan tabel hash dan menghitungnya sebagai , yang dalam hal ini mungkin wlog diganti dengan suffix tree menjadi . Saya hanya membaca sepintas teks, pertanyaan Anda masih sangat menuntut, tetapi saya tidak benar-benar mengerti mengapa Anda akan menghabiskan hanya untuk satu item. O(n)O(n)O(n2)
Evil
@ Evil Jadi Anda mengatakan bahwa seseorang dapat membangun pohon sufiks dalam waktu (BTW, saya masih tidak mengerti kapan mungkin untuk membangun pohon sufiks dalam waktu linier dan ketika dibutuhkan ). Kemudian kami menemukan substring yang paling sering di pohon suffix dalam waktu . Benar? SΘ(n)O(nlogn)Θ(n)
Eff
Saya? Tidak. Tapi Ukkonen mengatakan beberapa kata tentang itu. untuk alfabet ukuran konstan dan secara umum. Kemudian kita dapat mengurutkan berdasarkan frekuensi dalam atau bahkan mengeksploitasi bilangan alami kecil untuk menghitung sortir. Saya tidak yakin jika sesuatu 1 ~ n adalah , maaf tidak ada jawaban untuk bagian itu. O(n)O(nlogn)O(nlogn)Θ(n)
Jahat

Jawaban:

1

Saya telah memeriksa kodenya, membaca ulang makalahnya dan sepertinya algoritma tidak berkinerja dalam seperti yang Anda gambarkan. Panggilan rekursif untuk menemukan pasangan berfungsi diO(n)
O(nlogn)dibagi dengan konstanta jika Anda ingin mengemasnya sampai akhir. Bahkan struktur di bawahnya membuat pointer ke kejadian pertama dari pasangan, membagi antrian pasangan dengan kejadian untuk membuatnya efisien, tetapi tetap loglinear. Di sisi lain dengan menganalisis kode yang ditulis oleh Ph.D. mahasiswa penulis, saya telah menemukan beberapa trik - panjang pasangan (nama asli) diberikan sebagai parameter (standarnya adalah 2) dan pengulangan dibatasi oleh parameter, yang dapat membuang panggilan lebih lanjut (standarnya adalah sekitar 5 level), dengan kemampuan untuk membuat hanya satu operan atau dorong ke ujung. Kode default berjalan di , tetapi tidak akan menghasilkan kompresi optimal. Ada juga yang beralih memilih memori, waktu atau netral.O(n)

Makalah dan kode menunjukkan penggunaan tabel hash, yang berjalan hanya dalam waktu konstan yang diharapkan, tetapi fungsi yang diberikan bekerja sangat baik dengan karakter. Juga kode membatasi panjang input oleh hardcode konstan.

Mengubah hashtable untuk suffix tree dan mengubah bagian perulangan menjadi pembukuan berpasangan akan menghasilkan hasil yang lebih baik - Saya tidak yakin apakah ini mungkin untuk membuatnya , ini mungkin pertanyaan yang berbeda.O(n)

Ada juga trik yang digunakan untuk menjaga ruang kosong dari melintasi - awal blok kosong menunjuk ke karakter non-kosong pertama, tetapi ini hanya mempercepat melintasi, masih dengan waktu loglinear. Bagian yang bertanggung jawab untuk perilaku ini adalah mengganti pasangan dengan karakter baru setiap iterasi - menjaga hanya aturan penulisan ulang dan mengoperasikannya akan lebih cepat, tetapi masih akses untuk memeriksa apakah pasangan baru diperkenalkan akan perlu memeriksa aturan penulisan ulang terhadap yang baru - dalam kasus ini kita membangun pohon biner penuh dengan pasangan di daun sedemikian rupa sehingga setelah mengganti pasangan dengan karakter baru dan menyimpulkan dengan induk kita mendapatkan pasangan baru di daun hingga ke akar - ada karakter lalu berpasangan, lalu ,nn2n4n8 , ... Anda melihat polanya, ada pasangan, tetapi menurut deskripsi algoritma ini yelds waktu hanya input lintasan.n162nO(nlogn+n)

Jahat
sumber