码迷,mamicode.com
首页 > 编程语言 > 详细

Viterbi 算法无线通信信号处理Demo

时间:2015-05-24 23:06:08      阅读:335      评论:0      收藏:0      [点我收藏+]

标签:

  • 问题描述

信道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 }
  • 运行结果

技术分享

Viterbi 算法无线通信信号处理Demo

标签:

原文地址:http://www.cnblogs.com/zuoyouchen/p/4526545.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!