高度压缩数字网格

时间:2012-09-12 23:01:09

标签: c++ c

我有一个包含数字的正方形网格,我需要对其进行大量压缩,以便可以通过网络轻松传输。例如,无论网格中的数字值如何,我都需要能够将40x40网格压缩为小于512字节。这是我的基本要求。

每个网格的单元格包含一个0-7的数字,因此每个单元格可以容纳3位。

有谁知道一个可以实现我想要的好算法?

3 个答案:

答案 0 :(得分:2)

您可以对信息进行不同的编码。您不需要为所有数字0到7分配具有相同位数的代码。您可以根据序列中的次数进行分配。

首先阅读计算每个数字出现次数的整个序列。 基于此,您可以为每个数字分配代码。 如果您分配以下代码,例如Huffman code,则代码将是前缀代码,这意味着没有额外的字符来分隔数字。

根据您的测试结果,您可以在算法上引入某些变体来微调压缩率。

我在一个项目(大学)中使用了这种技术,它总体上提供了良好的结果。至少它应该接近每个字符的理论3位,并且如果概率分布有帮助可以更好。

答案 1 :(得分:1)

正如其他人所说,所述问题是不可能的,因为需要600个字节来表示所有可能的网格。 600字节来自40行,40列,每个单元3比特,每字节8比特(40 * 40 * 3 / 8)。正如Kerrek SB在评论中解释的那样,你将8个单元格打包成3个字节。

在您自己的评论中,您提到这是通过网络传输的游戏状态。假设您有一种机制来确保数据的可靠传输,那么如果在更新之间可以更改的单元数量存在合理限制,或者如果允许在特定数量的单元格更改时发送更新,则可以实现512字节的表示。如果使用1位来表示单元格是否已更改,则需要200个字节。然后,您有312个剩余字节来表示已更改的单元格的新值。因此,您最多可以代表312*8/3 = 832个已修改的单元格。

另外,这种表示法可以在不到600字节的情况下表示最多1064个已更改的单元格。

答案 2 :(得分:1)

您要做的是对数据执行“burrowes-wheeler”转换,然后对其进行压缩。在这种情况下,行程编码就足够了。

http://en.wikipedia.org/wiki/Burrows%E2%80%93Wheeler_transform

在你的情况下,这可能会超过霍夫曼。

在某些情况下,您需要超过512个字节。所以在你的协议中只是为“反常”网格做一个例外。但在一般情况下,你应该容易在512以下。