分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

香农-范诺算法(Shannon-Fano coding)原理

和Huffman-Tree一样,Shannon-Fano coding也是用一棵二叉树对字符进行编码。但在实际操作中呢,Shannon-Fano却没有大用处,这是由于它与Huffman coding相比,编码效率较低的结果(或者说香农-范诺算法的编码平均码字较大)。但是它的基本思路我们还是可以参考下的。

根据Wikipedia上面的解释,我们来看下香农范诺算法的原理:

Shannon-Fano的树是根据旨在定义一个有效的代码表的规范而建立的。实际的算法很简单:

  1. 对于一个给定的符号列表,制定了概率相应的列表或频率计数,使每个符号的相对发生频率是已知。
  2. 排序根据频率的符号列表,最常出现的符号在左边,最少出现的符号在右边。
  3. 清单分为两部分,使左边部分的总频率和尽可能接近右边部分的总频率和。
  4. 该列表的左半边分配二进制数字0,右半边是分配的数字1。这意味着,在第一半符号代都是将所有从0开始,第二半的代码都从1开始。
  5. 对左、右半部分递归应用步骤3和4,细分群体,并添加位的代码,直到每个符号已成为一个相应的代码树的叶。

示例

香农-范诺编码算法

这个例子展示了一组字母的香浓编码结构(如图a所示)这五个可被编码的字母有如下出现次数:

Symbol A B C D E
Count 15 7 6 6 5
Probabilities 0.38461538 0.17948718 0.15384615 0.15384615 0.12820513

从左到右,所有的符号以它们出现的次数划分。在字母B与C之间划定分割线,得到了左右两组,总次数分别为22,17。 这样就把两组的差别降到最小。通过这样的分割, A与B同时拥有了一个以0为开头的码字, C,D,E的码子则为1,如图b所示。 随后, 在树的左半边,于A,B间建立新的分割线,这样A就成为了码字为00的叶子节点,B的码子01。经过四次分割, 得到了一个树形编码。 如下表所示,在最终得到的树中, 拥有最大频率的符号被两位编码, 其他两个频率较低的符号被三位编码。

符号 A B C D E
编码 00 01 10 110 111

Entropy(熵,平均码字长度): 

Pseudo-code

 1:  begin 2:     count source units 3:     sort source units to non-decreasing order 4:     SF-SplitS 5:     output(count of symbols, encoded tree, symbols) 6:     write output 7:   end 8:   9:  procedure SF-Split(S)10:  begin11:     if (|S|>1) then12:      begin13:        divide S to S1 and S2 with about same count of units14:        add 1 to codes in S115:        add 0 to codes in S216:        SF-Split(S1)17:        SF-Split(S2)18:      end19:  end

想不清楚的朋友可以看下这个网站的模拟程序,很形象,perfect~

香农-范诺算法实现(Shannon-Fano coding implementation in C++)

