信息论实验-二元对称信道仿真(C++实现)
来源:互联网 发布:网络直播摄像头哪种好 编辑:程序博客网 时间:2024/06/06 23:16
二元对称信道模拟器
实验目的
加深理解二进制对称信道的工作原理,掌握通过高级编程语言生成伪随机数的方法。允许使用编程语言:C,C++等
实验要求
输入:BSC信道的错误概率,任意的二进制序列
输出:经BSC信道传输后的二进制序列
实验内容
二元对称信道定义
2元对称信道信道的转移概率为
如下图所示
对于二元对称信道DMC,其信道容量为
C、C++产生伪随机数原理
C++中常用rand()函数生成随机数,但严格意义上来讲生成的只是伪随机数(pseudo-random integral number)。生成随机数时需要我们指定一个种子,如果在程序内循环,那么下一次生成随机数时调用上一次的结果作为种子。但如果分两次执行程序,那么由于种子相同,生成的“随机数”也是相同的。在工程应用时,我们一般将系统当前时间(Unix时间)作为种子,这样生成的随机数更接近于实际意义上的随机数。
rand函数不是真正的随机数生成器,而srand()会设置供rand()使用的随机数种子。如果你在第一次调用rand()之前没有调用srand(),那么系统会为你自动调用srand()。而使用同种子相同的数调用 rand()会导致相同的随机数序列被生成。
srand((unsigned)time(NULL))则使用系统定时/计数器的值作为随机种子。每个种子对应一组根据算法预先生成的随机数,所以,在相同的平台环境下,不同时间产生的随机数会是不同的,相应的,若将srand(unsigned)time(NULL)改为srand(TP)(TP为任一常量),则无论何时运行、运行多少次得到的“随机数”都会是一组固定的序列,因此srand生成的随机数是伪随机数。
标准库中的两个用于产生随机数的函数srand()和rand().
函数原型:int rand(void)返回值:返回一个[0, RAND_MAX]间的随机整数函数原型:void srand(unsigned seed)输入参数:seed是rand()的种子,用来初始化rand()的起始值。
系统在调用rand()之前都会自动调用srand(),如果用户在rand()之前曾调用过srand()给参数seed指定了一个值,那么 rand()就会将seed的值作为产生伪随机数的初始值;而如果用户在rand()前没有调用过srand(),那么系统默认将1作为伪随机数的初始 值。如果给了一个定值,那么每次rand()产生的随机数序列都是一样的
所以为了避免上述情况的发生我们通常用srand((unsigned)time(0))或者srand((unsigned)time(NULL))来 产生种子。如果仍然觉得时间间隔太小,可以在(unsigned)time(0)或者(unsigned)time(NULL)后面乘上某个合适的整数。
二元对称信道的仿真实现
程序主函数
int main(){ print(); float P_error; //错误概率 Info *root = new Info; cout << "!------请输入二元信道的错误概率:-----!" << endl <<"P_error ="; cin >> P_error; getchar(); getBinaryString(root, P_error); putBinaryString(root); getchar();}
程序流程很简单,首先输入二元对称信道的错误概率,然后输入二元序列,最后将通过通道的二元对称序列输出。在输入二元序列的过程我采用链表的形式存储每一个二元码。对应的结构为:
struct Info{ unsigned char source; unsigned char output; struct Info *next;};
通过链表进行存储,有这样一个好处就是你不需要提前分配空间,程序会判断输入流中是否含有0或1的码,然后对给每一个码动态的分配存储空间,这样既不会造成提前分配很多空间造成空间浪费,也不会因为码字过长造成缓冲区溢出。
输入函数的代码如下
void getBinaryString(Info *root, float P){ unsigned char num; Info *node = root; Info *before; cout << "!-----请输入二元信号序列:------!" << endl << endl; num = cin.get(); srand((unsigned)time(NULL)); do { node->source = num; float x; x = rand(); x = x / float(RAND_MAX); //cout << x << ' '; if (x < P) { if (num == '0') { node->output = '1'; } if (num == '1') { node->output = '0'; } } else { node->output = num; } num = cin.get(); node->next = new Info; before = node; node = node->next; } while (num == '0' || num == '1'); before->next = NULL;}
输入函数的参数包括错误概率和根节点的地址,程序运行结束将会在根节点后链接读入的二元码信息,并完成通过信道的操作。
输出函数的代码如下
void putBinaryString(Info *root){ Info *node = root; cout << endl << "!-------输出的二元序列为:-------!" << endl << endl; while (node != NULL) { cout.put(node->output); node = node->next; } cout << endl << "!-------仿真程序运行结束-------!" << endl << endl;}
输出函数执行的功能就是将链表中的通过信道后的数据输出。
程序仿真结果如下图所示
可以看出此次仿真输入的错误概率为0.3,输出序列和输入序列有两个位是不同的,也就是通过信道时受到了干扰。下面我们看两种极端的情况,就能更高的理解二元对称信道的仿真过程了。
上图是错误概率为0时的仿真结果,可以看出输入的二元字符串和输出的字符串是完全一样的,即通过信道的过程不会发生错误。
上图是错误概率为1时的结果,可以看出,输入的二元字符串和输入的二元字符正好对应位置相反,及每一位的码字经过信道时都发生了错误。
- 信息论实验-二元对称信道仿真(C++实现)
- 信息论实验-通信系统仿真(C++)
- 信道 | 信息论
- Matlab 瑞利信道仿真
- 信息论实验-信道容量迭代算法(C++实现)
- 【信息论】信道与信道容量(一)
- 信息论-离散信道及其容量笔记
- 信息论实验-称硬币
- 信息论实验-Hamming编码
- 【SDR】LTE信道仿真模型-EPA信道
- c语言实现香农编码(信息论论文)
- 信息论实验-唯一可译码判决准则
- 大三上信息论与编码实验——汉明码的编码过程的c++实现
- 信息论实验-信源编码算法 (Huffman and Shannonn Fano编码C++实现)
- 信息论实验-信源编码2(Lz编码和算数编码的C++实现)
- Matlab下多径衰落信道的仿真
- (计算机网络)JAVA实现分槽ALOHA协议仿真实验
- C-DOCSIS上行信道
- x264源代码学习1:概述与架构分析
- <Linux>Makefile自动化变量及其变种
- python各个模块的下载
- CSU1809 Parenthesis(前缀和+括号匹配)
- c++STL函数中的unique函数
- 信息论实验-二元对称信道仿真(C++实现)
- C#位运算讲解与示例
- Thymeleaf怎么原样输出html内容
- toolbar字体大小修改
- c++中箭头和点的区别
- Linux定时任务的设置
- Viewpager和GridView
- codeforces 841A Generous Kefa
- Error: Unknown system variable 'language'