您的位置:首页 > 其它

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

2015-05-24 21:38 169 查看
问题描述

信道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。

实现代码

package cn.edu.karel.algorithm.wirelesschannel;

import java.util.Random;

/**
*Decoder类
*
* @author Karel Zuo
* @time 2015.5.18
* @version 1.0
* @description
*   该类模拟无线通信过程,接收信息后采用维特比算法或者枚举算法消除噪音并解码。
*/

public class Decoder
{
/** 接收到的信号*/
double receive[];
/** 去噪解码后的信息 */
int[] message;
/** 接收信号的通信信道*/
double h[];
/** 接收信号的基本信号类型*/
int signal[];
/**信道矩阵*/
double H[][];

/**
* @param receive 接收到的信号(Y)
* @return message 除噪并解码后得到的信号
*/
public void decodeByViterbi( double receive[])
{
int len = receive.length-(h.length-1);//原信号长度
int n = signal.length;//信号基本类型数
int minRoadIndex[][] = new int[len]
;//记录每一个阶段的最短路的序号,1表示前一个X为1,-1表示前一个X为-1
double minRoadValue[][] = new double[len]
;//记录每一个阶段的从原点到该点最短路的权值

/**计算每一个阶段的最短路权值和选择最短路*/
int i,j;
for(i=0;i<len;i++)
{
/**初始化原顶点层 */
if(i==0)
{
minRoadIndex[i][0] = 0;
minRoadIndex[i][1] = 0;

minRoadValue[i][0] = h[0]*-10;
minRoadValue[i][1] = h[0]*10;
}
else
{
/**计算各个路径的距离和该Xi到原点S的距离*/
int q,p;
for(q=0;q<n;q++)//遍历第Xi的所有可能取值
{
double temp[] = new double[2];
for(p=0;p<n;p++)//遍历Xi-1的所有可能取值
{
temp[p] = getValue(i, q, p, minRoadIndex)+minRoadValue[i-1][p];
}

if(temp[0] <temp[1])
{
minRoadIndex[i][q] = -1;
minRoadValue[i][q] = temp[0];
}
else
{
minRoadIndex[i][q] = 1;
minRoadValue[i][q] = temp[1];
}
}
}
}

/** 输出解码结果 */
message = new int[len];
if(minRoadValue[len-1][0] < minRoadValue[len-1][1])
message[len-1] = -10;
else
message[len-1] = 10;
for(j=len-2;j>=0;j--)
{
if(message[j+1] == -10)
message[j] = minRoadIndex[j+1][0]*10;
else
message[j] = minRoadIndex[j+1][1]*10;
}

System.out.println("");
System.out.println("");
System.out.print("Viterbi算法解码后的信号 :");
for(j=0;j<len;j++)
System.out.print(message[j] + " , ");
}

/**
* @param receive 接收到的信号(Y)
* @return message 除噪并解码后得到的信号
*/
public void decodeByEnum(double receive[])
{
int len_y = receive.length;//接收信号长度
int len_x = len_y-(h.length-1);//原信号长度
int num = (int) Math.pow(signal.length, len_x );
int x[][] = new int[num][len_x ];
double value[] = new double[num];

/** 枚举所有信号组合形式及其路径长度*/
x = enmuSignal(len_x ,num);

int p,q,k;
for(p=0;p<num;p++)
{
double temp = 0;
for(q=0;q<len_y;q++)
{
temp = 0;
for(k=0;k<len_x ;k++)
{
temp += x[p][k]*H[q][k];
}
value[p] += Math.pow((receive[q]-temp), 2);
}
}

/** 搜索到最短路径的组合 */
int minRoad = 0;
double minValue = value[minRoad];
int n;
for(n=1;n<num;n++)
{
if(value
<minValue)
{
minRoad = n;
minValue = value
;
}
}
/**输出,测试 */
System.out.println("枚举算法结果:  ");
for(n=0;n<len_x;n++)
System.out.print(x[minRoad]
+ " , ");
System.out.println("");
}

/**
* 接收信号及其他参数
* @param en 发送方类对象
*/
public void getSignal(Encoder en)
{
this.receive = new double[(Encoder.sendMessage.length)];
this.receive = Encoder.sendMessage;
this.h = new double[Encoder.h.length];
this.h = Encoder.h;
this.signal = new int[Encoder.signal.length];
this.signal = Encoder.signal;

/**初始化信道矩阵*/
int len = receive.length-(h.length-1);
H = new double[receive.length][len];//信道矩阵
int i,j;
for(i=0;i<len;i++)
{
for(j=i;j<(i+h.length);j++)
H[j][i] = h[(j-i)];
}
}

/**
* 计算Xi到Xi-1的边长
* @param index 当前x的下标
* @param cur_X 当前xi的取值序号(0,1)
* @param per_X 当前xi-1的取值序号(0,1)
* @param minRoadIndex 记录Xi到Xi-1的最短路时,Xi-1的取值
* @return value 边长
*/
public double getValue(int index, int cur_X, int per_X, int minRoadIndex[][])
{
double value = 0;
int x[] = new int[10];//x的序列

if(cur_X == 0)
x[index] = -10;
else
x[index] =10;

if(per_X == 0)
x[index-1] = -10;
else
x[index-1] = 10;

if(index >= 2)
{
int i;
for(i=(index-2);i>=0;i--)
{
if(x[i+1] == -10)
x[i] = minRoadIndex[i][0]*10;
else
x[i] = minRoadIndex[i][1]*10;
}
}

int i;
for(i=0;i<10;i++)
value += x[i]*H[index][i];
value = Math.pow((receive[index]-value),2);

return value;
}

/**递归实现信号转态的枚举
* @param len X序列的长度
* @param num X的组合总数
* @return x 所有枚举组合
* */
public int[][] enmuSignal(int len,int num)
{
int m = 0;
int i[] = new int[len];
int x[][] = new int[num][len];
int n = signal.length;

for(i[0]=0;i[0]<n;i[0]++){
for(i[1]=0;i[1]<n;i[1]++){
for(i[2]=0;i[2]<n;i[2]++){
for(i[3]=0;i[3]<n;i[3]++){
for(i[4]=0;i[4]<n;i[4]++){
for(i[5]=0;i[5]<n;i[5]++){
for(i[6]=0;i[6]<n;i[6]++){
for(i[7]=0;i[7]<n;i[7]++){
for(i[8]=0;i[8]<n;i[8]++){
for(i[9]=0;i[9]<n;i[9]++){
int j;
for(j=0;j<len;j++)
x[m][j]=signal[(i[j])];
m++;
}
}
}
}
}
}
}
}
}
}

return x;
}
}

