香农编码,费诺编码,赫夫曼编码(python实现)

开始参考了网上其他人的代码,但后来都发现要么代码有错误,要么输出结果不符合自己的预期,于是就重新实现了一下,代码仍存在一些小问题,但是能够满足作业要求,重要的是看懂思路,然后按照自己的想法去实现

代码存在的问题:

  1. 香农编码和费诺编码起始的符号及其概率都已给出并且做了初步处理,有想法的可以改成用户自定义输入
  2. 费诺编码的实现借助了字典和递归,但是如果初始输入的概率集中存在相同的key(也就是概率集中存在相同概率),那么字典update()方法的覆盖特性会使两个相同概率对应的码字合并(因为事情比较多,就没有改代码,有带佬知道怎么解决的话求帮助)
  3. 赫夫曼编码借鉴了别人的代码,初始数据是用户自定义输入的

香农编码

Code:

import mathp = [0.4, 0.3, 0.2, 0.1]        # 信源符号概率递减排列
p_next = [0, 0.4, 0.7, 0.9]     # 概率累加和
k = []          # 对应码长
length_k = 0    # 平均码长
H = 0           # 信源熵def code_length():for i in range(len(p)):k.append(int(math.log(p[i], 2) * (-1) + 0.99))print('码长:{}'.format(k))def average_length():global  length_kfor i in range(len(p)):length_k += k[i] * p[i]# print(round(length_k, 1))print("平均码长为:{:.3}(bit/sign)".format(length_k))# 将十进制小数转为二进制小数
def int_to_bin(px):b = []while True:px *= 2b.append(1 if px>=1 else 0)px -= int(px)if px == 0:for i in range(len(p)):if len(b) != k[i]:b.append('0'*(k[i]-len(b)))breakreturn bdef codeword():code = []  # 对应码字for i in range(len(p)):e = ''for j in range(k[i]):e += str(int_to_bin(p_next[i])[j])code.append(e)print('码字:{}'.format(code))def Hx():global Hfor i in range(len(p)):H += p[i] * math.log(p[i], 2) * (-1)# print(round(H, 2))print('信源熵:{:.3}(bit/sign)'.format(H))def efficiency():print('编码效率:{:.2%}'.format(H/length_k))if __name__ == '__main__':print(p)code_length()       # 求对应码长average_length()    # 求平均码长Hx()                # 求信源熵codeword()          # 求码字efficiency()        # 求编码效率

Result:

费诺编码

Code:

import mathp = [0.4, 0.3, 0.2, 0.1]      # 信源符号概率递减排列
k = []          # 码长
length_k = 0    # 平均码长
code = {}       # 符号及其对应的码字集合
list_code = []
H = 0           # 信源熵
# 编码空间
encode_dictionary = {}def code_length():for p in list_code:k.append(len(code[p]))print('码长:{}'.format(k))def average_length():global length_kfor p in list_code:length_k += len(code[p]) * pprint("平均码长为:{:.3}比特/符号".format(length_k))def codeword(px, encode_dictionary):if len(px) == 1:return 1# 最佳分组位置flag = 1find_position = 1for i in range(len(px)):sum1 = 0sum2 = 0for i in range(i+1):sum1 += px[i]for j in range(i+1,len(px)):sum2 += px[j]difference = abs(sum1 - sum2)if difference < flag:flag = differencefind_position = i+1# 编码for i in range(len(px)):if i < find_position:element = {px[i] : encode_dictionary[px[i]] + '0'}encode_dictionary.update(element)else:element = {px[i] : encode_dictionary[px[i]] + '1'}encode_dictionary.update(element)# 编码分组leftgroup = []rightgroup = []for i in range(find_position):leftgroup.append(px[i])for i in range(find_position, len(px)):rightgroup.append((px[i]))# 递归编码codeword(leftgroup, encode_dictionary)codeword(rightgroup, encode_dictionary)# 返回编码空间return encode_dictionarydef Hx():global Hfor i in range(len(p)):H += p[i] * math.log(p[i], 2) * (-1)# print(round(H, 2))print('信源熵:{:.3}(bit/sign)'.format(H))def efficiency():print('编码效率:{:.2%}'.format(H/length_k))if __name__ == '__main__':# 初始化编码空间for i in range(len(p)):element = {p[i]: ""}encode_dictionary.update(element)print(p)# 求码字code = codeword(p, encode_dictionary)list_code = list(code)code_length()  # 求码长average_length()  # 平均码长Hx()  # 求信源熵for p in list_code:print('对应码字:{}'.format(code[p]))efficiency()        # 求编码效率

