이 문제에 대한 대체 솔루션으로, 내 알고리즘은 남아있는 채워지지 않은 순위 수에 따라 데크의 카드 그룹에 대해 카드 당 복합 소수 (비정 수) 비트를 사용합니다. 다소 우아한 알고리즘입니다. 인코딩 알고리즘을 손으로 확인했는데 좋아 보인다. 인코더가 올바른 비트 스트링 (간단 성을 위해 바이트 형식)으로 보이는 것을 출력하고 있습니다.
삼754 A 236 J7131372613762 , 748 , 51722667 , 108 , 864241313428 , 56121532 , 76815 / 4 = 3.7526 / 7 = 3.714. 우리가 사용하는 경우 카드 당 비트 수 그래서 카드 당 약간 낮은 포장 방법을.26 / 7
그래서보고 , 우리는 단순히 우리의 마스터 "에서 그 계급의 서수 위치를 찾아 23456789 T J Q K "정렬 된 계급의 목록을. 예를 들어, 첫 번째 실제 카드 순위 5 는 순위 조회 문자열에서 조회 위치가 4 입니다. 우리는이 7 순위 위치 를 0으로 시작 하는 기본 13 숫자 로 취급합니다 (따라서 이전에 얻은 위치 4는 실제로 3이됩니다). (확인 목적으로) 기본 10으로 다시 변환 하면 15 , 565 , 975가 됩니다. 에서 (26)54 A 236 J23456789 T제이큐 K에이547131015 , 565 , 97526이진 비트는 입니다.00111011011000010010010111
2615 , 565 , 9751354 A 236 J7
도 13 , 12 , 11 . . . , 2 , 1 )13 , 12 , 11 ...21312122125248 , 832218262 , 14418 / 53.61326 / 73.71455553333
다음은 가능한 모든 순위의 비용에 대한 전체 비용 목록 (카드 당 비트 수)입니다.
(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 , K케이1312713케이21 , 2 , 3 ...삼131720
16813 , 12 , 11
10777748747에스. 데크가 쌍 (예 : 77), 트리플 / 세트 (예 : 777) 또는 쿼드 (예 : 7777)로 끝나면 알고리즘을 사용하여 해당 데크를 추가로 절약 할 수 있습니다.
3222613163232
데이터 파일의 첫 번째 데크에서 카드 인코딩은 다음과 같습니다 (나중에 다이어그램). 형식은 (그룹 크기, 비트, 순위 인코딩 모드)입니다.
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 ...삼22223333444455556666777788889999 T티티티제이제이제이제이Q Q Q Q K케이케이케이A A A A40
1103 , 7케이810순위 모드, 아마도 그 갑판에 더 적은 비트를 사용할 수 있습니다. 여러 카드의 특수 "그룹화 된"버킷에있는 카드 중 하나를 볼 때, 그 특수 "랭크"(실제 등급이 아니라 특정 버킷에서 무언가를 본 지표)를 출력 한 다음 몇 가지 더 비트가 디코더에서 내가 본 버킷의 카드를 알려 주면 그 카드를 그룹에서 제거합니다 (방금 채워 졌으므로). 나는 이것을 사용하여 비트 절약이 가능한지 알아보기 위해 이것을 손으로 추적 할 것입니다. 이 특수 버킷을 사용하면 모호성이 없어야합니다. 인코더와 디코더 모두 카드를 계산하고 어느 등급이 인지 만 알기 때문입니다.1남은 카드. 이는 인코더가 추가 메시지를 전달하지 않고 디코더가 올바른 가정을 할 수있을 때 인코딩 프로세스를보다 효율적으로 만들기 때문에 중요합니다.
삼13121110
26 26 26 18 18 10 9 17 13 5 0
54 A 236 J 87726 Q 3 3969 A A A Q J 케이7 개 T 9292 문 36 K 제이57 톤 8 개 T케이제이4 48 Q 8 T 55 K 4
(13) (12) 의 X , Y 98 7 6 543 2 1 0
2166175168비트. 데크 끝 부분에 단일 4 개만 있지만 대신 4 개 4 개가 모두있는 경우 더 나은 경우이며 해당 데크를 인코딩하는 데 161 비트 만 있으면됩니다. 패킹이 실제로 그것의 서수 위치의 직선 이진 인코딩의 엔트로피.
이제 비트 요구 사항을 계산하기 위해 코드를 구현했으며 3 백만 데크 테스트 파일의 경우 데크 당 약 175 비트, 155의 낮은 값과 183의 높은 값을 보여줍니다. 그래서 내 알고리즘은 데크 당 9 개의 추가 비트와 서수 위치 방법의 직선 이진 인코딩을 사용하는 것으로 보입니다. 5.5 %의 추가 스토리지 공간 만 있으면 나쁘지 않습니다. 176 비트는 정확히 22 바이트이므로 데크 당 52 바이트보다 훨씬 낫습니다. 최상의 경우 데크 (3 백만 개의 데크 테스트 파일에 표시되지 않음)를 136 비트로 압축하고 최악의 경우 데크 (테스트 파일에 8206 번 표시됨)는 183 비트입니다. 분석에 따르면 최악의 경우는 카드 40에 가까워 질 때까지 첫 번째 쿼드를 얻지 못하는 경우입니다. 그런 다음 인코딩 모드가 빠르게 떨어지기를 원할 때 블록에 (7 카드만큼 큰) 채우기 블록이 "고정"됩니다 더 높은 비트 인코딩 모드. 잘 섞인 데크를 사용하여 카드 40까지 쿼드를 얻는 것은 매우 드물다고 생각할 수도 있지만, 내 프로그램은 3 백만 데크의 테스트 파일에서 321 번 발생하여 9346 데크마다 약 1 번 발생한다고 알려줍니다. 내가 예상했던 것보다 더 자주입니다. 이 경우를 확인하고 더 적은 비트로 처리 할 수는 있지만 평균 비트에 충분히 영향을 미치지 않는 경우는 거의 없습니다.
여기 또 다른 흥미로운 것이 있습니다. 원시 데크 데이터에서 데크를 정렬하면 상당한 횟수의 반복되는 접두사 길이는 길이가 약 6 (예 : 222244)입니다. 그러나 압축 된 데이터의 경우 길이는 약 16으로 증가합니다. 즉, 압축 된 데이터를 정렬하면 디코더에 16 비트 접두사를 표시 한 다음 데크의 나머지를 출력하여 상당한 비용을 절감 할 수 있습니다. 동일한 접두사를 가진 (반복 접두사 빼기) 다음 접두사로 이동하여 반복하십시오. 이 방법으로 데크 당 10 비트 만 절약한다고 가정하면 데크 당 166 비트를 이길 수 있습니다. 다른 사람들이 열거 한 열거 기술을 사용하면 접두사가 내 알고리즘만큼 길어질 지 확실하지 않습니다. 또한 내 알고리즘을 사용하여 포장 및 포장 풀기 속도가 놀랍도록 좋습니다.
알고리즘의 출력 비트 열을 정렬하는 두 번째 압축 수준과 관련하여 "차이"인코딩을 사용합니다. 매우 간단한 방법은 출력 데이터에 최소 두 번 표시되는 61,278 개의 고유 한 16 비트 접두사를 인코딩하는 것입니다. 두 번째 레벨 압축 풀기 프로그램에 프리픽스 (예 : 0000111100001111)를 인코딩하고 동일한 프리픽스가있는 팩킹 된 데크는 포장 된 데크의 접두사가 아닌 부분을 나타냅니다. 프리픽스가 동일한 팩킹 된 데크의 평균 수는 각 프리픽스에 대해 약 49 개이며 고유 한 것을 포함하지 않습니다 (1 개의 데크에만 해당 프리픽스가 있음). 이 간단한 전략을 사용하여 데크 당 약 15 비트를 절약 할 수 있습니다 (공통 접두사를 한 번 저장).
첫 번째 인코더의 정렬 된 비트 문자열 출력의 차이 (접두사) 인코딩을 사용하여 두 번째 압축 수준을 얻은 후 데크 당 약 160 비트를 얻습니다. 길이 18 접두사를 사용하고 그대로 저장합니다. 가능한 18 비트 접두사 중 거의 모든 것이 (262144 중에서 245013 = 93.5 %) 나타나기 때문에 접두사를 인코딩하는 것이 훨씬 좋습니다. 아마도 2 비트를 사용하여 어떤 유형의 데이터를 인코딩 할 수 있습니다. 00 = 일반 길이 18 접두사 저장, 01 = "1 업 접두사"(1이 추가 된 것을 제외하고 이전 접두사와 동일), 11 = 첫 번째 레벨 패킹에서 평균 인코딩 (평균 약 175 비트). 10 = 비트를 절약 할 다른 인코딩을 생각할 때 미래 확장.
다른 사람이 아직 갑판 당 160 비트를 이겼습니까? 나는 위에서 언급 한 2 비트 디스크립터를 실험하고 사용하여 조금 더 나아질 수 있다고 생각한다. 아마도 158ish에 바닥이 될 것입니다. 내 목표는 카드 당 3 비트 이하이기 때문에 156 비트 (또는 더 나은)로 만드는 것입니다. 매우 인상적. 첫 번째 레벨 인코딩을 변경하면 최상의 2 레벨 인코딩이며 다시 시도해야 할 조합이 많기 때문에 그 수준으로 낮추기 위해 많은 실험을했습니다. 내가 변경 한 일부 변경 내용은 다른 유사한 임의 데이터에 유용 할 수 있지만 일부는이 데이터 세트에 편향 될 수 있습니다. 확실하지는 않지만 충동이 생기면 비슷한 결과를 얻을 때 어떤 일이 일어나는지 확인하기 위해 3 백만 데크 데이터 세트를 시도 할 수 있습니다.
1050
누구든지 평균적으로 각 데크의 스토리지 비트를 줄 이도록 인코딩 해야하는 다른 경우와 같이 알고리즘을 개선하는 방법에 대한 아이디어가 있습니까? 누군가?
2 더 많은 것들 : 1) 나는 더 많은 사람들이 공간에서 최적은 아니지만 여전히 구현하기에 적당하고 상당히 쉬운 내 솔루션을 공표하지 않았다는 것에 다소 실망했다. 2) 3 백만 개의 데크 데이터 파일을 분석 한 결과 1444 위와 같이 1 순위가 채워지는 가장 자주 발생하는 카드는 26 번 카드라는 것을 알았습니다.이 시간은 약 6.711 % (300 만 데크 중 201322) ). 나는이 정보를 사용하여 12 개의 심볼 인코딩 모드에서 시작하는 등 더 압축하기를 바랐습니다. 왜냐하면 평균 데크까지 모든 순위를 볼 수는 없기 때문에이 방법은 오버 헤드가 절약을 초과하여 압축하지 못했습니다. 실제로 비트를 저장할 수있는 알고리즘에 대한 조정을 찾고 있습니다.
내 알고리즘을 사용하여 데크 당 몇 비트를 절약하기 위해 다음에 시도해야 할 아이디어가 있습니까? 디코더가 어떤 패턴을 기대해야하는지에 대한 과도한 오버 헤드 후에도 데크 당 비트를 줄일 수 있도록 자주 발생하는 패턴을 찾고 있습니다. 나는 보이지 않는 나머지 카드의 예상 확률을 가진 무언가를 생각하고 남아있는 모든 단일 카드를 단일 버킷으로 묶습니다. 이렇게하면 낮은 인코딩 모드로 더 빨리 떨어질 수 있으며 비트를 절약 할 수는 있지만 의심합니다.
또한 참고로, 1 천만 개의 임의 셔플을 생성하여 데이터베이스에 저장하여 쉽게 분석 할 수있었습니다. 그중 488 개만 쿼드 (예 : 5555)로 끝납니다. 내 알고리즘을 사용하여 그것들을 포장하면 평균 165.71712 비트가 157 비트의 낮은 비트와 173 비트의 높은 비트를 얻습니다. 다른 인코딩 방법을 사용하면 166 비트 바로 아래에 있습니다. 나는이 사건이 얼마나 드문 지에 대해 다소 놀랐습니다 (평균 20,492 건의 셔플 중 약 1 건).