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

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

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新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);





}

}

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 隐藏任务栏显示

    隐藏任务栏显示ModifyStyleEx(WS_EX_APPWINDOW,WS_EX_APPWINDOW,0)    我用ModifyStyleEx(WS_EX_APPWINDOW,0);隐藏了程序在任务栏的显示.ModifyStyleEx(WS_EX_TOOLWINDOW,WS_EX_APPWINDOW,SWP_NOZORDER);注意最后要改回来void C

  • synchronousqueue场景_谈谈SynchronousQueue

    synchronousqueue场景_谈谈SynchronousQueueSynchronousQueue是一个没有容量的队列,它的put操作和take操作之间是相互依赖的,即put操作必须在take操作准备好时才能将元素“推”过去,反之take操作也必须在put操作准备推元素的时候才能获取到元素。有人可能会说只有1个容量大小的BlockingQueue也能实现该操作,但是它们之间有着本质的不同:1、SynchronousQueue在put时,如果另一个线程没有执行ta…

  • js unit8array和java变量之间的关系

    js unit8array和java变量之间的关系unit8array如何同java进行交互最近一个项目遇到了一个二维码转换的问题,厂家给的demo只有js的转换方式,其中用到了Unit8,由于实际应用场景,转换应该由后端java代码进行实现,这里记录一下实现方式。JS对字符串操作的时候,有时候我们会用到UNIT8ARRAY,例如varbinary_string=window.atob(str);vararray=new…

  • pvzβ版下载_喬二強

    pvzβ版下载_喬二強环境要求HttpRunner是一个基于Python开发的测试框架,可以运行在macOS、Linux、Windows系统平台上。这里使用macOS系统进行演示对于python版本要求:py

  • scp和rsync命令[通俗易懂]

    scp和rsync命令[通俗易懂]SCP命令(1)scp定义scp可以实现服务器与服务器之间的数据拷贝。(fromserver1toserver2)(2)基本语法scp-r$pdir/$fname$user@$host:$pdir/$fname命令递归要拷贝的文件路径/名称目的地用户@主机:目的地路径/名称(3)基本示例scp-rjdk1.8.0_291/root@hadoop103:opt/modulescp-rroot@hadoop102:/opt/module/*root@h

  • hive sql和mysql区别_mysql改表名语句

    hive sql和mysql区别_mysql改表名语句mssql的正式名字是SQLServerMS公司出的。图形操作界面好一些,性能还可以。在在mssql和oracle上不能互换.支持OLEDB连接.asp、mssaql只能forwindow mysql就是mysql下面是readme:免费软件。性能也可以。速度快,用于小规模.命令行界面.(可以装图形操作软件.) sqlserver我以前是做ASP的时候用的 现在学PHP

发表回复

您的电子邮箱地址不会被公开。

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