• 问题描述

信道H长度L=3,H = (h0,h1,h2),其中h0=,h1=,h2=; 基本信号类型 x =10或-10,一个完整的信号序列为X = (x0,x1,x2,...,x9);噪声W = (w0,w1,w2,...,w11)是满足高斯分布的(0,1)范围内的随机数;按照Y = H·X + W公式转换得到一个完整的信号序列Y = (y0,y1,y2,...,y11)。信号接收端需要在已知Y,H的情况下通过Viterbi算法得到满足 min (W)即 min(Y - H·X)的X`序列。

  • 算法思路

将问题转换为的篱笆图,通过动态规划算法,以min(Y - H·X)为图中每一条边的权值计算公式,从显性序列 Y 推导得到隐性序列 X。

  • 实现代码
  1 package cn.edu.karel.algorithm.wirelesschannel;
  2
  3 import java.util.Random;
  4
  5 /**
  6  *Decoder类
  7  *
  8  * @author Karel Zuo
  9  * @time 2015.5.18
 10  * @version 1.0
 11  * @description
 12  *   该类模拟无线通信过程,接收信息后采用维特比算法或者枚举算法消除噪音并解码。
 13  */
 14
 15 public class Decoder
 16 {
 17     /** 接收到的信号*/
 18     double receive[];
 19     /** 去噪解码后的信息 */
 20     int[] message;
 21     /** 接收信号的通信信道*/
 22     double h[];
 23     /** 接收信号的基本信号类型*/
 24     int signal[];
 25     /**信道矩阵*/
 26     double H[][];
 27
 28     /**
 29      * @param receive 接收到的信号(Y)
 30      * @return message 除噪并解码后得到的信号
 31      */
 32     public void decodeByViterbi( double receive[])
 33     {
 34         int len = receive.length-(h.length-1);//原信号长度
 35         int n = signal.length;//信号基本类型数
 36         int minRoadIndex[][] = new int[len][n];//记录每一个阶段的最短路的序号,1表示前一个X为1,-1表示前一个X为-1
 37         double minRoadValue[][] = new double[len][n];//记录每一个阶段的从原点到该点最短路的权值
 38
 39         /**计算每一个阶段的最短路权值和选择最短路*/
 40         int i,j;
 41         for(i=0;i<len;i++)
 42         {
 43             /**初始化原顶点层 */
 44             if(i==0)
 45             {
 46                 minRoadIndex[i][0] = 0;
 47                 minRoadIndex[i][1] = 0;
 48
 49                 minRoadValue[i][0] = h[0]*-10;
 50                 minRoadValue[i][1] = h[0]*10;
 51             }
 52             else
 53             {
 54                 /**计算各个路径的距离和该Xi到原点S的距离*/
 55                 int q,p;
 56                 for(q=0;q<n;q++)//遍历第Xi的所有可能取值
 57                 {
 58                     double temp[] = new double[2];
 59                     for(p=0;p<n;p++)//遍历Xi-1的所有可能取值
 60                     {
 61                         temp[p] = getValue(i, q, p, minRoadIndex)+minRoadValue[i-1][p];
 62                     }
 63
 64                     if(temp[0] <temp[1])
 65                     {
 66                         minRoadIndex[i][q] = -1;
 67                         minRoadValue[i][q] = temp[0];
 68                     }
 69                     else
 70                     {
 71                         minRoadIndex[i][q] = 1;
 72                         minRoadValue[i][q] = temp[1];
 73                     }
 74                 }
 75             }
 76         }
 77
 78         /** 输出解码结果 */
 79         message = new int[len];
 80         if(minRoadValue[len-1][0] < minRoadValue[len-1][1])
 81             message[len-1] = -10;
 82         else
 83             message[len-1] = 10;
 84         for(j=len-2;j>=0;j--)
 85         {
 86             if(message[j+1] == -10)
 87                 message[j] = minRoadIndex[j+1][0]*10;
 88             else
 89                 message[j] = minRoadIndex[j+1][1]*10;
 90         }
 91
 92         System.out.println("");
 93         System.out.println("");
 94         System.out.print("Viterbi算法解码后的信号 :");
 95         for(j=0;j<len;j++)
 96             System.out.print(message[j] + " , ");
 97     }
 98
 99     /**
100      * @param receive 接收到的信号(Y)
101      * @return message 除噪并解码后得到的信号
102      */
103     public void decodeByEnum(double receive[])
104     {
105         int len_y = receive.length;//接收信号长度
106         int len_x = len_y-(h.length-1);//原信号长度
107         int num = (int) Math.pow(signal.length, len_x );
108         int x[][] = new int[num][len_x ];
109         double value[] = new double[num];
110
111         /** 枚举所有信号组合形式及其路径长度*/
112         x = enmuSignal(len_x ,num);
113
114         int p,q,k;
115         for(p=0;p<num;p++)
116         {
117             double temp = 0;
118             for(q=0;q<len_y;q++)
119             {
120                 temp = 0;
121                 for(k=0;k<len_x ;k++)
122                 {
123                     temp += x[p][k]*H[q][k];
124                 }
125                 value[p] += Math.pow((receive[q]-temp), 2);
126             }
127         }
128
129         /** 搜索到最短路径的组合 */
130         int minRoad = 0;
131         double minValue = value[minRoad];
132         int n;
133         for(n=1;n<num;n++)
134         {
135             if(value[n]<minValue)
136             {
137                 minRoad = n;
138                 minValue = value[n];
139             }
140         }
141         /**输出,测试 */
142         System.out.println("枚举算法结果:  ");
143         for(n=0;n<len_x;n++)
144             System.out.print(x[minRoad][n] + " , ");
145         System.out.println("");
146     }
147
148     /**
149      * 接收信号及其他参数
150      * @param en 发送方类对象
151      */
152     public void getSignal(Encoder en)
153     {
154         this.receive = new double[(Encoder.sendMessage.length)];
155         this.receive = Encoder.sendMessage;
156         this.h = new double[Encoder.h.length];
157         this.h = Encoder.h;
158         this.signal = new int[Encoder.signal.length];
159         this.signal = Encoder.signal;
160
161         /**初始化信道矩阵*/
162         int len = receive.length-(h.length-1);
163         H = new double[receive.length][len];//信道矩阵
164         int i,j;
165         for(i=0;i<len;i++)
166         {
167             for(j=i;j<(i+h.length);j++)
168                 H[j][i] = h[(j-i)];
169         }
170     }
171
172     /**
173      * 计算Xi到Xi-1的边长
174      * @param index 当前x的下标
175      * @param cur_X 当前xi的取值序号(0,1)
176      * @param per_X 当前xi-1的取值序号(0,1)
177      * @param minRoadIndex 记录Xi到Xi-1的最短路时,Xi-1的取值
178      * @return value 边长
179      */
180     public double getValue(int index, int cur_X, int per_X, int minRoadIndex[][])
181     {
182         double value = 0;
183         int x[] = new int[10];//x的序列
184
185         if(cur_X == 0)
186             x[index] = -10;
187         else
188             x[index] =10;
189
190         if(per_X == 0)
191             x[index-1] = -10;
192         else
193             x[index-1] = 10;
194
195
196         if(index >= 2)
197         {
198             int i;
199             for(i=(index-2);i>=0;i--)
200             {
201                 if(x[i+1] == -10)
202                     x[i] = minRoadIndex[i][0]*10;
203                 else
204                     x[i] = minRoadIndex[i][1]*10;
205             }
206         }
207
208         int i;
209         for(i=0;i<10;i++)
210             value += x[i]*H[index][i];
211         value = Math.pow((receive[index]-value),2);
212
213         return value;
214     }
215
216     /**递归实现信号转态的枚举
217      * @param len X序列的长度
218      * @param num X的组合总数
219      * @return x 所有枚举组合
220      * */
221     public int[][] enmuSignal(int len,int num)
222     {
223         int m = 0;
224         int i[] = new int[len];
225         int x[][] = new int[num][len];
226         int n = signal.length;
227
228         for(i[0]=0;i[0]<n;i[0]++){
229             for(i[1]=0;i[1]<n;i[1]++){
230                 for(i[2]=0;i[2]<n;i[2]++){
231                     for(i[3]=0;i[3]<n;i[3]++){
232                         for(i[4]=0;i[4]<n;i[4]++){
233                             for(i[5]=0;i[5]<n;i[5]++){
234                                 for(i[6]=0;i[6]<n;i[6]++){
235                                     for(i[7]=0;i[7]<n;i[7]++){
236                                         for(i[8]=0;i[8]<n;i[8]++){
237                                             for(i[9]=0;i[9]<n;i[9]++){
238                                                 int j;
239                                                 for(j=0;j<len;j++)
240                                                     x[m][j]=signal[(i[j])];
241                                                 m++;
242                                             }
243                                         }
244                                     }
245                                 }
246                             }
247                         }
248                     }
249                 }
250             }
251         }
252
253         return x;
254     }
255 }
256
257 /**
258  * Encoder类
259  *
260  * @author Karel Zuo
261  * @time 2015.5.18
262  * @version 1.0
263  * @description
264  *   该类模拟无线通信过程,发送信息 X 经过编码得到H·X ,在传输过程中受到干扰变成 H·X + W ,并被接收。
265  */
266
267 public class Encoder
268 {
269     /** 信道总数 */
270     static final int L = 3;
271     /** 基本信号 */
272     static final int signal[] = {10,-10};
273     /** H */
274     static final double h[] = {0.8, 0.4, 0.2};
275     /** 信号长度  */
276     static final int SUM_X = 10;
277     /** 噪声数量 */
278     static final int SUM_W = 12;
279     /** 最终发送的信号 */
280     public static double sendMessage[];
281
282     public Encoder()
283     {
284         sendMessage = new double[SUM_W];
285         sendMessage = getMessage(creatMessage());
286     }
287
288     /**
289      * @param signal[] 基本信号
290      * @return message[] 随机产生的一段信号
291      */
292     public int[] creatMessage()
293     {
294         int message[] = new int[SUM_X];//随机产生并返回的一段信号信息
295         int i;
296         Random r = new Random();
297
298         for(i=0;i<SUM_X;i++)
299         {
300             if(r.nextInt(10) < 5)
301                 message[i] = signal[0];
302             else
303                 message[i] = signal[1];
304         }
305
306         /**输出,测试结果*/
307         System.out.println(" 随机生成的发送序列 X:");
308         for(i=0;i<SUM_X;i++)
309             System.out.print(message[i]+" , ");
310         System.out.println(" ");
311
312         return message;
313     }
314
315     /**
316      * @param message[] 原始信号
317      * @return receive[] 接收到的信号
318      */
319     public double[] getMessage(int message[])
320     {
321         double H[][] = new double[SUM_W][SUM_X];//信道矩阵
322         double receive[] = new double[SUM_W];//接收信号矩阵
323         int i,j;
324         Random r = new Random();
325
326         /** 初始化 H 矩阵 */
327         for(i=0;i<SUM_X;i++)
328             for(j=i;j<(i+h.length);j++)
329                 H[j][i] = h[(j-i)];
330
331         /** 矩阵运算 Y = H·X +W */
332         for(i=0;i<SUM_W;i++)
333         {
334             for(j=0;j<SUM_X;j++)
335                 receive[i] += H[i][j]*message[j];
336             receive[i] += r.nextGaussian();
337         }
338
339         /** 输出,测试 */
340         System.out.println("");
341         System.out.println("");
342         System.out.println(" 输出信号 Y :");
343         for(i=0;i<SUM_W;i++)
344             System.out.println(receive[i] + " , ");
345         System.out.println("");
346
347         return receive;
348     }
349 }
350
351 /**
352  * Test类
353  *
354  * @author Karel Zuo
355  * @time 2015.5.18
356  * @version 1.0
357  * @description
358  *   该类模拟无线通信过程。
359  */
360 public class Test {
361
362     public static void main(String[] args) {
363
364         /** 随机生成信号并用Viterbi算法和枚举算法分别还原信号 */
365         Encoder en = new Encoder();
366         Decoder de = new Decoder();
367         de.getSignal(en);
368
369         long startEnum = System.currentTimeMillis();//记录枚举算法开始时间
370         de.decodeByEnum(de.receive);
371         long endEnum = System.currentTimeMillis();//记录枚举算法结束时间(Viterbi算法开始时间)
372         long startViterbi = System.currentTimeMillis();//Viterbi算法开始时间
373         de.decodeByViterbi(de.receive);
374         long endViterbi = System.currentTimeMillis();//记录Viterbi算法结束时间
375
376
377         /**输出程序运行时间 */
378         System.out.println(" ");
379         System.out.println("枚举算法执行时间: " + (endEnum - startEnum));
380         System.out.println("Viterbi算法执行时间: " + (endViterbi - startViterbi));
381     }
382
383 }

  • 运行结果

转载于:https://www.cnblogs.com/zuoyouchen/p/4526545.html

Viterbi 算法无线通信信号处理Demo相关推荐

  1. HMM 前向 后向 Viterbi算法讲解通透的

    HMM  前向 后向 Viterbi算法讲解通透的 https://blog.csdn.net/xueyingxue001/article/details/52396494 什么是HMM https: ...

  2. 隐马尔可夫HMM中viterbi算法

    引言 viterbi算法简化最有可能的天气序列的运算过程,forward算法简化该该观察值的概率. 问题描述 你在中国,你朋友F在美国,F的作息有walk, shop, clean,但这选择跟天气有关 ...

  3. 隐马尔可夫(HMM)、前/后向算法、Viterbi算法

    HMM的模型  图1 如上图所示,白色那一行描述由一个隐藏的马尔科夫链生成不可观测的状态随机序列,蓝紫色那一行是各个状态生成可观测的随机序列 话说,上面也是个贝叶斯网络,而贝叶斯网络中有这么一种,如下 ...

  4. 机器学习知识点(二十四)隐马尔可夫模型HMM维特比Viterbi算法Java实现

    1.隐马尔可夫模型HMM    学习算法,看中文不如看英文,中文喜欢描述的很高深.    http://www.comp.leeds.ac.uk/roger/HiddenMarkovModels/ht ...

  5. viterbi算法_HMM模型和Viterbi算法如何应用于分词

    首先感谢以下博主的分享,第一,二个链接是讲的HMM模型,第三个文章讲的是Viterbi算法 结巴分词3--基于汉字成词能力的HMM模型识别未登录词 - 老顽童2007 - 博客园​www.cnblog ...

  6. 隐马尔可夫模型中的Viterbi算法zz

    隐马尔可夫模型中的Viterbi算法zz 这篇文章简单描述一下Viterbi算法--一年之前我听过它的名字,直到两周之前才花了一点时间研究了个皮毛,在这里做个简单检讨.先用一句话来简单描述一下:给出一 ...

  7. 线性链条件随机场与HMM在viterbi算法中的图解对比

    先整理下相关概念: 条件随机场P(Y|X): 表示的是给定一组输入随机变量 X 的条件下另一组输出随机变量 Y 的马尔可夫随机场,也就是说 CRF 的特点是假设输出随机变量构成马尔可夫随机场. 什么是 ...

  8. viterbi算法_序列比对(十四)——viterbi算法和后验解码的比较

    原创: hxj7 本文比较了viterbi算法求解最可能路径以及后验解码这两种不同的解码方法. 前文<序列比对(十)viterbi算法求解最可能路径>介绍了用viterbi算法求解最可能路 ...

  9. 语音识别维特比解码_HMM连续语音识别中Viterbi算法的优化及应用

    HMM 连续语音识别中 Viterbi 算法的优化及应用 袁俊 [期刊名称] <电子技术> [年 ( 卷 ), 期] 2001(028)002 [摘要] 基于 HMM 连续语音识别系统声学 ...

最新文章

  1. Android之NDK开发的简单实例
  2. 杂乱无章之javascript(一)
  3. 记录一个找问题的经过
  4. QT乱码总结0.Qt乱码产生因素
  5. Pygame 使用Djkstra广度搜索寻找迷宫(相对)最短路径
  6. 《Swift开发实战》——第1章,第1.4节启动iOS 8模拟器
  7. python中缩进在程序中_有没有办法将Python代码中的缩进转换为大括号?
  8. fir.im同款企业级APP分发平台系统源码
  9. 2020-10-24 pandas导入出现错误或者警告解决方案
  10. centos7下使用git提交代码
  11. 在vue中,如何禁止回退上一步,路由不存历史记录
  12. 3分钟下载好网易云付费音乐
  13. codeblock调试
  14. EXCEL慢的解决方法
  15. 快来:互联网内容运营人员的文案写作技巧
  16. [CGAL]建立一个正四面体
  17. Android 高德地图Marker和Marker点击事件处理
  18. html的vr图怎么制作,什么叫vr全景展示?vr图片怎么做的?
  19. P9065 [yLOI2023] 云梦谣 题解
  20. 什么是单元测试?该怎么做单元测试?

热门文章

  1. 1016.XXE漏洞攻防学习
  2. 前端相对路径 与后端相对路径的区分
  3. Ubuntu安装VLC播放器
  4. HDU 1297 Children’s Queue
  5. Python SSH爆破以及Python3线程池控制线程数
  6. Go - interface
  7. 《Linux内核分析》实践4
  8. sitemesh官网简介,安装配置教程。(非常适合新手)
  9. Tomcat源码学习(4)-How Tomcat works(转)
  10. git push origin master和git push有什么区别?