移动通信中的算法问题 实验二 相关检测

这回在上回实现功能的基础之上,修改了一些命名上的不规范,并且让文件操作更加优雅

一、引言

​ 1.相关检测技术是信号检测领域里一种重要工具,常用于从噪声背景中检测出有用的确定性信号。它利用确定性信号在不同时刻的取值一般都具有较强相关性,而干扰噪声因为随机性较强,不同时刻取值相关性较差的特性,把确定性信号和干扰噪声区分开来。

  1. 假设确定信号序列为x[m],具有噪声背景的实际信号序列为y[n],m<n,通过滑动相关计算,找出滑动相关计算序列z[k]的最大的值,则可以求出具有噪声背景的实际信号序列y中所包含的确定信号序列x的位置。

  2. 滑动相关计算公式为:

Alt

二、系统设计要求

总体要求:在12个候选小区中确认是否有适合接入的小区?若有,请找到终端最适合接入的小区。

要求输出中间过程的打印信息:

1、打印各小区强度以及排序的结果(小区ID即文件名);

2、打印与3组PSS相关后所获得的各自序列的最大值;

3、打印设置的强度门限以及相关门限;

4、体现流程分支走向(无适合接入小区,驻留失败/当前小区无法接入,寻找下一小区/当前小区满足接入条件,流程结束);

三、设计思路与方案

3.1 程序流程图设计

在这里插入图片描述

3.2 变量设计

#define data_N 12//数据组数
#define PSS_N 3//PSS文件数
#define MAX_data 30000 //data中存放信号强度的实部和虚部Q和I共30000个数据
#define MAX_PSS 4096 //PSS 存放数据4096行

struct Cell//小区结构体
{
    char ID[15];//小区名称——文件名称
    double avg_strength;//小区信号平均强度
    double strength[MAX_data/2];//小区信号强度
    double max_colleration[PSS_N];//相关性序列最大值
};
struct PSS //确定信号序列结构体
{
    char ID[15];
    double strength[MAX_PSS/2];//确定的信号强度
} ;

struct Cell cell[data_N];//小区结构体数组
struct PSS pss[PSS_N];//确定的信号序列结构体数组

void ID_init()//初始化小区名称
{
    int i;
    for(i=0;i<data_N;i++)
    {
        sprintf(cell[i].ID,"data%d.txt",i+24);//ID幅值data24~data35
    }
    for(i=0;i<PSS_N;i++)
    {
        sprintf(pss[i].ID,"PSS%d.txt",i);//ID幅值PSS0~PSS2
    }
}

3.3 文件读取以及数据处理

完成读取data文件,计算信号强度模值和平均信号强度并存入cell结构体;读取PSS文件并计算信号强度模值存入PSS数组

void fileop_data()//读取data文件,计算信号强度模值和平均信号强度并存入cell结构体
{
    FILE* fp;
    int i,j;
    double sum = 0;
    double Q,I;//定义双精度浮点数存放信号强度的实部和虚部
    for(i=0;i<data_N;i++)
    {
        if((fp = fopen(cell[i].ID,"r")) == NULL)
        {
            printf("打开文件错误");
        }
        else
        {
            for(j=0;j<MAX_data/2;j++)//
            {
                fscanf(fp,"%lf %lf",&Q,&I);//读取文件,并将数值存储到Q和I中
                sum = sum + sqrt(Q * Q + I * I);
                cell[i].strength[j] = sqrt(Q * Q + I * I);//求信号强度模值并存入结构体
            }
            if(j == MAX_data/2)//当执行到MAX/2次时执行以下代码
            {
                cell[i].avg_strength = sum / (MAX_data/2);//求平均信号强度并存入结构体
                sum = 0;//总和清零
                j = 0;//次数清零
            }
        }
        fclose(fp);
    }
}
void fileop_pss()//读取PSS文件并计算信号强度模值存入PSS数组
{
	FILE* fp;
	double Q, I;
	for (int i=0; i <PSS_N; i++)
	{
		if ((fp = fopen(pss[i].ID, "r")) == NULL)
		{
			printf("打开PSS文件错误");
		}
		for (int j=0; j<MAX_PSS/2; j++)
		{
 			fscanf(fp, "%lf %lf", &Q, &I);
			pss[i].strength[j] = sqrt(Q * Q + I * I);//计算信号强度模值并存入结构体
		}
		fclose(fp);
	}
}

3.4 冒泡排序

对小区平均信号强度从大到小进行冒泡排序。

void sort()//冒泡算法排序
{
	struct Cell temp;
	for (int i=0; i<=data_N-1; i++)
	{
		for (int j=0; j<=data_N-1-i; j++)
		{
			if (cell[j].avg_strength < cell[j+1].avg_strength)
			{
				temp = cell[j] ;
				cell[j] = cell[j+1];
				cell[j+1] = temp;
			}
		}
	}
}

3.5滑动相关检测

根据公式:
在这里插入图片描述
可设计算法如下:

