Là một giải pháp thay thế cho vấn đề này, thuật toán của tôi sử dụng các bit phân đoạn (không nguyên) cho mỗi thẻ cho các nhóm thẻ trong bộ bài dựa trên số lượng còn lại chưa được xếp hạng. Nó là một thuật toán khá thanh lịch. Tôi đã kiểm tra thuật toán mã hóa của mình bằng tay và nó có vẻ tốt. Bộ mã hóa đang xuất ra những gì có vẻ là bitstrings chính xác (ở dạng byte để đơn giản).
Tổng quan về thuật toán của tôi là nó sử dụng kết hợp các nhóm thẻ và mã hóa bit phân đoạn hỗn hợp. Ví dụ, trong tập tin thử nghiệm chia sẻ của tôi về triệu sàn xáo trộn, người đầu tiên có người đầu tiên 7 thẻ của 54 Một 236 J . Lý do tôi chọn kích thước khối 7 thẻ khi có thể xếp hạng 13 thẻ là vì 13 7 "dây giày" (vừa khít) thành 26 bit (kể từ 13 7 = 62 , 748 , 517 và 2 26 = 67 , 108 ,3754 A 236 J7131372613762 , 748 , 51722667 , 108 , 864). Lý tưởng nhất là chúng tôi muốn số đó càng gần càng tốt (nhưng với công suất của 2 số cao hơn một chút) vì vậy chúng tôi không lãng phí nhiều hơn một phần rất nhỏ của một chút trong quy trình đóng gói bit. Lưu ý tôi cũng có thể chọn nhóm 4 khi mã hóa 13 cấp bậc kể từ 13 4 = 28 , 561 và 2 15 = 32 , 768 . Nó không phải là một sự phù hợp chặt chẽ kể từ 15 / 4 = 3,75 nhưng 26 / 7 = 3,714241313428 , 56121532 , 76815 / 4 = 3,7526 / 7 = 3,714. Vì vậy, số bit cho mỗi thẻ là hơi thấp mỗi thẻ nếu chúng ta sử dụng phương pháp đóng gói.26 / 7
Vì vậy, nhìn vào , chúng tôi chỉ đơn giản là tìm kiếm vị trí thứ tự của các cấp bậc đó trong danh sách " 23456789 T J Q K A " của chúng tôi . Ví dụ: thứ hạng thẻ thực tế đầu tiên là 5 có vị trí tra cứu trong chuỗi tra cứu thứ hạng 4 . Chúng tôi chỉ coi 7 vị trí xếp hạng này là số 13 cơ sở bắt đầu bằng 0 (vì vậy vị trí 4 chúng tôi có trước đây sẽ thực sự là 3). Chuyển đổi trở lại cơ sở 10 (cho mục đích kiểm tra), chúng tôi nhận được 15 , 565 , 975 . Trong 2654 A 236 J23456789 TJQ KMột547131015 , 565 , 97526bit nhị phân, chúng tôi nhận được .00111011011000010010010111
Bộ giải mã hoạt động theo cách rất giống nhau. (Ví dụ), chuỗi bit đó sẽ chuyển đổi thành số thập phân (cơ số 10) để lấy 15 , 565 , 975 , sau đó chuyển đổi nó thành cơ sở 13 để lấy các giá trị bù vào chuỗi tra cứu xếp hạng, sau đó nó sẽ tái tạo lại thứ hạng cùng một lúc và được bản gốc 54 một 236 J đầu tiên 7 thẻ. Lưu ý rằng kích thước khối của bit sẽ không phải là 26 nhưng sẽ luôn bắt đầu ở mức 26 trong mỗi sàn. Cả bộ mã hóa và giải mã đều có một số thông tin quan trọng về dữ liệu boong ngay cả trước khi chúng hoạt động. Đó là một điều đặc biệt tốt đẹp về thuật toán này.2615 , 565 , 9751354 A 236 J7
Mỗi # ngạch còn lại (ví dụ như có groupsize riêng của mình và chi phí (# bit mỗi thẻ). Chúng được tìm thấy bằng thực nghiệm chỉ chơi xung quanh với sức mạnh của 13 , 12 , 11 ... và sức mạnh của 2 . Tôi đã giải thích làm thế nào tôi có được các nhóm khi chúng ta có thể nhìn thấy 13 cấp bậc, vậy còn khi chúng ta giảm xuống còn 12 cấp bậc thì sao? Phương pháp tương tự. Nhìn vào sức mạnh của 12 và dừng lại khi một trong số chúng đến rất gần với sức mạnh 2 nhưng chỉ hơi ở dưới nó. 13 , 12 , 11 . . . , 2 , 1 )13 , 12 , 11 ...21312122 = 248 , 832 và 2 18 = 262 , 144 . Đó là một phù hợp khá chặt chẽ. Số bit mã hóa nhóm này là 18 / 5 = 3,6 . Trong 13 nhóm Thứ hạng của nó là 26 / 7 = 3,714 như vậy là bạn có thể thấy, khi số lượng cấp bậc không hàn giảm (cấp bậc được làm đầy lên như 5555 , 3333 ), số lượng các bit để mã hóa các thẻ giảm.125248 , 832218262 , 14418 / 53.61326 / 73.71455553333
Dưới đây là danh sách đầy đủ các chi phí của tôi (# bit trên mỗi thẻ) cho tất cả các cấp bậc có thể được nhìn thấy:
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 / 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 = 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 / 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. Nếu bộ bài kết thúc trên một cặp (chẳng hạn như 77), bộ ba / bộ (chẳng hạn như 777) hoặc bộ tứ (chẳng hạn như 7777), chúng tôi sẽ nhận được khoản tiết kiệm bổ sung cho bộ bài đó bằng thuật toán của tôi.
3222613163232
Trong bộ bài đầu tiên trong datafile, việc mã hóa thẻ như sau (sơ đồ sẽ đến sau). Định dạng là (nhóm, bit, chế độ mã hóa xếp hạng):
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 KKKKA A A A A40
1103 , 7Ksố 8101Thẻ còn lại. Điều này rất quan trọng vì nó làm cho quá trình mã hóa hiệu quả hơn khi bộ giải mã có thể đưa ra các giả định chính xác mà không cần bộ mã hóa phải truyền thêm thông điệp đến nó.
313121110
26 26 26 18 18 10 9 17 13 5 0
54 A 236 J 87726 Q 3 3969 A A A Q JK7 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. Lưu ý rằng chúng tôi chỉ có 4 số duy nhất ở cuối bộ bài nhưng nếu thay vào đó chúng tôi có tất cả bốn chiếc 4s ở đó, thì đó là trường hợp tốt hơn và chúng tôi chỉ cần 161 bit để mã hóa bộ bài đó, một trường hợp trong đó việc đóng gói thực sự đánh bại entropy của một mã hóa nhị phân thẳng của vị trí thứ tự của nó.
Bây giờ tôi có mã được triển khai để tính toán các yêu cầu bit và nó đang hiển thị cho tôi trung bình, khoảng 175 bit trên mỗi sàn với mức thấp 155 và mức cao là 183 cho tệp thử nghiệm 3 triệu boong. Vì vậy, thuật toán của tôi dường như sử dụng thêm 9 bit cho mỗi bộ so với mã hóa nhị phân thẳng của phương thức vị trí thứ tự. Không quá tệ khi chỉ cần thêm 5,5% dung lượng lưu trữ. 176 bit chính xác là 22 byte nên tốt hơn một chút so với 52 byte trên mỗi sàn. Boong trường hợp tốt nhất (không hiển thị trong 3 triệu tệp thử nghiệm boong) gói tới 136 bit và boong trường hợp xấu nhất (đã xuất hiện trong testfile 8206 lần), là 183 bit. Phân tích cho thấy trường hợp xấu nhất là khi chúng tôi không nhận được bộ tứ đầu tiên cho đến khi gần (hoặc tại) thẻ 40. Sau đó, khi chế độ mã hóa muốn giảm nhanh, chúng tôi bị "kẹt" các khối điền (lớn bằng 7 thẻ) trong một chế độ mã hóa bit cao hơn. Mọi người có thể nghĩ rằng việc không nhận được bất kỳ quads nào cho đến khi thẻ 40 sẽ khá hiếm khi sử dụng một cỗ bài được xáo trộn tốt, nhưng chương trình của tôi nói với tôi rằng nó đã xảy ra tới 321 lần trong 3 triệu sàn để có khoảng 1 trên 9346 sàn. Đó là thường xuyên hơn mà tôi đã mong đợi. Tôi có thể kiểm tra trường hợp này và xử lý nó với ít bit hơn nhưng hiếm khi nó không ảnh hưởng đến các bit trung bình đủ.
Ngoài ra đây là một cái gì đó rất thú vị. Nếu tôi sắp xếp bộ bài trên dữ liệu bộ bài thô, độ dài của các tiền tố lặp lại một số lần đáng kể chỉ bằng khoảng 6 (chẳng hạn như 222244). Tuy nhiên, với dữ liệu được đóng gói, độ dài đó tăng lên khoảng 16. Điều đó có nghĩa là nếu tôi sắp xếp dữ liệu được đóng gói, tôi sẽ có thể nhận được một khoản tiết kiệm đáng kể bằng cách chỉ ra cho bộ giải mã một tiền tố 16 bit và sau đó chỉ xuất phần còn lại của các sàn (trừ tiền tố lặp lại) có cùng tiền tố đó, sau đó chuyển sang tiền tố tiếp theo và lặp lại. Giả sử tôi tiết kiệm thậm chí chỉ 10 bit trên mỗi sàn theo cách này, tôi nên đánh bại 166 bit trên mỗi sàn. Với kỹ thuật liệt kê được người khác nêu, tôi không chắc liệu tiền tố có dài như thuật toán của tôi không. Ngoài ra tốc độ đóng gói và giải nén bằng thuật toán của tôi là tốt đáng ngạc nhiên.
Về mức độ nén thứ 2 trong đó tôi sắp xếp các bit đầu ra của thuật toán của mình sau đó sử dụng mã hóa "khác biệt": Một phương pháp rất đơn giản là mã hóa 61.278 tiền tố 16 bit duy nhất hiển thị ít nhất hai lần trong dữ liệu đầu ra (và tối đa trong 89 lần được báo cáo) chỉ đơn giản là một bit đầu 0 trong đầu ra để chỉ ra cho bộ giải nén cấp 2 rằng chúng tôi đang mã hóa một tiền tố (chẳng hạn như 0000111100001111) và sau đó bất kỳ sàn đóng gói nào có cùng tiền tố đó sẽ đi theo với 1 bit đầu chỉ ra phần không tiền tố của bộ bài đóng gói. Số sàn trung bình được đóng gói có cùng tiền tố là khoảng 49 cho mỗi tiền tố, không bao gồm số sàn duy nhất (chỉ có 1 sàn có tiền tố cụ thể đó). Dường như tôi có thể tiết kiệm khoảng 15 bit cho mỗi bộ bài bằng cách sử dụng chiến lược đơn giản này (lưu trữ các tiền tố phổ biến một lần).
Sau mức nén thứ 2 bằng cách sử dụng mã hóa chênh lệch (tiền tố) của đầu ra chuỗi bit được sắp xếp của bộ mã hóa đầu tiên, giờ tôi nhận được khoảng 160 bit trên mỗi sàn. Tôi sử dụng tiền tố dài 18 và chỉ lưu nó nguyên vẹn. Vì hầu hết tất cả (245013 trong số 262144 = 93,5%) trong số các tiền tố 18 bit có thể xuất hiện, sẽ tốt hơn nếu mã hóa các tiền tố. Có lẽ tôi có thể sử dụng 2 bit để mã hóa loại dữ liệu nào tôi có. 00 = độ dài thông thường 18 tiền tố được lưu trữ, 01 = "1 tiền tố lên" (giống như tiền tố trước trừ 1 được thêm vào), 11 = mã hóa thẳng từ đóng gói cấp 1 (trung bình khoảng 175 bit). 10 = mở rộng trong tương lai khi tôi nghĩ ra một thứ khác để mã hóa sẽ tiết kiệm bit.
Có ai khác đánh bại 160 bit mỗi sàn chưa? Tôi nghĩ rằng tôi có thể nhận được mức thấp hơn một chút với một số thử nghiệm và sử dụng các mô tả 2 bit tôi đã đề cập ở trên. Có lẽ nó sẽ chạm đáy ở 158ish. Mục tiêu của tôi là đưa nó lên 156 bit (hoặc tốt hơn) bởi vì đó sẽ là 3 bit cho mỗi thẻ hoặc ít hơn. Rất ấn tượng. Rất nhiều thử nghiệm để đưa nó xuống mức đó bởi vì nếu tôi thay đổi mã hóa cấp đầu tiên thì tôi phải kiểm tra lại mã hóa cấp 2 tốt nhất và có nhiều kết hợp để thử. Một số thay đổi tôi thực hiện có thể tốt cho dữ liệu ngẫu nhiên tương tự khác nhưng một số thay đổi có thể bị sai lệch đối với tập dữ liệu này. Không thực sự chắc chắn nhưng nếu tôi bị thôi thúc, tôi có thể thử thêm 3 triệu tập dữ liệu để xem điều gì xảy ra nếu tôi nhận được kết quả tương tự trên đó.
1050
Có ai có bất kỳ ý tưởng nào về cách làm cho thuật toán của tôi tốt hơn như những trường hợp khác tôi nên mã hóa để giảm trung bình bit cho mỗi tầng không? Bất kỳ ai?
Thêm 2 điều nữa: 1) Tôi hơi thất vọng vì nhiều người không ủng hộ giải pháp của tôi, mặc dù không tối ưu về không gian, nhưng vẫn rất tốt và khá dễ thực hiện (Tôi đã làm việc tốt). 2) Tôi đã phân tích trên 3 triệu cơ sở dữ liệu boong của mình và nhận thấy rằng thẻ xảy ra thường xuyên nhất trong đó xếp hạng thứ nhất (chẳng hạn như 4444) là ở thẻ 26. Điều này xảy ra khoảng 6,711% thời gian (cho năm 20122 trong số 3 triệu sàn ). Tôi đã hy vọng sử dụng thông tin này để nén nhiều hơn, chẳng hạn như bắt đầu ở chế độ mã hóa 12 ký hiệu vì chúng ta biết trung bình chúng ta sẽ không thấy mọi thứ hạng cho đến khi về trung gian nhưng phương pháp này không thể nén được vì chi phí vượt quá mức tiết kiệm. Tôi đang tìm kiếm một số điều chỉnh cho thuật toán của tôi mà thực sự có thể tiết kiệm bit.
Vì vậy, có ai có bất kỳ ý tưởng nào tôi nên thử tiếp theo để tiết kiệm một vài bit trên mỗi sàn bằng thuật toán của tôi không? Tôi đang tìm kiếm một mô hình xảy ra đủ thường xuyên để tôi có thể giảm các bit trên mỗi sàn ngay cả khi có thêm chi phí để nói với bộ giải mã mô hình nào sẽ xảy ra. Tôi đã suy nghĩ điều gì đó với xác suất dự kiến của các thẻ chưa nhìn thấy còn lại và bỏ tất cả các thẻ còn lại vào một thùng duy nhất. Điều này sẽ cho phép tôi thả vào chế độ mã hóa thấp hơn nhanh hơn và có thể tiết kiệm một số bit nhưng tôi nghi ngờ điều đó.
Ngoài ra, FYI, tôi đã tạo ra 10 triệu xáo trộn ngẫu nhiên và lưu trữ chúng trong cơ sở dữ liệu để phân tích dễ dàng. Chỉ 488 trong số họ kết thúc trong một hình tứ giác (chẳng hạn như 5555). Nếu tôi chỉ đóng gói những người sử dụng thuật toán của mình, tôi nhận được trung bình 165.71712 bit với mức thấp là 157 bit và mức cao là 173 bit. Chỉ hơi thấp hơn 166 bit bằng phương pháp mã hóa khác. Tôi hơi ngạc nhiên khi thấy trường hợp này không thường xuyên (trung bình cứ khoảng 20.492 lần xáo trộn trung bình).