我们由上面的算法可知,需要迭代地寻找一个最优点,使得树中每个节点的左右子树频率总和尽可能相近。
这里我寻找最优化点用的是顺次查找法,其实呢,我们还可以用二分法(dichotomy)达到更高的效率~
/************************************************************************//* File Name: Shanno-Fano.cpp*  @Function: Lossless Compression@Author: Sophia Zhang@Create Time: 2012-9-26 20:20@Last Modify: 2012-9-26 20:57*//************************************************************************/#include"iostream"#include "queue"#include "map"#include "string"#include "iterator"#include "vector"#include "algorithm"#include "math.h"using namespace std;#define NChar 8 //suppose use 8 bits to describe all symbols#define Nsymbols 1<<NChar //can describe 256 symbols totally (include a-z, A-Z)#define INF 1<<31-1typedef vector<bool> SF_Code;//8 bit code of one charmap<char,SF_Code> SF_Dic; //huffman coding dictionaryint Sumvec[Nsymbols]; //record the sum of symbol count after sortingclass HTree{public : HTree* left; HTree* right; char ch; int weight; HTree(){left = right = NULL; weight=0;ch ='\0';} HTree(HTree* l,HTree* r,int w,char c){left = l; right = r; weight=w; ch=c;} ~HTree(){delete left; delete right;} bool Isleaf(){return !left && !right; }};bool comp(const HTree* t1, const HTree* t2)//function for sorting{ return (*t1).weight>(*t2).weight; }typedef vector<HTree*> TreeVector;TreeVector TreeArr;//record the symbol count array after sortingvoid Optimize_Tree(int a,int b,HTree& root)//find optimal separate point and optimize tree recursively{ if(a==b)//build one leaf node {  root = *TreeArr[a-1];  return; } else if(b-a==1)//build 2 leaf node {  root.left = TreeArr[a-1];  root.right=TreeArr[b-1];  return; } //find optimizing point x int x,minn=INF,curdiff; for(int i=a;i<b;i++)//find the point that minimize the difference between left and right; this can also be implemented by dichotomy {  curdiff = Sumvec[i]*2-Sumvec[a-1]-Sumvec[b];  if(abs(curdiff)<minn){   x=i;   minn = abs(curdiff);  }  else break;//because this algorithm has monotonicity } HTree*lc = new HTree; HTree *rc = new HTree; root.left = lc;  root.right = rc; Optimize_Tree(a,x,*lc); Optimize_Tree(x+1,b,*rc);}HTree* BuildTree(int* freqency)//create the tree use Optimize_Tree{ int i; for(i=0;i<Nsymbols;i++)//statistic {  if(freqency[i])   TreeArr.push_back(new HTree (NULL,NULL,freqency[i], (char)i)); } sort(TreeArr.begin(), TreeArr.end(), comp); memset(Sumvec,0,sizeof(Sumvec)); for(i=1;i<=TreeArr.size();i++)  Sumvec[i] = Sumvec[i-1]+TreeArr[i-1]->weight; HTree* root = new HTree; Optimize_Tree(1,TreeArr.size(),*root); return root;}/************************************************************************//* Give Shanno Coding to the Shanno Tree/*PS: actually, this generative process is same as Huffman coding/************************************************************************/void Generate_Coding(HTree* root, SF_Code& curcode){ if(root->Isleaf()) {  SF_Dic[root->ch] = curcode;  return; } SF_Code lcode = curcode; SF_Code rcode = curcode; lcode.push_back(false); rcode.push_back(true); Generate_Coding(root->left,lcode); Generate_Coding(root->right,rcode);}int main(){ int freq[Nsymbols] = {0}; char *str = "bbbbbbbccccccaaaaaaaaaaaaaaaeeeeedddddd";//15a,7b,6c,6d,5e //statistic character frequency while (*str!='\0')  freq[*str++]++; //build tree HTree* r = BuildTree(freq); SF_Code nullcode; Generate_Coding(r,nullcode); for(map<char,SF_Code>::iterator it = SF_Dic.begin(); it != SF_Dic.end(); it++) {    cout<<(*it).first<<'\t';    std::copy(it->second.begin(),it->second.end(),std::ostream_iterator<bool>(cout));    cout<<endl;   }  }

Result:

以上面图中的统计数据为例,进行编码。

符号 A B C D E
计数 15 7 6 6 5

Reference:

  1. Shannon-Fano coding. Wikipedia, the free encyclopedia
  2. Claude Elwood Shannon. Wikipedia, the free encyclopedia.
  3. C. E. Shannon: A Mathematical Theory of Communication. The Bell System Technical Journal, Vol. 27, July, October, 1948.
  4. C. E. Shannon: Prediction and Entropy of Printed English. The Bell System Technical Journal, Vol. 30, 1951.
  5. C. E. Shannon: Communication Theory of Secrecy Systems. The Bell System Technical Journal, Vol. 28, 1949.
  6. http://www.stringology.org/DataCompression/sf/index_en.html
关于Compression更多的学习资料将继续更新,敬请关注本博客和新浪微博Sophia_qing。

给我老师的人工智能教程打call!http://blog.csdn.net/jiangjunshow