Result:

赫夫曼编码

Code:

import math# 码长
def code_length():list_code = list(code)for i in range(len(list_code)):k.append(len(code[s[i]]))print('码长:{}'.format(k))def Hx():global Hfor i in range(len(s)):H += w[i] * math.log(w[i], 2) * (-1)# print(round(H, 2))print('信源熵:{:.3}(bit/sign)'.format(H))# 平均码长
def huffmanCode(root, tree, rootCode='', codeDict={}, depth=1, res=0):# 对左子树进行处理:如果是叶子节点,就打印编码;否则递归if len(root['left'][0]) == 1:codeDict[root['left'][0]] = '0' + rootCoderes += (len(rootCode) + 1) * root['left'][1]  # 计算平均位数else:codeDict, res = huffmanCode(tree[root['left'][0]], tree, '0' + rootCode, codeDict, depth + 1, res)# 对右子树进行处理:如果是叶子节点,就打印编码;否则递归if len(root['right'][0]) == 1:codeDict[root['right'][0]] = '1' + rootCoderes += (len(rootCode) + 1) * root['right'][1]  # 计算平均位数else:codeDict, res = huffmanCode(tree[root['right'][0]], tree, '1' + rootCode, codeDict, depth + 1, res)return codeDict, ress = eval(input('若干字符:'))
w = eval(input('对应概率:'))# 合并成一个字典
arr = [[s[i], w[i]] for i in range(len(s))]tree = {}
while len(arr) > 1:# 1 根据权重排序arr.sort(key=lambda x: x[1])# 2 选出最小的两个节点,分别作为左子树,右子树l = arr[0]  # 较小的作为左子树r = arr[1]  # 较大者作为右子树if len(arr) > 2:tree[l[0] + r[0]] = {'left': l, 'right': r}# 3 用新节点置换这两个节点arr = arr[2:]arr.append([l[0] + r[0], l[1] + r[1]])else:tree['root'] = {'left': l, 'right': r}breakcode, res = huffmanCode(tree['root'], tree)
# 码长k
k = []
H = 0
code_length()
print('平均码长:{:.3}'.format(res/sum(w)))
Hx()
# 码字m
m = []
for i in range(len(s)):x = str(code[s[i]].replace('1','2'))y = x.replace('0','1')z = y.replace('2','0')n = list(z)n.reverse()m.append(''.join(n))
print('码字:{}'.format(m))
print('编码效率:{:.2%}'.format(H / round(res/sum(w),3)))# 'a','b','c','d'
# 0.4,0.3,0.2,0.1

Result:

总结

由上可得,相同的数据,使用不同的编码,效率也不相同
编码效率:赫夫曼编码 >= 费诺编码 > 香农编码

上面费诺编码和赫夫曼编码的编码效率不都是97.18%吗?
为什么赫夫曼编码的编码效率不是应该等于费诺编码的编码效率吗?
我觉得这个应该是特殊情况