/**
* Encoder类
*
* @author Karel Zuo
* @time 2015.5.18
* @version 1.0
* @description
*   该类模拟无线通信过程,发送信息 X 经过编码得到H·X ,在传输过程中受到干扰变成 H·X + W ,并被接收。
*/

public class Encoder
{
/** 信道总数 */
static final int L = 3;
/** 基本信号 */
static final int signal[] = {10,-10};
/** H */
static final double h[] = {0.8, 0.4, 0.2};
/** 信号长度  */
static final int SUM_X = 10;
/** 噪声数量 */
static final int SUM_W = 12;
/** 最终发送的信号 */
public static double sendMessage[];

public Encoder()
{
sendMessage = new double[SUM_W];
sendMessage = getMessage(creatMessage());
}

/**
* @param signal[] 基本信号
* @return message[] 随机产生的一段信号
*/
public int[] creatMessage()
{
int message[] = new int[SUM_X];//随机产生并返回的一段信号信息
int i;
Random r = new Random();

for(i=0;i<SUM_X;i++)
{
if(r.nextInt(10) < 5)
message[i] = signal[0];
else
message[i] = signal[1];
}

/**输出,测试结果*/
System.out.println(" 随机生成的发送序列 X:");
for(i=0;i<SUM_X;i++)
System.out.print(message[i]+" , ");
System.out.println(" ");

return message;
}

/**
* @param message[] 原始信号
* @return receive[] 接收到的信号
*/
public double[] getMessage(int message[])
{
double H[][] = new double[SUM_W][SUM_X];//信道矩阵
double receive[] = new double[SUM_W];//接收信号矩阵
int i,j;
Random r = new Random();

/** 初始化 H 矩阵 */
for(i=0;i<SUM_X;i++)
for(j=i;j<(i+h.length);j++)
H[j][i] = h[(j-i)];

/** 矩阵运算 Y = H·X +W */
for(i=0;i<SUM_W;i++)
{
for(j=0;j<SUM_X;j++)
receive[i] += H[i][j]*message[j];
receive[i] += r.nextGaussian();
}

/** 输出,测试 */
System.out.println("");
System.out.println("");
System.out.println(" 输出信号 Y :");
for(i=0;i<SUM_W;i++)
System.out.println(receive[i] + " , ");
System.out.println("");

return receive;
}
}

/**
* Test类
*
* @author Karel Zuo
* @time 2015.5.18
* @version 1.0
* @description
*   该类模拟无线通信过程。
*/
public class Test {

public static void main(String[] args) {

/** 随机生成信号并用Viterbi算法和枚举算法分别还原信号 */
Encoder en = new Encoder();
Decoder de = new Decoder();
de.getSignal(en);

long startEnum = System.currentTimeMillis();//记录枚举算法开始时间
de.decodeByEnum(de.receive);
long endEnum = System.currentTimeMillis();//记录枚举算法结束时间(Viterbi算法开始时间)
long startViterbi = System.currentTimeMillis();//Viterbi算法开始时间
de.decodeByViterbi(de.receive);
long endViterbi = System.currentTimeMillis();//记录Viterbi算法结束时间

/**输出程序运行时间 */
System.out.println(" ");
System.out.println("枚举算法执行时间: " + (endEnum - startEnum));
System.out.println("Viterbi算法执行时间: " + (endViterbi - startViterbi));
}

}


运行结果

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: