我需要帮助来分析这种编程技术来压缩数组

时间:2012-04-07 09:37:49

标签: algorithm compression

我希望读者了解shannon的信息理论,该理论认为与概率为p(a)的事件a相关的信息内容是-log(p(a))。在外行术语中,如果你需要表示0-7范围内的数字,那么你至少需要-log(1/8)= log(8)(其中base是2),即3位。

假设有一个整数数组,范围从0到255.我不是将数组存储为8位数,而是先按升序对数组进行排序(保留一个备份)。不是将每个数组元素编码为8位整数,而是输出它在排序数组中的位置。现在问题是让解码器或接收器知道这个排序的数组。我将输出第一个(最小)整数值作为8位数,然后将增量添加到此数字中。首先是所有排序的数组,后跟元素的顺序,即位置值。

Ex:原始阵列 - > 231,3,45,0,23,32,78

排序数组 - > 0,3,23,32,45,78,231

编码信息为0(排序数组的第一个元素为8位数)然后是3(这是0的增量)然后是20然后是9然后是13,然后是33然后是153.

在发送第一个数字和连续的增量后,我将发送订单,即因为这里有7个整数,我将需要一个3位数的订单,3(原始数组中的0的位置)然后1(3的位置) )然后4(23的位置)然后5(32的位置)然后2(45的位置)然后6(位置78)然后0(位置231)。

,即位置值现在为3,1,4,5,2,6,0

分析看这个方案是否会压缩:

第一个数字 - > 8位(实际上可能需要更少的位,因为它是最小的)

接下来的6个号码 - > 5位(问题是我们可以编码0,3,20,9,13,5位但不是33和153,我们可能需要编码为31(最大为5位))

每个3位的7个位置 - > 21位

total-> 8 + 6×5 + 21 = 59。这超过了我们每次需要编码7个8位数的56位,我们已经实现了扩展而不是压缩,我们的方案是有损的,因为我们无法用一些大数字代表它们。

让我们为这个方案增加一些复杂性。

我将第一个0编码为8位数,紧接着是最后一个数字231的代码。然后我将发送代码为3,下一个增量超过0然后代码为153,减少超过231然后是20然后是33,9 ,13

即我已按不同顺序发送 - >而不是0,3,20,9,13,33,153我将发送为3,153,20,33,9,13

我得到的是你观察到的动态范围的连续减少,我们已经发送了0然后是231然后是3然后153这时值的范围减小了我的意思是下一个增加到3将是20不能大于第二个数字,即78,数字20不能超过75(如果它去,那么第三个数字(3 + 76(比方说))将大于78,明显违反我们的排序假设。

如果你已经理解了这个想法到现在为止我有一个进一步改进的方案,使用二进制搜索的想法来进一步减少动态范围并将这种技术用于类固醇。 这是排序的数组

0,3,23,32,45,78,231

观察排序的数组有7个数字,中间的数字是32.所以现在我们将用32位编码32,然后我们将按顺序发送增量。即32之后的下一个数字将是3,其将编码为29(即32-3),下一个将被编码为46(78-32),然后0编码为3(3-0)然后23编码为20 (23-3)然后45编码为33(78-45),然后最后一编231编码为153(231-78)。

如果您现在看到我们可以根据具体情况决定每个号码使用多少位。

我们将排序的数组发送为32(范围0-255,即8位),29(范围0-32,所以6位),46(范围32-255,所以8位),3(范围0-3)所以2位),20(范围3-32所以5位),33(范围32-78所以6位),153(范围78-255所以8位)

所以总共8 + 6 + 8 + 2 + 5 + 6 + 8 = 43这是非有损的并且超过我们的初始估计值38(8位+ 5 * 6位)所以这增加了7位置值三位共43 + 21 = 64超过56.我们的方案仍在扩大。

我们可以对21位的位置数做些什么改进。因为每次我们发送位置信息,如果我们有7个位置要发送,位置数减少一个,那么位数是log(7)+ log(6)+ log(5)....这就是log(事实) (7))所有对数都是2的位。

观察我使用了公式log(a)+ log(b)= log(ab)