信息论与编码-python实现三种编码(香农编码,费诺编码,赫夫曼编码)相关推荐

  1. 香农费诺编码 c语言实现,信息论课程设计(香农、费诺编码)

    <信息论课程设计(香农.费诺编码)>由会员分享,可在线阅读,更多相关<信息论课程设计(香农.费诺编码)(34页珍藏版)>请在人人文库网上搜索. 1.华北科技学院信息论基础课程设 ...

  2. 费诺编码 c++代码实现 信息论实验

    费诺编码 1.实验目的 (1)进一步熟悉费诺编码过程: (2)掌握Matlab 或C语言递归程序的设计和调试技术 2.实验要求 (1)输入:信源符号个数 ,每个信源符号的概率分布P从键盘输入 (2)输 ...

  3. 用MATLAB实现费诺编码

    一.简述 <信息论与编码>是一门理论与实践密切结合的课程,课程设计是其实践性教学环节之一,同时也是对课堂所学理论知识的巩固和补充.其主要目的是加深对理论知识的理解,掌握查阅有关资料的技能, ...

  4. MATLAB实现费诺编码的计算与分析

    一.实验目的 1.理解霍费诺编码的原理. 2.掌握费诺编码的方法和步骤. 3.熟悉费诺编码的效率. 4.本实验用Matlab语言编程实现费诺(Fano)编码. 二.实验环境 windows XP,MA ...

  5. 费诺码设计matlab,费诺编码的matlab实现.doc

    费诺编码的matlab实现.doc 多媒体技术实验报告学院:城南学院 姓名:学号:指导老师:尹波时间:2015年11月25日 教师评语:成绩 评阅教师 日期 实验一:费诺编码的matlab实现1实验目 ...

  6. 信息论与编码 python实现 费诺编码 代码详解

    先给出整体代码 要copy的朋友可以拿去 下面给出 from math import * class FanoCod: #费诺编码code_dict = {}x_p = {}x_plist = []A ...

  7. 基于Python实现的费诺编码

    目录 基于Python实现的费诺编码 (一)费诺编码原理及过程 1.原理 2.过程 Talk is cheap. Show me the code. 测试结果 前言:学习信息论与编码时想实现费诺编码, ...

  8. 费诺编码实验报告c语言,信息论编码实验报告费诺编码附源代码..doc

    信息论编码实验报告费诺编码附源代码. 中南大学 信息论与编码实验报告 选 题: 费诺编码 学生姓名: 学 号: 专业班级: 通信工程 指导老师: 学 院: 信息科学与工程学院 时 间: 2015 目录 ...

  9. java实现.费诺编码_信息论编码实验报告费诺编码附源代码

    信息论编码实验报告费诺编码附源代码 中南大学信息论与编码实验报告选 题: 费诺编码 学生姓名: 学 号: 专业班级: 通信工程 指导老师: 学 院: 信息科学与工程学院 时 间: 2015 目录1.实 ...

最新文章

  1. 基于熵权法优劣解距离法_维普资讯中文期刊服务平台-基于改进TOPSIS方法的航空装备预研项目技术风险评估...
  2. 《云计算:原理与范式》一3.9 SaaS集成服务
  3. c#中使用消息循环机制发送接收字符串的方法和数据类型转换
  4. 制作两个字符串字谜的最小步骤数
  5. 定时跑视图往另外一张表添加数据_程序猿删库跑路示例
  6. boot lvm 分区_LVM磁盘逻辑卷管理
  7. 如何为回归问题,选择最合适的机器学习方法?
  8. SSH关于公钥认证Permission denied的问题
  9. ThinkPHP3.2.3 的异常和错误屏蔽处理
  10. NLP学习一 形式语言与自动机
  11. mysql取消安全模式
  12. 计算机图形学-二维图形的裁剪
  13. JavaScript前端数据呈现——Table会拐弯的column,数据分多列展示
  14. iphone15尺寸大小 苹果15参数配置
  15. 在线演绎3D图表如何操作
  16. iphone7刷入linux,iPhone7怎么进入DFU模式 iPhone7刷机步骤【详解】
  17. VisualSFM的配置与使用 MeshLab的网格生成与纹理添加
  18. 知识百科:针式打印机打印头是核心技术
  19. 泊松噪声(附Matlab代码)
  20. C51中的INTRINS.H:内部函数

热门文章

  1. 单链表的头插法与尾插法详解
  2. linux下rsync命令,linux上的rsync命令详解
  3. oracle 建索引 00054,ora-00054 表被lock导致资源忙等待不能操作案例
  4. 百度网盘限速的解决办法
  5. 反汇编入门试手 简单程序
  6. ddr3写操作app_wdf_end说明
  7. 回归预测 | MATLAB实现MPR多元多项式回归
  8. 软件工程c语言2000行代码,C语言教务管理系统(2000行代码)
  9. 【VUE】【高德地图】如何隐藏(去除)高德地图api左下角logo
  10. linux常用指令词典