Python - b=2n 和 b!=2n 的 Golomb 编码
Golomb 编码是一种数据压缩技术,用于对具有特定分布的非负整数进行编码。它由 Solomon W. Golomb 于 1966 年推出,并已广泛应用于各种应用,包括视频和图像压缩、信息检索和数据存储。在本文中,我们将探索 Golomb 编码并了解两种情况,即基数是 2 的幂(b=2^n)以及基数不是 2 的幂(b ≠ 2^n)。
b=2^n 的 Golomb 编码(基数是 2 的幂)
当基数是 2 的幂时,Golomb 编码变得相对简单。让我们考虑一个 b = 4 (2^2) 的例子。
当基数是 2 的幂时,查找数字的 Golomb 编码的步骤。
确定商和余数
要对数字 (n) 进行编码,我们首先将其除以 b 并得到商 (q) 和余数 (r)。在我们的示例中,我们假设 n = 12。
n = 12
b = 4
q = n // b # 商 r = n % b # 余数
因此,在我们的示例中:
q = 12 // 4 = 3
r = 12 % 4 = 0
对商进行编码
商 (q) 使用一元编码进行编码,这意味着它由 q 个连续的 1 后跟一个 0 表示。在我们的示例中,q = 3,因此 q 的一元编码为"1110"(三个 1 后跟一个0)。
对余数进行编码
余数 (r) 使用二进制编码进行编码。由于 b = 4,我们需要使用 2 位对 r 进行编码。在我们的例子中,r = 0,可以用二进制表示为"00"。n = 12 和 b = 4 的最终 Golomb 编码是 q 的一元编码和 r 的二进制编码的串联。因此,n = 12 的 Golomb 编码为"111000"。
b ≠ 2^n(底数不是 2 的幂)的 Golomb 编码
当底数不是 2 的幂时,编码过程会变得稍微复杂一些。让我们考虑一个 b = 7 的例子。
当基数不是 2 的幂时,查找数字的哥伦布编码的步骤。
确定商和余数
与前一种情况类似,我们将数字 (n) 除以 b 得到商 (q) 和余数 (r)。假设 n = 23。
n = 23
b = 7
q = n // b # 商 r = n % b # 余数
在我们的示例中:
q = 23 // 7 = 3
r = 23 % 7 = 2
对商进行编码
与上例一样,商 (q) 使用一元编码进行编码。因此,q = 3 将以一元形式表示为 "1110"。
对余数进行编码
余数 (r) 使用 Rice 编码或二进制编码进行编码。 Rice 编码通过将 r 分为前缀和后缀两部分来对其进行编码。
前缀计算
前缀通过计算 k 来确定,k 是满足 2^k ≥ b 的最小整数。在我们的示例中,b = 7,因此 k = 3。我们将范围 (R) 计算为 R = 2^k − b。在本例中,R = 2^3 − 7 = 1。如果 r < R,我们使用 k−1 位的二进制编码对 r 进行编码。否则,我们使用 k 位的二进制编码对 r+R 进行编码。在我们的示例中,r = 2 且 R = 1。由于 r < R,我们使用 k−1 = 2 位的二进制编码对 r = 2 进行编码。因此,r = 2 将用二进制表示为"10"。 n = 23 和 b = 7 的最终 Golomb 编码是 q 的一元编码和编码余数 r 的串联。因此,n = 23 的 Golomb 编码为"111010"。
Golomb 编码实现
我们可以通过创建用于一元编码、二进制编码的函数,使用 Python 实现 Golomb 编码背后的逻辑。Golomb 编码的代码实现如下所示。
示例
在下面的示例中,unary_encoding 函数对给定的商 (q) 执行一元编码。它创建一个由 q 个连续的"1"和"0"组成的字符串,以一元形式表示商。binary_encoding 函数对给定的余数 (r) 和前缀长度 (k) 执行二进制编码。如果 r 小于 2^k 和 r 之间的差,则它使用 k-1 位的二进制对 r 进行编码。否则,它使用具有 k 位的二进制对 r+2^k−r 进行编码。 golomb_encoding 函数对给定的数字 (n) 和基数 (b) 执行 Golomb 编码。它分别通过执行整数除法和模运算来计算商 (q) 和余数 (r)。以下示例涵盖的情况包括:
如果基数 (b) 是 2 的幂(使用 b & (b − 1) == 0 检查),它直接将余数 (r) 转换为二进制并用零填充以匹配 b 的二进制表示的长度。
如果基数 (b) 不是 2 的幂,它通过从 b 的二进制表示的长度中减去 3 来计算前缀长度 (k)。然后,它调用 binary_encoding 函数使用前缀长度 (k) 对余数 (r) 进行编码。
编码的哥伦布数是通过将一元编码商 (q) 和二进制编码余数 (r) 连接起来得到的。
def unary_encoding(q): """ Perform unary encoding for the given quotient (q). """ encoded = "1" * q + "0" return encoded def binary_encoding(r, k): """ Perform binary encoding for the given remainder (r) and prefix length (k). """ if r < 2 ** k - r: encoded = bin(r)[2:].zfill(k - 1) else: encoded = bin(r + 2 ** k - r)[2:].zfill(k) return encoded def golomb_encoding(n, b): """ Perform Golomb encoding for the given number (n) and base (b). """ q = n // b # quotient r = n % b # remainder unary_encoded = unary_encoding(q) if b & (b - 1) == 0: # Check if b is a power of 2 binary_encoded = bin(r)[2:].zfill(len(bin(b)) - 2) else: k = len(bin(b)) - 3 # Prefix length binary_encoded = binary_encoding(r, k) encoded = unary_encoded + binary_encoded return encoded # 示例用法 number = 23 base = 7 encoded_number = golomb_encoding(number, base) print("Golomb Encoding for number", number, "with base", base, ":",coded_number)
输出
Golomb Encoding for number 23 with base 7 : 1110100
结论
在本文中,我们讨论了 Golumb 编码及其相关的两种情况,即 b=2^n 和 b ≠ 2^n 。Golomb 编码是一种有用的数据压缩技术,尤其是对于具有某些模式的非负整数分布。在使用压缩算法、信息检索系统和其他数据密集型应用程序时,了解 Golomb 编码非常有用。