这等于12.299,当加上43等于55.299时,这比一般低于56.但这是不切实际的。我们需要至少3(范围7)+3(范围6)+3(范围5)+2(范围4)+2(范围3)+ 1(范围2)+0(范围1)= 14与43给出57这是扩展。

这项工作的目标是实现数据大小至少减少1位。如果我们将56位压缩到55而没有任何关于数据的假设,那么我们可以取55位的输出并再次压缩到54位。这看起来不可能,这个想法类似于永久机器。现在的任务是看看是什么阻止我们压缩更多。

我需要分析一个更大的数组的例子来看看排序数组的43位是否小于43.还有一个优点是将数组分成多个部分并单独编码每个部分。另一个目标是找到计算表示排序数组所需位数的公式。即给定数组大小和数组元素范围如何找到像43这样的数字。

让我们再次将此3,1,4,5,2,6,0作为未排序的数组,并观察该序列是从0到6的7个数字的5040个排列之一。我们可以将其表示为13位数字(理论建议为12.299)。

我需要知道是否可以更多地压缩这个数组。

2 个答案:

答案 0 :(得分:1)

  

如果我们将56位压缩为55而没有任何关于数据的假设,那么我们可以取55位的输出并再次将其压缩为54位。这看起来不可能,这个想法类似于永久机器。现在的任务是看看是什么阻止我们压缩更多。

如果没有对保证减小所有可能数据值大小的数据的任何假设,就不可能有无损压缩算法。只需pigeon hole principle,我们就可以看到以下内容。使用n位时,可以表示2 ^ n个值。使用n-1位,您只能表示2 ^(n-1)个值。因此,如果您对原始值的一半进行编码,则必须使用与已编码值之一相同的位对下一个值进行编码,因此您将丢失信息。当然,如果在原始数据中只使用少于2 ^(n-1)个不同的值,则可以将该数据的大小减少一点(或更多),但这已经在假设数据。此外,您将无法使用该方法递归地减小数据的大小而不会有任何损失。

因此,您可能会找到一些压缩数组的方法,但仅限于当前压缩方式最多使用一半可能的位模式的情况。这可能是压缩阵列的一些模糊方法,并且肯定会使用一些k位的一半以上的位模式。这个k将是你的门槛,你将无法再减小它的大小。

  

将数组分成多个部分并单独编码每个部分的优点是什么。

如果将数组拆分为较小的部分,则局部差异会较小,因此您可以使用较少的位来表示数字之间的差异。因此,在像[1,2,3,4,2 ^ 30,2 ^ 30 + 1,2 ^ 30 + 2,2 ^ 30 + 3]的数组中,您可以节省一些空间。但是,您将不得不使用更多位来表示新的绝对值。它们再次可以表示为到某个任意绝对值的距离以节省一些空间。但是我不确定你所列出的所有努力是否真的值得在某些情况下节省1比特。

总结一下。如果你有一个类似[2 ^ 30,2 ^ 30 + 1,2 ^ 30 + 2,2 ^ 30 + 3]的数组,你可以通过获取数字之间的差异来显然节省一些空间,但正如你已经在你的答案,在某些情况下会增加数据的大小。因此,您不能使用压缩算法来存储任何(不做假设)数字的数组,使用少于n位,其中n是数组中数字的对数上限的总和。

答案 1 :(得分:1)

  

这项工作的目标是实现数据减少至少1位   大小

对所有输入都不可能。当你真正需要做的就是计算有多少案例时,你可以浪费大量精力来试图正确计算各种表示中的位,犯错误,修复它们等等。

有2 ^ k个可能的输入,其中k是输入中的位数。假设您认为每个输入都有一个k-1位表示。然后有2 ^(k-1)个可能的表示。然后,如果您将这两个2 ^(k-1)表示中的每一个表示提供给解压缩器,您显然只会得到2 ^(k-1)个结果。其他2 ^(k-1)个可能的输入在操作中缺失。无法从您的表示中生成缺少的输入,这意味着实际上您的表示不能涵盖所有可能的2 ^ k输入。至少有一半没有被覆盖。