Como uma solução alternativa para esse problema, meu algoritmo usa bits fracionários compostos (não inteiros) por cartão para grupos de cartões no baralho com base em quantas fileiras não preenchidas ainda existem. É um algoritmo bastante elegante. Eu verifiquei meu algoritmo de codificação manualmente e está com boa aparência. O codificador está emitindo o que parece ser uma sequência de bits correta (em formato de bytes, para simplificar).
A visão geral do meu algoritmo é que ele usa uma combinação de grupos de cartões e codificação de bits fracionários compostos. Por exemplo, no meu arquivo de teste compartilhada de milhões de baralhos, o primeiro tem os primeiros 7 cartões de 54 A 236 J . A razão pela qual escolhi um tamanho de bloco de 7 cartas quando 13 fileiras de cartas são possíveis é porque 13 7 "calçadeiras" (se encaixam perfeitamente) em 26 bits (desde 13 7 = 62 , 748 , 517 e 2 26 = 67 , 108 ,3754A236J7131372613762,748,517226 ). Idealmente, queremos que esses 2 números sejam o mais próximo possível (mas com a potência do número 2 um pouco maior), para não desperdiçar mais do que uma fração muito pequena de um pouco no processo de empacotamento de bits. Observe que eu também poderia ter escolhido o tamanho do grupo 4 ao codificar 13 classificações desde 13 4 = 28 , 561 e 2 15 = 32 , 768 . Não é tão apertado um ajuste desde 15 / 4 = 3,75 , mas 26 de / 7 = 3.71467,108,864241313428,56121532,76815/4=3.7526/7=3.714. Assim, o número de bits por cartão é um pouco menor por cartão se usarmos a método de embalagem.26/7
Então, olhando para , simplesmente procuramos a posição ordinal dessas classificações em nossa lista principal " 23456789 T J Q K A " de classificações. Por exemplo, o primeiro ranking de cartas real de 5 tem uma posição de pesquisa na sequência de pesquisa de ranking de 4 . Apenas tratamos essas 7 posições de classificação como um número base 13 começando com 0 (então a posição 4 que obtivemos anteriormente será realmente um 3). Convertido de volta à base 10 (para fins de verificação), obtemos 15 , 565 , 975 . Em 2654A236J23456789TJQKA547131015,565,97526bits de binário obtemos .00111011011000010010010111
O decodificador funciona de maneira muito semelhante. Ele pega (por exemplo) essa sequência de bits e a converte novamente em decimal (base 10) para obter 15 , 565 , 975 , depois a converte na base 13 para obter as compensações na sequência de pesquisa de classificação e depois reconstrói as classificações um de cada vez e recebe as primeiras 7 cartas originais 54 A 236 J. Observe que o tamanho do bloco de bits nem sempre será 26, mas sempre começará em 26 em cada deck. O codificador e o decodificador têm algumas informações importantes sobre os dados do deck antes mesmo de operar. Essa é uma coisa excepcionalmente agradável sobre esse algoritmo.2615,565,9751354A236J7
Cada # de fileiras restante (tal como tem o seu próprio groupsize e custo (# de bits por cartão). Estes foram encontrados experimentalmente apenas brincando com potências de 13 , 12 , 11 ... e potências de 2 . Eu já expliquei como consegui o tamanho do grupo para quando podemos ver 13 classificações, então que tal cairmos para 12 classificações não preenchidas? Mesmo método. Observe as potências de 12 e pare quando uma delas estiver muito próxima de uma potência de 2, mas apenas um pouco abaixo dela. 13,12,11...,2,1)13,12,11...21312122 = 248 , 832 e 2 18 = 262 , 144 . Esse é um ajuste bem apertado. O número de bits que codificam este grupo é 18 de / 5 = 3,6 . No 13 grupo posto era 26 de / 7 = 3,714 , de modo que possa ver, como o número de fileiras não preenchidas diminui (fileiras estão enchendo tais como 5555 , 3333 ), o número de bits para codificar os cartões diminui.125248,832218262,14418/53.61326/73.71455553333
Aqui está minha lista completa de custos (número de bits por cartão) para todos os possíveis números de classificações a serem vistos:
12 18 de / 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 / 113 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
7 17 / 6 = 2.833 = 2 5 / 6 6 13 / 5 = 2600 = 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 / 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
1 0 / 1..4 = 0,0 = 0 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. Se o baralho terminar em um par (como 77), triplo / set (como 777) ou quad (como 7777), obteremos economias adicionais para esse baralho usando meu algoritmo.
3222613163232
No primeiro baralho no arquivo de dados, a codificação dos cartões é a seguinte (diagrama a seguir). O formato é (tamanho do grupo, bits, modo de codificação de classificação):
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,7K8101cartão restante. Isso é importante porque torna o processo de codificação mais eficiente quando o decodificador pode fazer suposições corretas sem que o codificador precise passar mensagens extras para ele.
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
2166175168bits. Observe que nós só temos um 4 no final do baralho, mas se tivermos todos os quatro 4s lá, esse é um caso melhor e precisaríamos de apenas 161 bits para codificar esse baralho, um caso em que a embalagem realmente bate o entropia de uma codificação binária direta da posição ordinal dela.
Agora tenho o código implementado para calcular os requisitos de bit e ele está mostrando, em média, cerca de 175 bits por deck com um mínimo de 155 e um máximo de 183 para o arquivo de teste de 3 milhões de deck. Portanto, meu algoritmo parece usar 9 bits extras por deck versus a codificação binária direta do método da posição ordinal. Não é tão ruim com apenas 5,5% de espaço de armazenamento adicional necessário. 176 bits são exatamente 22 bytes, o que é um pouco melhor que 52 bytes por deck. Pacotes de melhor case (não apareceu em 3 milhões de arquivos de teste de deck) com 136 bits e pior cenário (apareceu no arquivo de teste 8206 vezes) é de 183 bits. A análise mostra que o pior caso é quando não obtemos o primeiro quad até perto da (ou na) placa 40. Então, como o modo de codificação quer cair rapidamente, somos "presos" blocos de preenchimento (tão grandes quanto 7 placas) em um modo de codificação de bit mais alto. Pode-se pensar que não obter quads até o card 40 seria bastante raro usando um baralho bem baralhado, mas meu programa está me dizendo que aconteceu 321 vezes no arquivo de teste de 3 milhões de decks, de modo que cerca de 1 em cada 9346 decks. Isso é mais frequente do que eu esperava. Eu poderia verificar esse caso e lidar com menos bits, mas é tão raro que não afetaria os bits médios o suficiente.
Também aqui está algo muito interessante. Se eu classificar o baralho nos dados brutos do baralho, o tamanho dos prefixos que repetem um número significativo de vezes é apenas do tamanho 6 (como 222244). No entanto, com os dados compactados, esse comprimento aumenta para cerca de 16. Isso significa que, se eu classificar os dados compactados, conseguirá uma economia significativa apenas indicando ao decodificador um prefixo de 16 bits e, em seguida, apenas exibindo o restante dos decks (menos o prefixo de repetição) que possui o mesmo prefixo, vá para o próximo prefixo e repita. Supondo que eu economize apenas 10 bits por deck dessa maneira, devo vencer os 166 bits por deck. Com a técnica de enumeração declarada por outros, não tenho certeza se o prefixo seria tão longo quanto no meu algoritmo. Além disso, a velocidade de empacotar e descompactar usando meu algoritmo é surpreendentemente boa.
No que diz respeito ao segundo nível de compactação em que classifico as seqüências de bits de saída do meu algoritmo, em seguida, uso a codificação "diferença": Um método muito simples seria codificar os 61.278 prefixos exclusivos de 16 bits que aparecem pelo menos duas vezes nos dados de saída (e um máximo 89 vezes relatado) simplesmente como um bit inicial de 0 na saída para indicar ao descompressor de segundo nível que estamos codificando um prefixo (como 0000111100001111) e, em seguida, todos os decks compactados com o mesmo prefixo seguirão com 1 bit inicial para indique a parte sem prefixo do baralho embalado. O número médio de decks compactados com o mesmo prefixo é de cerca de 49 para cada prefixo, sem incluir os poucos que são únicos (apenas 1 deck possui esse prefixo específico). Parece que posso economizar cerca de 15 bits por deck usando essa estratégia simples (armazenando os prefixos comuns uma vez).
Após o segundo nível de compactação usando a codificação de diferença (prefixo) da saída classificada em bitstring do primeiro codificador, agora estou obtendo cerca de 160 bits por deck. Eu uso o prefixo do comprimento 18 e apenas o armazeno intacto. Como quase todos (245013 de 262144 = 93,5%) desses possíveis prefixos de 18 bits são exibidos, seria ainda melhor codificar os prefixos. Talvez eu possa usar 2 bits para codificar que tipo de dados eu tenho. 00 = prefixo 18 de tamanho normal armazenado, 01 = "prefixo 1 up" (igual ao prefixo anterior, exceto 1 adicionado), 11 = codificação direta a partir do empacotamento do 1º nível (aproximadamente 175 bits em média). 10 = expansão futura quando penso em outra coisa para codificar que economizará bits.
Já alguém bateu 160 bits por baralho? Acho que posso diminuir um pouco o meu com algumas experiências e o uso dos descritores de 2 bits que mencionei acima. Talvez isso chegue ao fim. Meu objetivo é chegar a 156 bits (ou melhor), porque seriam 3 bits por cartão ou menos. Muito impressionante. Muitas experiências para chegar a esse nível, porque se eu mudar a codificação do primeiro nível, tenho que testar novamente qual é a melhor codificação do segundo nível e há muitas combinações para tentar. Algumas alterações que eu faço podem ser boas para outros dados aleatórios semelhantes, mas algumas podem ser tendenciosas em relação a esse conjunto de dados. Não tenho muita certeza, mas se eu tiver vontade, posso tentar outro conjunto de dados de 3 milhões de decks para ver como acontece se eu obtiver resultados semelhantes.
1050.
Alguém tem alguma idéia de como melhorar meu algoritmo, como em outros casos que eu deveria codificar que reduziriam, em média, bits de armazenamento para cada deck? Qualquer um?
Mais duas coisas: 1) Estou um pouco decepcionado com o fato de mais pessoas não terem votado na minha solução, que apesar de não ser ótima no espaço, ainda é decente e bastante fácil de implementar (fiz a minha funcionar bem). 2) Fiz uma análise no meu arquivo de dados de 3 milhões de baralhos e notei que o cartão que ocorre com mais frequência onde o 1º ranking ocupa (como 4444) é o cartão 26. Isso acontece cerca de 6,711% do tempo (em 201322 dos 3 milhões de baralhos ) Eu esperava usar essas informações para comprimir mais, como iniciar no modo de codificação de 12 símbolos, pois sabemos que, em média, não veremos todas as classificações até o meio do dia, mas esse método não conseguiu compactar, pois a sobrecarga excedeu a economia. Estou procurando por alguns ajustes no meu algoritmo que podem realmente salvar bits.
Alguém tem alguma idéia do que devo tentar a seguir para economizar alguns bits por deck usando meu algoritmo? Estou procurando por um padrão que ocorra com frequência suficiente para que eu possa reduzir os bits por baralho, mesmo após a sobrecarga extra de informar ao decodificador qual padrão esperar. Eu estava pensando em algo com as probabilidades esperadas dos restantes cartões invisíveis e agrupando todos os restantes em um único balde. Isso me permitirá entrar em um modo de codificação inferior mais rápido e talvez salvar alguns bits, mas duvido.
Além disso, para sua informação, gerei 10 milhões de shuffles aleatórios e os armazenei em um banco de dados para facilitar a análise. Apenas 488 deles terminam em um quadrilátero (como o 5555). Se eu empacotar apenas aqueles que usam meu algoritmo, recebo 165.71712 bits, em média, com um mínimo de 157 bits e um máximo de 173 bits. Um pouco abaixo dos 166 bits usando o outro método de codificação. Estou um pouco surpreso com a raridade deste caso (cerca de 1 em cada 20.492 embaralhamentos em média).