[二维压缩] | Recursive Range Reduction


一、Recursive Range Reduction

在他们1977年的原始论文A universal algorithm for sequential data compression中,Lempel和Ziv已经证明了他们的字典方法可以将数据压缩到熵,但他们指出,需要大量的数据才能接近理想的压缩。其他算法也存在同样的问题。通常,用户愿意牺牲压缩性能,以方便地实现和知道算法的性能与数据的数量无关。这里描述的递归范围缩减(3R)方法可以生成良好的压缩,易于实现,并且其性能与要压缩的数据量无关。这些特性使它成为嵌入式系统、低成本微控制器和其他空间有限或资源有限的应用程序中压缩的一个有吸引力的候选对象。该方法与可变长码的关系较远。该方法首先被描述为一个已排序的整数列表,其中它的应用程序是最简单的,不需要递归。我们将这一版本命名为“范围减少”(RR)。然后,我们将展示如何将RR扩展到可以应用于任何整数集的递归版本(RRR或3R)。给定一个整数列表,我们首先消除符号位的影响。我们要么旋转每个整数,将符号位移动到最不重要的位置(一个可折叠的位置),要么向所有的整数添加一个偏移量,这样它们就会变成非负数。然后将列表按非递增顺序排序。列表中的第一个元素是最大的一个元素,我们假设它最重要的位是1(也就是说,它在左边没有额外的零)。很明显,跟在第一个元素后面的整数可能有一些最显著的零位,而RR方法的核心是消除大部分这些位,同时留下足够的信息供解码器恢复它们。压缩流中的第一项是长度为最大整数L的头。此长度存储在一个固定大小的字段中,该字段的大小足以满足可能遇到的任何数据。

二、范围递减编码示例及代码实现

1.范围递减编码示例

在这里插入图片描述

在这里的例子中,这个大小是4位,允许多达16位长的整数。一旦解码器输入L,它就知道第一个整数的长度。这个整数的MSB是1,所以这个位可以被消除,第一个整数可以发出为L−1位。下一个整数以l位数的形式写在输出上,从而允许解码器明确地读取它。然后,解码器检查第二个整数中最重要的位。如果最左边的k位是零,那么解码器知道下一个整数(即第三个)没有k个零,因此占据了压缩流中的下一个L−k位。这就是RR压缩非负整数列表的排序方式。

2. 范围递减编码代码实现


class Recursive_Range_Reduction:
    def recursive_range_reduction(self, List):
        List.reverse()
        RRpre = []
        ListMax = List[0]
        # print(List)
        if ListMax > 2 * List[-1]:
            RRproWord = '0' + int2bin(math.ceil(math.log2(ListMax + 1)) - 1,
                                      math.ceil(math.log2(1 + math.log2(ListMax + 1))))
        else:
            RRproWord = '1' + int2bin(math.ceil(math.log2(ListMax + 1)) - 1,
                                      math.ceil(math.log2(1 + math.log2(ListMax + 1))))

        for ListValue in List:
            RRpre.append(int2bin(int(ListValue), math.ceil(math.log2(ListMax + 1))))

        RRafterWords = ''
        for RRpreNum in range(len(RRpre)):
            if RRpreNum == 0:
                RRafterWords += RRpre[RRpreNum][1:]
            else:
                if RRpre[RRpreNum].find('1') == -1:
                    if RRpre[RRpreNum - 1].find('1') == -1:
                        RRafterWords += '0'
                    else:
                        for order in range(math.ceil(math.log2(ListMax)) - RRpre[RRpreNum - 1].find('1')):
                            RRafterWords += '0'
                else:
                    for order in range(RRpre[RRpreNum].find('1') - RRpre[RRpreNum - 1].find('1')):
                        RRafterWords += '0'
                    RRafterWords += RRpre[RRpreNum][RRpre[RRpreNum].find('1'):]
            # print(RRafterWords)
        RRWords = RRproWord + RRafterWords
        return RRWords, len(RRWords)

input :  [0, 0, 4, 6, 7, 20]
output :  ('01000100001111101000000', 23)

总结

以上就是今天要讲的内容,本文仅仅简单介绍了范围递减编码的相关定义和其中简单代码实的实现方法。


参考

[1] Salomon, David, and Giovanni Motta. Handbook of data compression. London; New York: Springer, 2010.

本文部分参考自《Handbook of Data Compression 》,该内容仅供学习研究之用,如若喜欢请支持购买正品书籍。
转载本文请联系原作者获取授权,同时请注明本文来自池鱼醉故渊博客。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
将多维数组转换为二维数组,可以使用PHP中的array_walk_recursive()函数。该函数可以遍历多维数组中的所有元素,并对每个元素应用一个回调函数。在回调函数中,将多维数组的每个元素都添加到一个新的一维数组中,最终得到一个二维数组。 以下是一个示例代码: ``` // 原始多维数组 $multiArray = array( array('id' => 1, 'name' => 'A', 'age' => 20), array('id' => 2, 'name' => 'B', 'age' => 25), array('id' => 3, 'name' => 'C', 'age' => 30) ); // 用于将多维数组转换为一维数组的回调函数 function flattenArray($value, $key, &$result) { $result[] = $value; } // 将多维数组转换为二维数组 $flattenArray = array(); array_walk_recursive($multiArray, 'flattenArray', $flattenArray); $twoDimensionalArray = array_chunk($flattenArray, count($multiArray[0])); // 输出转换后的二维数组 print_r($twoDimensionalArray); ``` 在上面的示例代码中,我们首先定义了一个原始的多维数组$multiArray。然后我们使用array_walk_recursive()函数遍历该多维数组,并将每个元素都添加到$flattenArray数组中。最后,我们使用array_chunk()函数将$flattenArray数组转换为二维数组$twoDimensionalArray。 值得注意的是,在使用array_chunk()函数将一维数组转换为二维数组时,我们使用了count($multiArray[0])作为第二个参数,这是因为原始多维数组中的每个子数组都具有相同的键名,因此我们可以使用任何一个子数组的键名数量作为第二个参数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值