double slide(struct Cell *cell, struct PSS *pss)//滑动相关检测
{
    int i,j;
    double max=0;//用于放置最大相关序列
    double temp;//用于暂存当前序列
    for(i=0; i<MAX_data/2 - MAX_PSS/2 + 1; i++)//根据公式i∈[0,n-m]
    {
        temp = 0;
        for(j=0;j<MAX_PSS/2;j++)
        {
            temp = temp + pss->strength[j] * cell->strength[i+j];
        }
        if(temp>max)
        {
            max = temp;
        }
        return max;
    }
    return 0;
}

3.6 判断是否能接入

由于排序后的结构体数据根据平均强度由强到弱的顺序存放,故先判断小区信号平均强度的最大值是否满足设定平均强度门限,若不满足则输出“无适合接入小区,驻留失败”;若满足则用flag标记出满足条件的最小位;再判断满足条平均强度的小区中,最大相关序列是否满足设定的相关门限;若满足则输出“当前小区满足接入条件,流程结束”;若当前小区不满足则继续判断下一个小区是否满足条件。

void IfConnect()//根据输入门限判断能否连接
{
    int i;
    int flag;//用于标记满足平均强度门限的小区
    double strength_threshold;//定义平均强度门限
    double correlation_threshold;//定义相关后最大强度门限
    printf("\n请输入强度门限:\n");
    scanf("%lf",&strength_threshold);
    //判断是否满足平均强度门限
    if(cell[0].avg_strength<strength_threshold)//最大值也低于门限
    {
        printf("\n无适合接入小区,驻留失败");
        return;
    }
    printf("\n满足平均强度门限条件的小区有:\n");
    for (i=0; i<data_N; i++)
	{
		if(cell[i].avg_strength>=strength_threshold)//如果满足门限条件打印相关信息
		{
		    printf("ID:%s\b\b\b\b 信号平均强度:%lf\n", cell[i].ID, cell[i].avg_strength);
            flag=i;
		}
	}
    printf("\n请输入相关门限:\n");
    scanf("%lf",&correlation_threshold);
    //判断是否满足最大相关门限
    for(i=0;i<=flag;i++)
    {
        if(cell[i].max_colleration[0]>correlation_threshold&&
            cell[i].max_colleration[1]>correlation_threshold&&
            cell[i].max_colleration[2]>correlation_threshold)
        printf("ID:%s\b\b\b\b 当前小区满足接入条件,流程结束\n",cell[i].ID);
        else
        printf("ID:%s\b\b\b\b 当前小区无法接入,寻找下一小区\n",cell[i].ID);
    }
}

3.7 主函数

int main()
{
    int i,j;
    ID_init();//初始化小区名称
    printf("文件读取中...\n");
    fileop_pss();
    fileop_data();
    sort();
    printf("\n排序结果为:\n");
    for(int i=0; i<data_N; i++)
    {
        printf("ID;%s\b\b\b\b信号平均强度为:%lf\n",cell[i].ID,cell[i].avg_strength);
    }
    printf("\nPSS与小区匹配结果:\n");
    for(i=0;i<data_N;i++)//求实际信号与确定信号相关性序列最大值
    {
        for(j=0;j<PSS_N;j++)
        {
            cell[i].max_colleration[j] = slide(&cell[i],&pss[j]);//将滑动相关后的相关性序列最大值给小区结构体
            printf("ID:%s\b\b\b\b 与 PSS%d 相关性序列最大值:%lf\n", cell[i].ID, j, cell[i].max_colleration[j]);
        }
    }
    IfConnect();
}

3.8 整体代码

#include <stdio.h>
#include <string.h>
#include <math.h>
#define data_N 12//数据组数
#define PSS_N 3//PSS文件数
#define MAX_data 30000 //data中存放信号强度的实部和虚部Q和I共30000个数据
#define MAX_PSS 4096 //PSS 存放数据4096行

struct Cell//小区结构体
{
    char ID[15];//小区名称——文件名称
    double avg_strength;//小区信号平均强度
    double strength[MAX_data/2];//小区信号强度
    double max_colleration[PSS_N];//相关性序列最大值
};
struct PSS //确定信号序列结构体
{
    char ID[15];
    double strength[MAX_PSS/2];//确定的信号强度
} ;

struct Cell cell[data_N];//小区结构体数组
struct PSS pss[PSS_N];//确定的信号序列结构体数组

