用python完成信源(Huffman)信道(汉明)编解码

本文介绍如何使用Python编程实现Huffman编码和汉明编码,详细阐述了编解码的过程,并提供了相应的代码示例,旨在帮助读者理解这两种重要的数据压缩和错误检测方法。
摘要由CSDN通过智能技术生成
def transmission1(sourceByte):
    t = len(sourceByte) / 1
    print('本信源数据率为8bit/s(1bytes/s),需要传输', t, '秒')
    return t


def transmission2(sourceBit):
    t = len(sourceBit) / 8
    print('本信源数据率为8bit/s(1bytes/s),需要传输', t, '秒')
    return t

#计算信源序列的信息量
def transmission_source(t, sourceByte, prob):
    source = list(sourceByte)
    freq = {
   }
    I = 0
    for item in source:
        freq[item] = freq.get(item, 0) + 1
    for key in prob:
        I += -freq[key] * math.log(prob[key], 2)
    return I, t


# 还原带有时间性质的信道传输并计算信道的数据传输率
def transmission3(len_hamcode):
    a = len_hamcode / 8
    print('需要传输', a, 's, 总数据量为', len_hamcode, 'bit,信道传输的数据率:8 bit/s')
    return a

#信道以一定错误概率输出,不使用信源编码时
def output(some_list,probabilities):
    x = random.uniform(0,1)
    cumulative_probability = 0.0
    new_some_list = []
    Temp_list = []
   
    for i in range(len(some_list)):
        item = some_list[i]#取出的第一个信源进行传输
        Temp_list.append('e')
        Temp_list.append(item)#形成[e,信源i]
        for outcome, outcome_probability in zip(Temp_list, probabilities):
            cumulative_probability += outcome_probability          #若x为0.1~0.299,有0.3的概率传输后是e,若x为0.3~1,则传输后是本身
            if x < cumulative_probability: break
        x = random.uniform(0,1)
        cumulative_probability = 0.0
        new_some_list.append(outcome)
        Temp_list = []
        i += 1
        
    return new_some_list
    '''霍夫曼编解码 '''


# _init_方法定义节点类
class Node:
    def __init__(self, name, weight):
        self.name = name  # 节点名
        self.left = None  # 节点左孩子
        self.right = None  # 节点右孩子
        self.father = None  # 节点的父节点
        self.weight = weight  # 节点权重,即概率

    def is_left(self):  # 判断是否是左孩子:节点的父节点的左孩子是否是节点本身
        return self.father.left == self


# 创建叶子节点,节点名为信源符号,权重为信源符号的概率
def create_nodes(labels, data_set):
    if (len(data_set) != len(labels)):
        raise Exception('数据和标签不匹配!')
    nodes = []
    for i in range(len(labels)):
        nodes.append(Node(labels[i], data_set[i]))
    return nodes


# 创建Huffman树
def create_huffman_tree(nodes):
    queue = nodes[:]  # 复制节点集

    while len(queue) > 1:  # 只剩根节点时退出循环
        queue.sort(key=lambda item: item.weight)  # 按概率值升序排序
        node_left = queue.pop(0)
        node_right = queue.pop(0)  # 取出节点集中最后两个节点,即概率最小的两个,且左孩子权重必然小于等于右孩子
        node_father = Node(None, (node_left.weight + node_right.weight))  # 新节点的权重为两个子节点权重和
        node_father.left = node_left
        node_father.right = node_right  # 新节点的左、右孩子即原来选出的两节点
        node_left.father = node_father
        node_right.father = node_father  # 原来选出的两节点的父节点即新节点
        queue.append(node_father)  # 将新节点加入节点集,循环

    queue[0].father = None  # 根节点没有父节点
    return queue[0]  # 返回根节点


# 建立Huffman编码码书
def get_huffman_code(nodes):
    codes = {
   }

    for node in nodes:  # 遍历节点组合码符号生成码字
        code = ''
        name = node.name
        while node.father != None:  # 到达根节点时跳出循环
            if node.is_left():  # 规定将0分配给左孩子,1分配给右孩子
                code = '0' + code
            else:
                code = '1' + code
            node = node.father
        codes[name] = code
    return codes


# 计算平均码长
def get_averageLength(codes, data_set):
    num = 0
    a = []
    codes_v = list(codes.values())
    for i in range(len(codes_v)):  # 得到每个码字的长度
        length = len(codes_v[i])
        a.append(length)

    all = zip(a, data_set)  # 将两个列表对应的元素组合,形成新列表

    for i, j in all:
        num += i * j
    return round(num, 3)


# 计算信息熵
def informationEntropy(data_set):
    entropy = 0

    for i in range(len(data_set)):
        probility = data_set[i]
        entropy = entropy + probility * math.log2(probility)

    entropy = -entropy

    return entropy


# 编码字符串
def encode_str(text, codes):
    ret = ''
    codes_n=list(codes.items()) #把字典转为列表
    for char in text:
        i = 0
        for item in codes_n:
            if char == item[0]:#item[0]即原字典中的键值,即信源符号
                 ret += codes[char] #codes[char]即信源符号对应的码字
            i
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值