Sebagai solusi alternatif untuk masalah ini, algoritma saya menggunakan bit pecahan majemuk (non integer) per kartu untuk kelompok kartu di dek berdasarkan pada berapa banyak peringkat yang tidak terisi yang tersisa. Ini adalah algoritma yang agak elegan. Saya memeriksa algoritma penyandian saya dengan tangan dan terlihat bagus. Encoder mengeluarkan bitstring yang tampaknya benar (dalam bentuk byte untuk kesederhanaan).
3754 A 236 J7131372613762 , 748 , 51722667 , 108 , 864241313428 , 56121532 , 76815 / 4 = 3,7526 / 7 = 3,71426 / 7
54 A 236 J23456789 TJQ KSEBUAH547131015 , 565 , 9752600111011011000010010010111
2615 , 565 , 9751354 A 236 J7
13 , 12 , 11 . . . , 2 , 1 )13 , 12 , 11 ...21312122125248 , 832218262 , 14418 / 53.61326 / 73.71455553333
Inilah daftar lengkap biaya saya (# bit per kartu) untuk semua peringkat yang mungkin dilihat:
13 26 / 7 = 3,714 = 3 5 / 7
12 18 / 5 = 3.600 = 3 3 / 5
11 7 / 2 = 3.500 = 3 1 / 2
10 10 / 3 = 3,333 = 3 1 / 3
9 16 / 5 = 3.200 = 3 1 / 5
8 3 / 1 = 3,000 = 3
7 17 / 6 = 2,833 = 2 5 / 6
6 13 / 5 = 2.600 = 2 3 / 5
5 7 / 3 = 2,333 = 2 1 / 3
4 2 / 1 = 2.000 = 2
3 5 / 3 = 1,667 = 1 2 / 3
2 1 / 1 = 1.000 = 1
1 0 / 1..4 = 0.0 = 0
75 , 6 , 7 , 7 , 7 , 7 , KK1312713K21 , 2 , 3 ...3131720
16813 , 12 , 11
10777748747s. Jika dek berakhir pada pasangan (seperti 77), triple / set (seperti 777) atau quad (seperti 7777), kami mendapatkan penghematan tambahan untuk dek tersebut menggunakan algoritma saya.
3222613163232
Di dek pertama dalam file data, pengkodean kartu adalah sebagai berikut (diagram yang akan datang nanti). Formatnya adalah (groupsize, bits, mode encode peringkat):
7 , 26 , 1372613
7 , 26 , 13
7 , 26 , 13
5 , 18 , 12
5 , 18 , 12
3 , 10 , 10
3 , 9 , 8
6 , 17 , 7
5 , 13 , 6
3 , 5 , 3
1 , 0 , 1
521683.23
181 / 33.23.254545454722772277 ...322223333444455556666777788889999 TTTTJJJJQ Q Q Q Q KKKKA A A A40
1103 , 7K8101kartu tersisa. Ini penting karena membuat proses pengkodean lebih efisien ketika decoder dapat membuat asumsi yang benar tanpa encoder harus menyampaikan pesan tambahan kepadanya.
313121110
26 26 26 18 18 10 9 17 13 5 0
54 A 236 J 87726 Q 3 3969 A A A Q J K7 T 9292 Q 36 K J57 T 8 TKJ4 48 Q 8 T 55 K 4
13 12 x y 98 7 6 543 2 1 0
2166175168bit. Perhatikan bahwa kita hanya mendapatkan 4 tunggal di ujung geladak tetapi jika sebaliknya kita punya keempat 4 di sana, itu adalah kasus yang lebih baik dan kita akan membutuhkan hanya 161 bit untuk menyandikan dek itu, sebuah kasus di mana pengepakan benar-benar mengalahkan entropi dari kode biner lurus dari posisi ordinal itu.
Saya sekarang memiliki kode yang diterapkan untuk menghitung persyaratan bit dan itu menunjukkan kepada saya rata-rata, sekitar 175 bit per dek dengan rendah 155 dan tinggi 183 untuk file tes 3 juta dek. Jadi algoritma saya tampaknya menggunakan 9 bit tambahan per dek vs penyandian biner lurus dari metode posisi ordinal. Tidak terlalu buruk hanya membutuhkan 5,5% ruang penyimpanan tambahan. 176 bit persis 22 byte sehingga sedikit lebih baik dari 52 byte per dek. Dek case terbaik (tidak muncul dalam 3 juta file test deck) paket hingga 136 bit dan case deck terburuk (muncul di testfile 8206 kali), adalah 183 bit. Analisis menunjukkan kasus terburuk adalah ketika kita tidak mendapatkan quad pertama hingga mendekati (atau pada) kartu 40. Kemudian karena mode encode ingin turun dengan cepat, kita "terjebak" mengisi blok (sebesar 7 kartu) dalam sebuah mode pengodean bit yang lebih tinggi. Orang mungkin berpikir bahwa tidak mendapatkan paha depan sampai kartu 40 akan sangat jarang menggunakan deck yang dikocok dengan baik, tetapi program saya mengatakan kepada saya bahwa itu terjadi 321 kali dalam testfile dari 3 juta deck sehingga sekitar 1 dari setiap 9346 deck. Itu lebih sering yang saya harapkan. Saya bisa memeriksa kasus ini dan menanganinya dengan bit lebih sedikit tetapi sangat jarang sehingga tidak akan mempengaruhi bit rata-rata cukup.
Juga ada hal lain yang sangat menarik. Jika saya mengurutkan deck pada data deck mentah, panjang awalan yang mengulang # kali signifikan hanya sekitar panjang 6 (seperti 222244). Namun dengan data yang dikemas, panjangnya meningkat menjadi sekitar 16. Itu berarti jika saya mengurutkan data yang dikemas, saya harus bisa mendapatkan penghematan yang signifikan dengan hanya menunjukkan ke decoder awalan 16 bit dan kemudian hanya menampilkan sisa deck. (minus awalan berulang) yang memiliki awalan yang sama, kemudian pergi ke awalan berikutnya dan ulangi. Dengan asumsi saya menyimpan bahkan 10 bit per deck dengan cara ini, saya harus mengalahkan 166 bit per deck. Dengan teknik enumerasi yang dinyatakan oleh orang lain, saya tidak yakin apakah awalan akan sepanjang dengan algoritma saya. Juga kecepatan pengemasan dan pembongkaran menggunakan algoritma saya sangat bagus.
Mengenai tingkat kompresi ke-2 di mana saya mengurutkan bitstrings output dari algoritma saya, kemudian menggunakan pengkodean "perbedaan": Metode yang sangat sederhana adalah untuk mengkodekan 61.278 prefiks 16 bit unik yang muncul setidaknya dua kali dalam data output (dan maksimum dari 89 kali dilaporkan) hanya sebagai bit 0 di output untuk menunjukkan ke dekompresor tingkat 2 bahwa kita sedang mengkodekan awalan (seperti 0000111100001111) dan kemudian setiap deck yang dikemas dengan awalan yang sama akan mengikuti dengan 1 bit terkemuka untuk menunjukkan bagian non awalan dari dek yang sudah dikemas. Rata-rata # dari tumpukan deck dengan awalan yang sama adalah sekitar 49 untuk setiap awalan, tidak termasuk beberapa yang unik (hanya 1 deck memiliki awalan tertentu). Tampaknya saya dapat menghemat sekitar 15 bit per deck menggunakan strategi sederhana ini (menyimpan awalan umum sekali).
Setelah level 2 kompresi menggunakan perbedaan (awalan) pengkodean dari output bitstring yang diurutkan dari encoder pertama, saya sekarang mendapatkan sekitar 160 bit per deck. Saya menggunakan awalan panjang 18 dan hanya menyimpannya utuh. Karena hampir semua (245013 dari 262144 = 93,5%) dari kemungkinan awalan 18 bit muncul, akan lebih baik untuk menyandikan awalan. Mungkin saya bisa menggunakan 2 bit untuk mengkodekan tipe data apa yang saya miliki. 00 = panjang reguler 18 awalan disimpan, 01 = "awalan 1 up" (sama dengan awalan sebelumnya kecuali 1 ditambahkan), 11 = penyandian langsung dari kemasan tingkat 1 (rata-rata sekitar 175 bit). 10 = ekspansi di masa depan ketika saya memikirkan hal lain untuk dikodekan yang akan menghemat bit.
Apakah ada orang lain yang mengalahkan 160 bit per deck? Saya pikir saya bisa mendapatkan milik saya sedikit lebih rendah dengan beberapa bereksperimen dan menggunakan deskriptor 2 bit yang saya sebutkan di atas. Mungkin itu akan keluar di 158ish. Tujuan saya adalah untuk membuatnya menjadi 156 bit (atau lebih baik) karena itu akan menjadi 3 bit per kartu atau kurang. Sangat mengesankan. Banyak percobaan untuk turun ke tingkat itu karena jika saya mengubah pengkodean tingkat pertama maka saya harus menguji ulang yang merupakan pengkodean tingkat 2 terbaik dan ada banyak kombinasi untuk mencoba. Beberapa perubahan yang saya buat mungkin baik untuk data acak serupa lainnya tetapi beberapa mungkin bias terhadap dataset ini. Tidak benar-benar yakin tetapi jika saya mendapatkan dorongan saya dapat mencoba set data 3 juta deck lain untuk melihat apa yang terjadi seperti jika saya mendapatkan hasil yang sama di atasnya.
1050
Adakah yang punya ide tentang bagaimana membuat algoritma saya lebih baik seperti kasus lain apa yang harus saya encode yang akan mengurangi bit penyimpanan untuk setiap deck rata-rata? Siapa saja?
2 lebih banyak hal: 1) Saya agak kecewa bahwa lebih banyak orang tidak memperbaiki solusi saya yang walaupun tidak optimal dalam hal ruang, masih layak dan cukup mudah untuk diterapkan (saya dapat pekerjaan saya dengan baik). 2) Saya melakukan analisis pada datafile 3 juta dek saya dan memperhatikan bahwa kartu yang paling sering terjadi di mana peringkat 1 terisi (seperti 4444) ada pada kartu 26. Ini terjadi sekitar 6,711% dari waktu (untuk 201322 dari 3 juta deck) ). Saya berharap untuk menggunakan info ini untuk kompres lebih seperti memulai dalam 12 mode penyandian simbol karena kita tahu rata-rata kita tidak akan melihat setiap peringkat sampai sekitar middeck tetapi metode ini gagal untuk mengompres apa pun karena biaya overhead itu melebihi penghematan. Saya mencari beberapa perubahan pada algoritma saya yang sebenarnya dapat menghemat bit.
Jadi apakah ada yang punya ide apa yang harus saya coba selanjutnya untuk menyimpan beberapa bit per deck menggunakan algoritma saya? Saya mencari pola yang cukup sering terjadi sehingga saya dapat mengurangi bit per deck bahkan setelah overhead tambahan memberitahu decoder pola apa yang diharapkan. Saya sedang memikirkan sesuatu dengan probabilitas yang diharapkan dari kartu yang tidak terlihat yang tersisa dan menyatukan semua kartu yang tersisa menjadi satu ember. Ini akan memungkinkan saya untuk masuk ke mode encode yang lebih rendah lebih cepat dan mungkin menyimpan beberapa bit tapi saya ragu.
Juga, FYI, saya menghasilkan 10 juta shuffles acak dan menyimpannya dalam database untuk memudahkan analisis. Hanya 488 dari mereka berakhir di quad (seperti 5555). Jika saya mengemas hanya mereka yang menggunakan algoritma saya, saya mendapatkan rata-rata 165,71712 bit dengan rendah 157 bit dan tinggi 173 bit. Hanya sedikit di bawah 166 bit menggunakan metode pengkodean lainnya. Saya agak terkejut melihat betapa jarangnya kasus ini (sekitar 1 dari setiap 20.492 mengocok rata-rata).