Comme solution alternative à ce problème, mon algorithme utilise des bits fractionnaires composés (non entiers) par carte pour des groupes de cartes dans le jeu en fonction du nombre de rangs non remplis qui restent. C'est un algorithme assez élégant. J'ai vérifié mon algorithme d'encodage à la main et il a l'air bien. L'encodeur sort ce qui semble être des chaînes de bits correctes (sous forme d'octets pour plus de simplicité).
3sept54 A 236 Jsept1313sept2613sept62 , 748 , 51722667 , 108 , 864241313428 , 56121532 , 76815 / quatre = 3,7526 / sept = 3,71426 / 7
54 A 236 J23456789 TJQ KUNE54sept13dix15 , 565 , 9752600111011011000010010010111
2615 , 565 , 9751354 A 236 Jsept
13 , 12 , 11 . . . , 2 , 1 )13 , 12 , 11 ...21312122125248 , 832218262 , 14418 / 53.61326 / 73.71455553333
Voici ma liste complète des coûts (# de bits par carte) pour tous les # possibles de rangs à voir:
13 26 / 7 = 3,714 = 3 cinq / 7
12 dix-huit / 5 = 3,600 = 3 3 / 5
11 sept / deux = 3,500 = 3 une / deux
10 10 / 3 = 3,333 = 3 1 / 3
9 16 / 5 = 3,200 = 3 une / 5
8 3 / une = 3,000 = 3
7 dix-sept / 6 = 2,833 = 2 cinq / 6
6 treize / 5 = 2,600 = 2 3 / 5
5 7 / 3 = 2,333 = 2 1 / 3
4 2 / une = 2,000 = 2
3 5 / 3 = 1,667 = 1 2 / 3
2 1 / 1 = 1,000 = 1
1 0 / 1..4 = 0,0 = 0
sept5 , 6 , 7 , 7 , 7 , 7 , KK1312sept13K21 , 2 , 3 ...3131sept20
16813 , 12 , 11
10777748sept4septs. Si le jeu se termine sur une paire (comme 77), triple / set (comme 777) ou un quad (comme 7777), nous obtenons des économies supplémentaires pour ce jeu en utilisant mon algorithme.
3222613163232
Dans le premier deck du fichier de données, l'encodage des cartes est le suivant (schéma à venir plus tard). Le format est (taille de groupe, bits, mode d'encodage de rang):
7 , 26 , 13sept2613
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 KKKKA A A A40
1dix3 , 7K8dix1carte restante. Ceci est important car il rend le processus d'encodage plus efficace lorsque le décodeur peut émettre des hypothèses correctes sans que l'encodeur n'ait à lui transmettre des messages supplémentaires.
3131211dix
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
2166175168morceaux. Notez que nous n'avons obtenu qu'un seul 4 à la fin du jeu, mais si au lieu de cela, nous avons tous les quatre 4, c'est un meilleur cas et nous n'aurions eu besoin que de 161 bits pour coder ce jeu, un cas où l'emballage bat réellement le entropie d'un codage binaire droit de la position ordinale de celui-ci.
J'ai maintenant le code implémenté pour calculer les exigences en bits et il me montre en moyenne environ 175 bits par deck avec un minimum de 155 et un maximum de 183 pour le fichier de test de 3 millions de deck. Mon algorithme semble donc utiliser 9 bits supplémentaires par jeu par rapport au codage binaire droit de la méthode de position ordinale. Pas trop mal avec seulement 5,5% d'espace de stockage supplémentaire requis. 176 bits est exactement 22 octets, ce qui est un peu mieux que 52 octets par platine. Le meilleur paquet de cas (n'apparaissait pas dans 3 millions de fichiers de test de paquet) contient 136 bits et le pire cas (il est apparu dans le fichier de test 8206 fois), est de 183 bits. L'analyse montre que le pire des cas est lorsque nous n'obtenons le premier quadruple que près (ou au niveau) de la carte 40. Ensuite, comme le mode d'encodage veut tomber rapidement, nous sommes "bloqués" en remplissant des blocs (jusqu'à 7 cartes) dans un mode de codage de bits supérieur. On pourrait penser que ne pas obtenir de quads avant la carte 40 serait assez rare en utilisant un deck bien mélangé, mais mon programme me dit que cela s'est produit 321 fois dans le fichier de test de 3 millions de decks, ce qui fait environ 1 sur 9346 decks. C'est plus souvent que je m'y attendais. Je pourrais vérifier ce cas et le gérer avec moins de bits, mais il est si rare qu'il n'affecterait pas suffisamment les bits moyens.
Voici aussi autre chose de très intéressant. Si je trie le jeu sur les données brutes du jeu, la longueur des préfixes qui se répètent un nombre significatif de fois n'est que de la longueur 6 (comme 222244). Cependant, avec les données compressées, cette longueur augmente à environ 16. Cela signifie que si je trie les données compressées, je devrais être en mesure de réaliser des économies importantes en indiquant simplement au décodeur un préfixe de 16 bits, puis en sortant simplement le reste des ponts (moins le préfixe répétitif) qui ont le même préfixe, puis passez au préfixe suivant et répétez. En supposant que j'économise même seulement 10 bits par deck de cette façon, je devrais battre les 166 bits par deck. Avec la technique d'énumération indiquée par d'autres, je ne sais pas si le préfixe serait aussi long qu'avec mon algorithme. De plus, la vitesse d'emballage et de déballage en utilisant mon algorithme est étonnamment bonne.
Concernant le 2ème niveau de compression où je trie les chaînes de bits de sortie de mon algorithme, puis j'utilise un codage "différence": Une méthode très simple serait de coder les 61.278 préfixes 16 bits uniques qui apparaissent au moins deux fois dans les données de sortie (et un maximum de 89 fois rapporté) simplement comme un bit de tête de 0 dans la sortie pour indiquer au décompresseur de 2e niveau que nous encodons un préfixe (tel que 0000111100001111), puis tous les ponts emballés avec ce même préfixe suivront avec un bit de tête de 1 à indiquer la partie non préfixe du paquet emballé. Le nombre moyen de decks emballés avec le même préfixe est d'environ 49 pour chaque préfixe, sans compter les quelques uns qui sont uniques (seulement 1 deck a ce préfixe particulier). Il semble que je puisse économiser environ 15 bits par jeu en utilisant cette stratégie simple (en stockant une fois les préfixes communs).
Après le 2ème niveau de compression utilisant le codage de différence (préfixe) de la sortie de chaîne de bits triée du premier codeur, j'obtiens maintenant environ 160 bits par platine. J'utilise le préfixe de longueur 18 et je le stocke intact. Étant donné que presque tous (245013 sur 262144 = 93,5%) de ces préfixes 18 bits possibles apparaissent, il serait encore mieux de coder les préfixes. Je peux peut-être utiliser 2 bits pour coder le type de données dont je dispose. 00 = longueur régulière 18 préfixe stocké, 01 = "1 préfixe supérieur" (identique au préfixe précédent sauf 1 ajouté), 11 = codage direct à partir d'un emballage de 1er niveau (environ 175 bits en moyenne). 10 = extension future quand je pense à autre chose à encoder qui sauvera des bits.
Quelqu'un d'autre a-t-il déjà battu 160 bits par jeu? Je pense que je peux obtenir le mien un peu plus bas avec quelques expériences et en utilisant les descripteurs 2 bits que j'ai mentionnés ci-dessus. Peut-être qu'il atteindra un creux à 158ish. Mon objectif est de l'amener à 156 bits (ou mieux) car ce serait 3 bits par carte ou moins. Très impressionnant. Beaucoup d'expérimentations pour descendre à ce niveau car si je change l'encodage de premier niveau, je dois retester qui est le meilleur encodage de 2ème niveau et il y a beaucoup de combinaisons à essayer. Certaines modifications que je fais peuvent être bonnes pour d'autres données aléatoires similaires, mais certaines peuvent être biaisées vers cet ensemble de données. Pas vraiment sûr, mais si j'ai envie, je peux essayer un autre ensemble de données de 3 millions de jeux pour voir ce qui se passe si j'obtiens des résultats similaires.
dix50
Quelqu'un a-t-il des idées sur la façon d'améliorer mon algorithme, comme les autres cas que je devrais encoder, ce qui réduirait en moyenne les bits de stockage pour chaque deck? N'importe qui?
2 autres choses: 1) Je suis quelque peu déçu que plus de gens n'aient pas voté pour ma solution qui, bien qu'elle ne soit pas optimale dans l'espace, est toujours décente et assez facile à mettre en œuvre (la mienne fonctionnait bien). 2) J'ai fait une analyse sur mon fichier de données de 3 millions de deck et j'ai remarqué que la carte la plus fréquente où le premier rang se remplit (comme 4444) est à la carte 26. Cela se produit environ 6,711% du temps (pour 201322 des 3 millions de decks ). J'espérais utiliser ces informations pour compresser davantage, comme commencer en mode d'encodage à 12 symboles, car nous savons qu'en moyenne, nous ne verrons pas tous les rangs jusqu'à environ middeck, mais cette méthode n'a pas réussi à compresser tout car les frais généraux dépassaient les économies. Je cherche quelques ajustements à mon algorithme qui peuvent réellement sauver des bits.
Alors, quelqu'un a-t-il des idées sur ce que je devrais essayer ensuite pour économiser quelques bits par jeu en utilisant mon algorithme? Je recherche un modèle qui se produit assez fréquemment pour que je puisse réduire les bits par platine même après la surcharge supplémentaire de dire au décodeur quel modèle à attendre. Je pensais à quelque chose avec les probabilités attendues des cartes invisibles restantes et je regroupais toutes les cartes restantes dans un seul seau. Cela me permettra de passer plus rapidement en mode d'encodage inférieur et peut-être d'enregistrer quelques bits mais j'en doute.
Aussi, pour info, j'ai généré 10 millions de shuffles aléatoires et les ai stockés dans une base de données pour une analyse facile. Seuls 488 d'entre eux se terminent en quad (comme 5555). Si je n'emballe que ceux qui utilisent mon algorithme, j'obtiens 165.71712 bits en moyenne avec un minimum de 157 bits et un maximum de 173 bits. Juste légèrement en dessous des 166 bits en utilisant l'autre méthode de codage. Je suis quelque peu surpris de la rareté de ce cas (environ 1 sur 20 492 shuffles en moyenne).