香农编码熵怎么算_香农范诺编码

香农编码熵怎么算_香农范诺编码一、香农编码的概念概念:香农编码是是采用信源符号的累计概率分布函数来分配字码的。香农编码是根据香农第一定理直接得出的,指出了平均码长与信息之间的关系,同时也指出了可以通过编码使平均码长达到极限值。香农第一定理是将原始信源符号转化为新的码符号,使码符号尽量服从等概分布,从而每个码符号所携带的信息量达到最大,进而可以用尽量少的码符号传输信源信息。香农编码属于不等长编码,通常将经常出现的

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

一、香农编码的概念

概念:

香农编码是是采用信源符号的累计概率分布函数来分配字码的。香农编码是根据香农第一定理直接得出的,指出了平均码长与信息之间的关系,同时也指出了可以通过编码使平均码长达到极限值。香农第一定理是将原始信源符号转化为新的码符号,使码符号尽量服从等概分布,从而每个码符号所携带的信息量达到最大,进而可以用尽量少的码符号传输信源信息。

香农编码属于不等长编码,通常将经常出现的消息变成短码,不经常出现的消息编成长码,从而提高通信效率。

二、问题分析

① 由于总是进一取整,香浓编码方法不一定是最佳的。

② 由于第一个消息符号的累加概率总是0,故它对应得分码字总是0、00、000、0……0的式样。

③ 码字集合是唯一的,且为即时码。

④ 先有码长再有码字。

⑤ 对于一些信源,编码效率不高,信源冗余度稍大,因此其实用性受到较大限制。

三、算法实现及流程图

算法基本步骤:

1) 将q个信源符号按概率递减的方式进行排序:P1≥P2≥……Pq。

2) 按式-logP(Si)≤li≤1-logP(Si)(i=1,2,……q),计算出每个信源符号的码长li。  

3) 为编成唯一可译码,计算第i个信源符号的累加概率:。  

4) 将累加概率Gi用二进制表示。  

5) 取Gi对应二进制数的小数点后li位构成该信源符号的二进制码字。

 

四、运行结果

 

五、学习心得

香农编码本质上就是一个信源概率组进行一系列的规则运算后得到的二进制数组。

在用C语言编写的香农编码程序中,对于计算编码时用到的各种概率值要有具体的定义,由于进行香农编码时,首先要进行从大到下的概率排序,所以,程序中编辑的降序的部分是必须的,运行结果不仅要求有编码结果,还要有信源熵,平均码长,所以在程序中也应定义这两个值。通过运用香农编码方法进行计算和对香农编码程序的运行,可知,香农编码方法多余度稍大,相较于其他编码方法实用性不大,但香农编码法有重要的理论意义。

package cn.com;

import java.io.Externalizable;

import java.util.ArrayList;

import java.util.Arrays;

import java.util.Collections;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import java.util.Scanner;

