Bu soruna alternatif bir çözüm olarak, algoritmam, kaç tane doldurulmamış sıralama kaldığına bağlı olarak destedeki kart grupları için kart başına bileşik kesirli (tamsayı olmayan) bitler kullanır. Oldukça zarif bir algoritmadır. Kodlama algoritmamı elle kontrol ettim ve iyi görünüyor. Kodlayıcı, doğru bit dizeleri gibi görünen çıktıları (basitlik için bayt formunda) çıkarır.
3754A236J7131372613762,748,51722667,108,864241313428,56121532,76815/4=3.7526/7=3.71426/7
54A236J23456789TJQKA547131015,565,9752600111011011000010010010111
2615,565,9751354A236J7
13,12,11...,2,1)13,12,11...21312122125248,832218262,14418/53.61326/73.71455553333
İşte tüm olası sıra sayısı için maliyetlerin tam listesi (kart başına bit sayısı):
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. Eğer güverte bir çift (77 gibi), üçlü / set (777 gibi) veya dörtlü (7777 gibi) ile biterse, algoritmamı kullanarak bu güverte için ek tasarruf elde ederiz.
3222613163232
Veri dosyasındaki ilk destede, kartların kodlanması aşağıdaki gibidir (daha sonra gelecek diyagram). Biçim (grup boyutu, bitler, sıralama kodlama modu):
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...322223333444455556666777788889999TTTTJJJJQQQQKKKKAAAA40
1103,7K8101kart kaldı. Bu önemlidir, çünkü kod çözücü ilave mesajlar iletmek zorunda kalmadan kod çözücü doğru varsayımlar yapabildiğinde kodlama işlemini daha verimli hale getirir.
313121110
26 26 26 18 18 10 9 17 13 5 0
54A236J 87726Q3 3969AAA QJK7T 9292Q 36K J57 T8TKJ4 48Q8T 55K 4
13 12 xy 98 7 6 543 2 1 0
2166175168bit. Güverte sonunda sadece tek bir 4 var, ancak bunun yerine dört 4s'nin hepsi varsa, bu daha iyi bir durumdur ve bu güverteyi kodlamak için sadece 161 bite ihtiyacımız olurdu, bu da ambalajın sıralı pozisyonunun düz bir ikili kodlamasının entropisi.
Şimdi bit gereksinimlerini hesaplamak için uygulanan kod var ve ortalama 3 milyon güverte test dosyası için 155 düşük ve 183 yüksek güverte başına yaklaşık 175 bit gösteriyor. Yani algoritmam sıra başına pozisyon yönteminin düz ikili kodlamasına karşı güverte başına 9 ekstra bit kullanıyor gibi görünüyor. Sadece% 5,5 ilave depolama alanında çok kötü değil. 176 bit tam olarak 22 bayttır, bu nedenle güverte başına 52 bayttan biraz daha iyidir. 136 bite kadar en iyi durum güvertesi (3 milyon güverte test dosyasında görünmedi) paketleri ve en kötü durum güvertesi (8206 kez test dosyasında göründü), 183 bittir. Analiz, en kötü durumun kart 40'a (veya kartın) yakınına kadar (veya dört kartta) ilk çeyreği alamadığımız durum olduğunu gösterir. Daha sonra kodlama modu hızlı bir şekilde düşmek istediği için, daha yüksek bit kodlama modu. Kart 40'a kadar dörtlü almamanın iyi karıştırılmış bir desteyi kullanarak oldukça nadir olacağını düşünebilirim, ancak programım bana her 3 milyon desteğin test dosyasında 321 kez olduğunu ve her 9346 desteden yaklaşık 1'inde olduğunu söylüyor. Bu daha çok beklerdim. Bu durumu kontrol edebilir ve daha az bitle başa çıkabilirim, ancak ortalama bitleri yeterince etkilemeyecek kadar nadirdir.
Ayrıca burada çok ilginç başka bir şey var. Ham güverte verilerinde desteyi sıralarsam, önemli sayıda # tekrar eden öneklerin uzunluğu yalnızca yaklaşık 6'dır (222244 gibi). Bununla birlikte, paketlenmiş verilerle bu uzunluk yaklaşık 16'ya yükselir. Bu, paketlenmiş verileri sıralarsam, kod çözücüye sadece 16 bit önek belirterek ve sadece desteğin kalanını çıkararak önemli bir tasarruf elde edebilmem gerektiği anlamına gelir. (önek eksi eksi) ekini tıklayın, ardından bir sonraki önekin üzerine gelin ve işlemi tekrarlayın. Güverte başına sadece 10 bit kurtardığımı varsayarsak, güverte başına 166 bit yendi. Başkaları tarafından belirtilen numaralandırma tekniğiyle, önekin algoritmamla olduğu kadar uzun olacağından emin değilim. Ayrıca algoritmamı kullanarak paketleme ve açma hızı şaşırtıcı derecede iyi.
Algoritmamın çıkış bit dizilerini sıraladığım 2. sıkıştırma düzeyiyle ilgili olarak, "fark" kodlamasını kullanın: Çok basit bir yöntem, çıkış verilerinde en az iki kez görünen 61.278 benzersiz 16 bit önekleri kodlamak (ve bir maksimum 2. seviye dekompresöre bir önek kodladığımızı (0000111100001111 gibi) göstermek için çıkıştaki 0 önde gelen bit olarak ve daha sonra aynı önekle paketlenmiş tüm desteler, paketlenmiş destenin önek olmayan kısmını belirtir. Aynı önekle paketlenmiş güvertelerin ortalama sayısı, benzersiz olanlardan azı dahil olmak üzere her önek için yaklaşık 49'dur (yalnızca 1 destenin belirli öneki vardır). Görünüşe göre bu basit stratejiyi kullanarak (ortak önekleri bir kez saklayarak) güverte başına yaklaşık 15 bit kaydedebilirim.
Birinci kodlayıcının sıralı bit dizisi çıktısının fark (önek) kodlamasını kullanarak 2. sıkıştırma seviyesinden sonra, şimdi güverte başına yaklaşık 160 bit alıyorum. Uzunluk 18 önekini kullanıyorum ve sadece sağlam saklıyorum. Olası 18 bit öneklerin neredeyse tamamı (262144 =% 93,5) 245013 olduğundan, önekleri kodlamak daha da iyi olacaktır. Belki de sahip olduğum veri türünü kodlamak için 2 bit kullanabilirim. 00 = normal uzunluk 18 önek kaydedildi, 01 = "1 yukarı önek" (eklenen 1 hariç önceki önekle aynı), 11 = 1. seviye ambalajdan düz kodlama (ortalama yaklaşık 175 bit). 10 = kodlamak için bitleri kurtaracak başka bir şey düşündüğümde gelecekteki genişleme.
Henüz güverte başına 160 bit yenen var mı? Yukarıda bahsettiğim 2 bit tanımlayıcıları kullanarak biraz deneme yaparak benimkini biraz düşürebilirim. Belki de 158ish dibe inecek. Amacım bunu 156 bit (veya daha iyisi) elde etmektir, çünkü bu kart başına 3 bit veya daha az olacaktır. Çok etkileyici. İlk seviye kodlamasını değiştirirsem en iyi 2. seviye kodlaması olan ve tekrar denemek için birçok kombinasyon var. Yaptığım bazı değişiklikler diğer benzer rastgele veriler için iyi olabilir, ancak bazıları bu veri kümesine doğru eğilimli olabilir. Gerçekten emin değilim ama dürtüyü alırsam, benzer sonuçlar alırsam nasıl olacağını görmek için 3 milyonluk bir güverte veri seti deneyebilirim.
1050
Herkes algoritma nasıl daha iyi kodlamak için her durumda her güverte için depolama bitlerini azaltacak diğer durumlarda gibi daha iyi yapmak hakkında herhangi bir fikri var mı? Kimse?
2 daha fazla şey: 1) Uzayda en uygun olmasa da, hala iyi ve uygulanması oldukça kolay olan daha fazla insanın çözümümü desteklemediğini hayal kırıklığına uğrattım (benim iyi çalışıyor). 2) 3 milyon deste veri dosyam üzerinde analiz yaptım ve 1. derecenin (4444 gibi) doldurduğu en sık görülen kartın 26. kartta olduğunu fark ettim. Bu, zamanın yaklaşık% 6.711'inde (3 milyon desteğin 201322'si için) olur ). Bu bilgiyi 12 sembol kodlama modunda başlamak gibi daha fazla sıkıştırmak için kullanmayı umuyordum, çünkü ortalama olarak middeck'e kadar her rütbeyi görmeyeceğimizi biliyoruz, ancak bu yöntem yükü tasarrufları aştığı için herhangi bir sıkıştırmayı başaramadı. Algoritmamda bitleri kaydedebilecek bazı değişiklikler arıyorum.
Yani kimse algoritma kullanarak güverte başına birkaç bit kaydetmek için ne denemek gerekir herhangi bir fikir var mı? Kod çözücüye hangi desenin beklemesini söyleyen ekstra yükten sonra bile güverte başına bitleri azaltabilmem için yeterince sık olan bir desen arıyorum. Kalan görünmeyen kartların beklenen olasılıkları ile bir şey düşünüyordum ve kalan tüm kartları tek bir kovaya topladım. Bu, daha düşük bir kodlama moduna daha hızlı düşmeme ve belki de bazı bitleri kaydetmeme izin verecek, ancak bundan şüpheliyim.
Ayrıca, FYI, 10 milyon rastgele karıştırmayı oluşturdum ve kolay analiz için bir veritabanında sakladım. Sadece 488'i dörtlüdür (5555 gibi). Sadece algoritmamı kullananları paketlersem, ortalama 157 bit ve yüksek 173 bit ile 165.71712 bit elde ederim. Diğer kodlama yöntemini kullanarak 166 bitin biraz altında. Bu vakanın ne kadar seyrek olduğuna biraz şaşırdım (ortalama her 20.492 karıştırmadan yaklaşık 1'i).