Shannon-Fano编码——原理与实现相关推荐

  1. 香农-范诺编码(Shannon–Fano Coding)

    香农-范诺编码 香农-范诺编码 简介 算法 示例 香农-范诺编码 简介 香农-范诺编码(Shannon–Fano Coding)是一种基于一组符号集及其出现的或然率(估量或测量所得),从而构建前缀码的 ...

  2. 建议收藏 | H.265编码原理入门

    视频编码的目的是为了压缩原始视频,压缩的主要思路是从空间.时间.编码.视觉等几个主要角度去除冗余信息.由于 H.264 出色的数据压缩比率和视频质量,成为当前市场上最为流行的编解码标准.而 H.265 ...

  3. 【Android 内存优化】Android 原生 API 图片压缩原理 ( 哈夫曼编码开关 | 哈夫曼编码原理 | libjpeg-turbo 函数库 )

    文章目录 一. 哈夫曼编码开关 二. 哈夫曼编码原理 三. libjpeg-turbo 函数库 四. libjpeg-turbo 函数库下载 [Android 内存优化]图片文件压缩 ( Androi ...

  4. base64编码_几分钟看懂Base64编码原理

    Base64简介 Base64是基于64个可打印字符(小写字母a-z,大写字母A-Z,数字0-9,符号"+","/" 再加上作为垫字的"=" ...

  5. 【RS码1】系统RS码编码原理及MATLAB实现(不使用MATLAB库函数)

    关注公号[逆向通信猿]更精彩!!! 基础知识 要想搞懂本节知识,需要先熟悉掌握以下前几篇博客 [多元域乘法]多项式乘法电路原理及MATLAB详解 [多元域除法]多项式除法电路原理及MATLAB详解 R ...

  6. 【BCH码1】系统BCH码编码原理及MATLAB实现(不使用MATLAB库函数)

    关注公号[逆向通信猿]更精彩!!! BCH编码原理 设一个 ( n , k ) (n,k) (n,k)循环码的生成多项式为 g

  7. 信息论 哈夫曼编码 与 菲诺编码的实现(对一幅BMP格式的灰度图像(个人 证件照片)进行二元霍夫曼编码和译码。并进行编码效率的计算,对一幅BMP格式的灰度图像进行二 元Fano编码、译码 )

    信息论 哈夫曼编码 与 菲诺编码的实现(对一幅BMP格式的灰度图像(个人 证件照片)进行二元霍夫曼编码和译码.并进行编码效率的计算,对一幅BMP格式的灰度图像进行二 元Fano编码.译码 ) 原始图片 ...

  8. 详解varint编码原理

    什么是Varint编码 Varint是一种使用一个或多个字节序列化整数的方法,会把整数编码为变长字节.对于32位整型数据经过Varint编码后需要1~5个字节,小的数字使用1个byte,大的数字使用5 ...

  9. 哈夫曼编码原理与Python实现代码(附手动推导过程原稿真迹)

    哈夫曼编码依据字符出现概率来构造异字头(任何一个字符的编码都不是其他字符的前缀)的平均长度最短的码字,通过构造二叉树来实现,出现频次越多的字符编码越短,出现频次越少的字符编码越长.为了演示哈夫曼编码原 ...

  10. 字符编码原理 ASCII,Unicode和UTF-8 - - ITeye技术网站

    字符编码原理 ASCII,Unicode和UTF-8 - - ITeye技术网站 字符编码原理 ASCII,Unicode和UTF-8 博客分类:coder加密与解密 编码utf-8unicode原理 ...

最新文章

  1. You Don't Know JS: Scope Closures(翻译)
  2. Istio:一个用于微服务间通信的服务网格开源项目
  3. 吴恩达《Machine Learning》精炼笔记 2:梯度下降与正规方程
  4. Thinkphp5.0快速入门笔记(3)
  5. 2018-2019-2 20175235 实验四《Android开发基础》实验报告
  6. 基于Apache OLTU的OAuth2.0授权解决方案
  7. Nginx反向代理Redis服务
  8. Qt程序缺少dll解决方案
  9. 收藏:如何实现路由器的本地验证和授权
  10. 百元性价比高的蓝牙耳机推荐:学生党适合使用的蓝牙耳机
  11. java技术管理的简历_基于javaweb个人简历生成及管理系统.doc
  12. 判断链表是否中心对称(21.6.8)
  13. 把失败看成常态 把成功当作偶然”——与庞加莱猜想“封顶”者之一、中山大学教授朱熹平面对面
  14. 数据驱动的互联网营销和运营专用名词速览
  15. LWN:让内核支持符合FIPS规范的随机数!
  16. error C2039: ‘tr1‘: is not a member of ‘std‘
  17. 腾讯区块链强势出击,公链的机会在哪里?
  18. 每日优鲜完成新一轮4.5亿美元融资,自有品牌商品占比j将提升至50%
  19. Android计算器心得体会,计算器编程设计心得体会
  20. 如何在Unity中使用WebXR开发AR/VR应用

热门文章

  1. 几何公差基础知识之圆柱度
  2. 163邮箱格式 ,个人邮箱的正确格式
  3. envi5.6处理gf3(SAR)详细过程记录
  4. 如何使用计算机计算平方面积,平方怎么算面积公式-3种方法详解须知
  5. Git分支模型(master/hotfix/develop/feature/release)
  6. linux系统网络老掉线,Linux使用ADSL上网时经常掉线
  7. 虫虫吃第一颗豆子---第一次作业
  8. 经典回味:ResNet到底在解决一个什么问题呢?
  9. ADSL拨号代理服务器实现HTTP代理的搭建过程
  10. 客户关系管理之会员管理