public class Shannon {


/**


* 将概率从大到小排序


* @param p 输入的概率数组


* @return 


*/


public double[] Sort(double[] p){


double[] p1 = new double[p.length];


for(int i = 0; i < p1.length; i++){


p1[i] = p[i];


}


Arrays.sort(p1);


for(int i = 0, j = p.length-1; i < p.length/2; i++, j–){


double temp = p1[i];


p1[i] = p1[j];


p1[j] = temp;


}


return p1;


}





/**


* 验证概率和是否为1,合格为true,否则false


* @param p 输入的概率数组


* @return


*/


public boolean varification(double[] p){


boolean bool = false;


double d = 0;


for(int i = 0; i < p.length; i++){


d+=p[i];


}


if(d – 1.0 < 0.000001){


return true;


}


return bool;


}





/**


* 计算每个信源的码长


* @param p 信源的概率


* @return


*/


public int[] codeLength(double[] p){


int[] Li = new int[p.length];


double temp = 0;


for(int i = 0; i < Li.length; i++){


temp = – (Math.log(p[i]) / Math.log(2.0));


Li[i] = (int)Math.ceil(temp);


}


return Li;


}





/**


* 计算信源的熵


* @param p 信源的概率数组


* @return


*/


public double entropyAll(double[] p){


double H = 0;


for(int i = 0; i < p.length; i++){


H-=(p[i] * (Math.log(p[i]) / Math.log(2.0)));


}





return H;


}





/**


* 计算平均码长


* @param p 信源的概率数组


* @param Li 每个信源的码长数组


* @return


*/


public double averageCodeLength(double[] p, int[] Li){


double n = 0;


for(int i = 0; i < p.length; i++){


n+=p[i] * Li[i];


}





return n;


}





/**


* 计算累加概率


* @param p 信源的概率数组


* @return


*/


public double[] accumulation(double[] p){


double[] q = new double[p.length];


q[0] = 0;





for(int i = 1; i < p.length; i++){


q[i] = q[i-1] + p[i-1];


}


return q;


}





/**


* 计算二进制编码


* @param acl 累加概率数组


* @param cl 每个信源的码长数组


* @return


*/


public int[][] binaryMode(double[] acl, int[] cl){


int[][] c = new int[acl.length][];


for(int i = 0; i < acl.length; i++){


c[i] = new int[cl[i]];


}





double[] a = new double[acl.length+1];


for(int i = 0; i < acl.length; i++){


for(int j = 0; j < cl[i]; j++){


if(j == 0){


a[j] = acl[i] * 2;


}else{


a[j] = a[j-1] * 2;


}


if(a[j] > 1){


c[i][j] = 1;


a[j] = a[j] – 1;


}else{


c[i][j] = 0;


}


}


}





return c;


}








public static void main(String[] args) {


Scanner sc = new Scanner(System.in);


Shannon t = new Shannon();


System.out.println(“输入信源的个数:”);


int num = sc.nextInt();


double[] p = new double[num];


System.out.println(“输入概率:”);


for(int i = 0; i < p.length; i++){


p[i] = sc.nextDouble();


}


if(!t.varification(p)){


System.out.println(“输入的概率有误!”);


return;


}


double[] q = t.Sort(p);





int[] cl = t.codeLength(p);





double[] acl = t.accumulation(p);


int[][] c = t.binaryMode(acl, cl);


System.out.println(“概率              香农编码”);


for(int i = 0; i < p.length; i++){


System.out.print(q[i]+”—>”);


for(int j = 0; j < cl[i]; j++){


System.out.print(c[i][j]);


}


System.out.println();


}


double avg = t.averageCodeLength(p, cl);


double ea = t.entropyAll(p);


System.out.println(“平均码长为:”+avg);


System.out.println(“信源的信息熵为:”+ea);


System.out.println(“编码效率为”+ea/avg);





}

}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/195176.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • java集合超详解

    java集合超详解一、集合大纲1.集合和数组的区别:2.Collection集合的方法:3.常用集合的分类:Collection接口的接口对象的集合(单列集合)├——-List接口:元素按进入先后有序保存,可重复│—————-├LinkedList接口实现类,链表,插入删除,没有同步,线程不安全│—————-├ArrayList接口…

    2022年6月7日
    26
  • ubuntu16.04配置本地镜像源_修改ubuntu镜像源

    ubuntu16.04配置本地镜像源_修改ubuntu镜像源一、Ubuntu版本和代号:Ubuntu可谓是Linux世界中的黑马,其第一个正式版本于2004年10月正式推出。需要详细解释的是Ubuntu版本编号的定义,其编号以“年份的最后一位.发布月份”的格式命名,因此Ubuntu的第一个版本就称为4.10(2004.10)。除了代号之外,每个Ubuntu版本在开发之初还有一个开发代号。Ubuntu开发代号比较有意思,格式为“形容词+动物”,且形容词和动物名称的第一个字母要一致,如Ubuntu16.04的开发代号是XenialXerus,译为“好客的非洲地松鼠

    2022年10月14日
    0
  • TCP/IP协议详解 卷1 Traceroute程序[通俗易懂]

    TCP/IP协议详解 卷1 Traceroute程序[通俗易懂]作用可以让我们看到IP数据报从1台主机传到另一台主机所经过的路由。比Ping程序看到更多东西优势不是所有路由器都支持RR选项。所以有些路由器上会出现不记录IP的现象。Traceroute不需要路由器具备任何特殊的功能RR选项的数据报的目的Ping服务器(主机)会将接受到的RR清单Copy回去。然后再加上回去的IP清单。这样就是X2。这会收到一些限制IP首部的空间有限,不能存放太多的IP…

    2022年6月20日
    25
  • findstr 用法

    findstr 用法http://bathome.l3.wuyou.com/thread-11159-1-6.html/B在一行的开始配对模式。——只在行开头搜索。/E在一行的结尾配对模式。——只在行结尾搜索。/L按字使用搜索字符串。——具体不详,可以与/r参数替换测试。

    2022年10月26日
    0
  • python数组截取

    python数组截取importtensorflowastfimportnumpyasnp#one-dimentiona=np.array([0,1,2,3,4,5,6,7,8,9])print(a)b=a[:4]print(b)c=a[4:]print(c)#multi-dimentiond=np.array([[0,1,2,3,4,5,6,7,8,9],[1,2,3,4…

    2022年4月30日
    46
  • R语言和数据分析十大:购物篮分析

    R语言和数据分析十大:购物篮分析

    2022年1月12日
    42

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号