信道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的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。