文章首发于我的个人博客
前言
这篇博客主要总结大二下课程《信息论》实验的内容。主要包含固定模式的算数编码以及自适应模式的算术编码。我将首先介绍这两种算术编码的基本思想和实现思路,然后给出具体的python代码并对代码中的一些关键点进行解释说明。
固定模式的算术编码
问题
设信源可能输出的符号是26个字母,且每个字母出现的概率为:a, b, c, d, e, f 均为0.1,其它是等概的,试编写程序可以对任意字母序列(如presentation)进行固定模式的算术编码,并进行相应的译码。
算法原理
以上图为例说明固定模式算术编码的原理。首先,假设有A、B、C、D四个字符,这四个字符出现的概率分别为0.2、0.2、0.2、0.4,要求对字符序列“ADBCD”进行编码。开始编码时,概率空间为[0,1],当我们首先对A进行编码时,我们的概率空间将会缩小到字符A的区间,即[0,0.2],然后在缩小的区间内根据各个字符的概率重新分配概率空间。依次类推,当进行到最后一个字符时,我们将最后一个字符对应的概率空间作为编码区间,并且在编码区间内选择一个靠近区间上界的概率作为编码概率,利用公式 l i = l o g r 1 p ( s i ) {l_i = log_r}\frac{1}{p(s_i)} li=logrp(si)1
得到**码长。**之后将编码概率转换为与码长等长的二进制序列,即为编码的结果。
译码时,首先将二进制编码序列转换为浮点数,即还原出编码概率。然后顺序遍历编码时存储的字符概率空间改变序列与还原出的编码概率进行比较,选择相应字符概率空间对应的字符即可。这样就可以得到原字符序列。
代码
import math
from decimal import *
def float2bin(x, n):
'''
x : float type
n : bins nums
return : list type
'''
bins = []
while n > 0:
x = x * 2
if x >= 1.0:
bins.append(1)
else:
bins.append(0)
x -= int(x)
n -= 1
# print(bins)
return bins
def bin2float(bins):
'''
bins: list type
return : float type
'''
c = []
f = -1
for i in range(len(bins)):
c.append(f)
f -= 1
num = Decimal(0.0)
for i in range(len(bins)):
num += Decimal(bins[i] * 2**c[i])
# print(num)
return num
def fixed_AC_encode(str, char, char_list):
'''
固定模式算术编码
str: 要进行编码的字符串序列
char:编码字符初始概率空间
char_list: 编码过程中概率空间的变化序列
return : code_length: 编码长度
bins: 编码序列
'''
cha = char.copy()
char_list.append(char.copy()) # 将初始概率空间添加进序列
i = 0
for s in str: # 根据字符序列中字符出现顺序不断更改概率空间
p = Decimal(cha