Visual Studio 2010+C#实现信源和信息熵

2024-02-07 09:52

本文主要是介绍Visual Studio 2010+C#实现信源和信息熵,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. 设计要求

以图形界面的方式设计一套程序,该程序可以实现以下功能:

  1. 从输入框输入单个或多个概率,然后使用者可以通过相关按钮的点击求解相应的对数,自信息以及信息熵
  2. 程序要能够实现马尔可夫信源转移概率矩阵的输入并且可以计算该马尔可夫信源在每一个状态下每输出一个符号的平均信息量,稳态概率以及最后的信息熵。
  3. 结果在在界面中直接呈现

2. 设计过程

首先进行图形界面的设计,根据要求界面中应该包括相关标签,输入,输出以及对应按钮,单行少量输入可以采用普通TextBox控件,多行输入可以采用RichTextBox控件,输出要有对应的标签,为了美观,将输出控件原始标签删除修改为空白,只有输出值才会出现

本实验总体界面设计如图一所示:

图1 设计图形界面

接下来对于点击不同按钮产生的事件进行设计:

由于对数值以及自信息设计过程相对简单,以下着重介绍信息熵以及马尔可夫信源设计过程。

 查看信息熵按钮代码实现:

 private void button5_Click(object sender, EventArgs e){string[] a = new string[richTextBox1.Lines.Length];//定义数组,设定空间大小为输入框的行数double[] px = new double[richTextBox1.Lines.Length];double[] y = new double[richTextBox1.Lines.Length];double z = 0;for (int i = 0; i < richTextBox1.Lines.Length; i++){a[i] = richTextBox1.Lines[i];//获取每一行的值,存入数组a中px[i] = Convert.ToDouble(a[i]);//将字符串转换为可计算的double类型y[i] = Math.Log(1 / px[i], 2);z = z + px[i] * y[i];//计算信息熵}label8.Text = Convert.ToString(Math.Round(z, 2));//结果转换成字符串形式再输出}

在相关按钮中输入上述所示代码即可实现信息熵的计算

在设计马尔可夫信源时,考虑到其概率矩阵更便于观察,所以需要通过输入概率矩阵然后提取相关的概率来进行计算。

要想求信源熵,我们得知道稳态概率值以及在si状态下每输出一个符号的平均信息量,最后对状态取统计平均后得到信源每输出一个符号的信息量,即马尔可夫信源的熵。

对于H(X|si)的值可以直接通过计算得到,求法如下:

 private void button6_Click(object sender, EventArgs e){int a = richTextBox2.Lines.Length;double[,] p = new double[a, a];char[] sp = new char[3] { ' ', '\t', '\n' };string[] str1 = new string[100];str1 = richTextBox2.Text.Split(sp);label10.Text = "";for (int i = 0; i < a; i++){double h = 0;for (int j = 0; j < a; j++){p[i, j] = Convert.ToDouble(str1[i * a + j]);if (p[i, j] == 0){p[i, j] = 1;}h = h + p[i, j] * Math.Log(1 / p[i, j], 2);}label10.Text += Convert.ToString(Math.Round(h, 3)) + '\n';}}

对于稳态概率的值无法直接进行计算得到,因为需要解方程,我对此采用的方法为高斯列选主元消元迭代求解。

首先将概率矩阵进行转置,然后每一行都可以列方程,为使求解更加简便,将方程移项,等式左边为未知数,右边为一个常数,例如初始概率矩阵第一列为0.1 0.5 0 这三个数,转置后可列方程组W1=0.1*W1+0.5*W2+0*W3,移相后为-0.9*W1+0.5*W2+0*W3=0,而在数组中即为[-0.9 0.5 0 0],而对于已知方程概率和W1+W2+W3=1在数组中形式为[1 1 1 1]。

处理后代码如下:

//以下a为处理后的矩阵,b为每一行方程等式右边的常数值double[] b = new double[n];for (int i = 0; i < n; i++){b[i] = a[i, n];//将最后一列(方程右边常数值)存入数组b中}for (int k = 0; k < n - 1; k++){//找每一列主元,最开始我们选k行k列的为最大max = Math.Abs(a[k, k]);//最大元值maxp = k;//最大元列的下标for (int p = k + 1; p < n; p++){if (Math.Abs(a[p, k]) > max){max = Math.Abs(a[p, k]);maxp = p;}}if (maxp != k){//需要交换两行double[] tmp = new double[n];for (int i = 0; i < n; i++){tmp[i] = a[maxp, i];a[maxp, i] = a[k, i];a[k, i] = tmp[i];}double tmpp;tmpp = b[k];b[k] = b[maxp];b[maxp] = tmpp;}for (int i = k + 1; i < n; i++){for (int j = k + 1; j < n; j++){a[i, j] -= a[k, j] * a[i, k] / a[k, k];}b[i] -= b[k] * a[i, k] / a[k, k];}}x[n - 1] = b[n - 1] / a[n - 1, n - 1];for (int k = n - 2; k > -1; k--){double sum1 = 0;for (int j = k + 1; j < n; j++){sum1 += a[k, j] * x[j];}x[k] = b[k] - sum1;x[k] /= a[k, k];}//x即为方程的解

至此,求解信源熵的两大关键部分都已经实现,最后直接计算即可完成。

四、实验测试

图2 总体测试

从图2中可以看出:

在输入姓名后点击登录按钮将会显示欢迎,在输入概率后可以点击按钮查看它的对数或者自信息量,也可以输入多个概率并且求取信息熵,这些通过验证,结果均为正确。对于马尔可夫信源的测试,我使用的是课本上例

图3 例子

将图2中所求结果与图3中结果对比后可以看出结果正确,可以与例题中的结果一一对应上

改变数据继续验证:

图4

图5

通过图4,图5的多次验证,可以保证其与手动计算结果基本保持一致,误差可以忽略不计,实验成功。

3. 总结

按照模块分别进行设计难度不大,但是在最后实现马尔可夫信源时需要使用C#对矩阵进行处理以及运算,需要大家掌握一定的数学知识,本文的思想就是利用求解线性方程的相关算法以及高斯迭代求解方程的方法去实现。完整项目后续会上传至资源中

这篇关于Visual Studio 2010+C#实现信源和信息熵的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/687338

相关文章

分布式锁在Spring Boot应用中的实现过程

《分布式锁在SpringBoot应用中的实现过程》文章介绍在SpringBoot中通过自定义Lock注解、LockAspect切面和RedisLockUtils工具类实现分布式锁,确保多实例并发操作... 目录Lock注解LockASPect切面RedisLockUtils工具类总结在现代微服务架构中,分布

Java使用Thumbnailator库实现图片处理与压缩功能

《Java使用Thumbnailator库实现图片处理与压缩功能》Thumbnailator是高性能Java图像处理库,支持缩放、旋转、水印添加、裁剪及格式转换,提供易用API和性能优化,适合Web应... 目录1. 图片处理库Thumbnailator介绍2. 基本和指定大小图片缩放功能2.1 图片缩放的

Python使用Tenacity一行代码实现自动重试详解

《Python使用Tenacity一行代码实现自动重试详解》tenacity是一个专为Python设计的通用重试库,它的核心理念就是用简单、清晰的方式,为任何可能失败的操作添加重试能力,下面我们就来看... 目录一切始于一个简单的 API 调用Tenacity 入门:一行代码实现优雅重试精细控制:让重试按我

Redis客户端连接机制的实现方案

《Redis客户端连接机制的实现方案》本文主要介绍了Redis客户端连接机制的实现方案,包括事件驱动模型、非阻塞I/O处理、连接池应用及配置优化,具有一定的参考价值,感兴趣的可以了解一下... 目录1. Redis连接模型概述2. 连接建立过程详解2.1 连php接初始化流程2.2 关键配置参数3. 最大连

Python实现网格交易策略的过程

《Python实现网格交易策略的过程》本文讲解Python网格交易策略,利用ccxt获取加密货币数据及backtrader回测,通过设定网格节点,低买高卖获利,适合震荡行情,下面跟我一起看看我们的第一... 网格交易是一种经典的量化交易策略,其核心思想是在价格上下预设多个“网格”,当价格触发特定网格时执行买

python设置环境变量路径实现过程

《python设置环境变量路径实现过程》本文介绍设置Python路径的多种方法:临时设置(Windows用`set`,Linux/macOS用`export`)、永久设置(系统属性或shell配置文件... 目录设置python路径的方法临时设置环境变量(适用于当前会话)永久设置环境变量(Windows系统

Python对接支付宝支付之使用AliPay实现的详细操作指南

《Python对接支付宝支付之使用AliPay实现的详细操作指南》支付宝没有提供PythonSDK,但是强大的github就有提供python-alipay-sdk,封装里很多复杂操作,使用这个我们就... 目录一、引言二、准备工作2.1 支付宝开放平台入驻与应用创建2.2 密钥生成与配置2.3 安装ali

Spring Security 单点登录与自动登录机制的实现原理

《SpringSecurity单点登录与自动登录机制的实现原理》本文探讨SpringSecurity实现单点登录(SSO)与自动登录机制,涵盖JWT跨系统认证、RememberMe持久化Token... 目录一、核心概念解析1.1 单点登录(SSO)1.2 自动登录(Remember Me)二、代码分析三、

C#中lock关键字的使用小结

《C#中lock关键字的使用小结》在C#中,lock关键字用于确保当一个线程位于给定实例的代码块中时,其他线程无法访问同一实例的该代码块,下面就来介绍一下lock关键字的使用... 目录使用方式工作原理注意事项示例代码为什么不能lock值类型在C#中,lock关键字用于确保当一个线程位于给定实例的代码块中时

C# $字符串插值的使用

《C#$字符串插值的使用》本文介绍了C#中的字符串插值功能,详细介绍了使用$符号的实现方式,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧... 目录$ 字符使用方式创建内插字符串包含不同的数据类型控制内插表达式的格式控制内插表达式的对齐方式内插表达式中使用转义序列内插表达式中使用