void ID_init()//初始化小区名称
{
    int i;
    for(i=0;i<data_N;i++)
    {
        sprintf(cell[i].ID,"data%d.txt",i+24);
    }
    for(i=0;i<PSS_N;i++)
    {
        sprintf(pss[i].ID,"PSS%d.txt",i);
    }
}
void fileop_data()//读取data文件,计算信号强度模值和平均信号强度并存入cell结构体
{
    FILE* fp;
    int i,j;
    double sum = 0;
    double Q,I;//定义双精度浮点数存放信号强度的实部和虚部
    for(i=0;i<data_N;i++)
    {
        if((fp = fopen(cell[i].ID,"r")) == NULL)
        {
            printf("打开文件错误");
        }
        else
        {
            for(j=0;j<MAX_data/2;j++)//
            {
                fscanf(fp,"%lf %lf",&Q,&I);//读取文件,并将数值存储到Q和I中
                sum = sum + sqrt(Q * Q + I * I);
                cell[i].strength[j] = sqrt(Q * Q + I * I);//求信号强度模值并存入结构体
            }
            if(j == MAX_data/2)//当执行到MAX/2次时执行以下代码
            {
                cell[i].avg_strength = sum / (MAX_data/2);//求平均信号强度并存入结构体
                sum = 0;//总和清零
                j = 0;//次数清零
            }
        }
        fclose(fp);
    }
}
void fileop_pss()//读取PSS文件并计算信号强度模值存入PSS数组
{
	FILE* fp;
	double Q, I;
	for (int i=0; i <PSS_N; i++)
	{
		if ((fp = fopen(pss[i].ID, "r")) == NULL)
		{
			printf("打开PSS文件错误");
		}
		for (int j=0; j<MAX_PSS/2; j++)
		{
 			fscanf(fp, "%lf %lf", &Q, &I);
			pss[i].strength[j] = sqrt(Q * Q + I * I);//计算信号强度模值并存入结构体
		}
		fclose(fp);
	}
}

void sort()//冒泡算法排序
{
	struct Cell temp;
	for (int i=0; i<=data_N-1; i++)
	{
		for (int j=0; j<=data_N-1-i; j++)
		{
			if (cell[j].avg_strength < cell[j+1].avg_strength)
			{
				temp = cell[j] ;
				cell[j] = cell[j+1];
				cell[j+1] = temp;
			}
		}
	}
}
double slide(struct Cell *cell, struct PSS *pss)//滑动相关检测
{
    int i,j;
    double max=0;//用于放置最大相关序列
    double temp;//用于暂存当前序列
    for(i=0; i<MAX_data/2 - MAX_PSS/2 + 1; i++)//i∈[0,n-m]
    {
        temp = 0;
        for(j=0;j<MAX_PSS/2;j++)
        {
            temp = temp + pss->strength[j] * cell->strength[i+j];
        }
        if(temp>max)
        {
            max = temp;
        }
        return max;
    }
    return 0;
}
void IfConnect()//根据输入门限判断能否连接
{
    int i;
    int flag;//用于标记满足平均强度门限的小区
    double strength_threshold;//定义平均强度门限
    double correlation_threshold;//定义相关后最大强度门限
    printf("\n请输入强度门限:\n");
    scanf("%lf",&strength_threshold);
    //判断是否满足平均强度门限
    if(cell[0].avg_strength<strength_threshold)//最大值也低于门限
    {
        printf("\n无适合接入小区,驻留失败");
        return;
    }
    printf("\n满足平均强度门限条件的小区有:\n");
    for (i=0; i<data_N; i++)
	{
		if(cell[i].avg_strength>=strength_threshold)//如果满足门限条件打印相关信息
		{
		    printf("ID:%s\b\b\b\b 信号平均强度:%lf\n", cell[i].ID, cell[i].avg_strength);
            flag=i;
		}
	}
    printf("\n请输入相关门限:\n");
    scanf("%lf",&correlation_threshold);
    //判断是否满足最大相关门限
    for(i=0;i<=flag;i++)
    {
        if(cell[i].max_colleration[0]>correlation_threshold&&
            cell[i].max_colleration[1]>correlation_threshold&&
            cell[i].max_colleration[2]>correlation_threshold)
        printf("ID:%s\b\b\b\b 当前小区满足接入条件,流程结束\n",cell[i].ID);
        else
        printf("ID:%s\b\b\b\b 当前小区无法接入,寻找下一小区\n",cell[i].ID);
    }
}
int main()
{
    int i,j;
    ID_init();//初始化小区名称
    printf("文件读取中...\n");
    fileop_pss();
    fileop_data();
    sort();
    printf("\n排序结果为:\n");
    for(int i=0; i<data_N; i++)
    {
        printf("ID;%s\b\b\b\b信号平均强度为:%lf\n",cell[i].ID,cell[i].avg_strength);
    }
    printf("\nPSS与小区匹配结果:\n");
    for(i=0;i<data_N;i++)//求实际信号与确定信号相关性序列最大值
    {
        for(j=0;j<PSS_N;j++)
        {
            cell[i].max_colleration[j] = slide(&cell[i],&pss[j]);//将滑动相关后的相关性最大值赋予小区结构体
            printf("ID:%s\b\b\b\b 与 PSS%d 相关性序列最大值:%lf\n", cell[i].ID, j, cell[i].max_colleration[j]);
        }
    }
    IfConnect();
}

四、调试

五、心得体会

六、 意见

七、附录

运行结果
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
第一个即为最合适接入的小区,只需对Ifconnect()函数中代码稍作修改即可实现找到最优解立马退出程序,这里为了便于直观理解,就将所有情况都打印出来

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值