可在单片机上运行的机器学习算法KNN(C语言实现)

2017年全国大学生电子设计大赛I题可见光定位问题,本方法提供一种基于位置指纹的无线定位思路,需要离线构建无线指纹库(信号强度构成的向量与对应位置标签),再用机器学习算法,例如KNN进行定位,由于比赛只允许在单片机上运行,因此针对比赛用C改写了一个可直接在单片机裸机上运行的KNN算法。

2.为什么要用C

因为诸于python等高级语言编写的机器学习代码需要有操作系统支持,而一般意义上的单片机无法运行Linux,Windows等可以支持高级语言的操作系统,因此需要使用单片机裸机或者ucOS可以支持的C 语言进行改写。

/***********************************   
     Author: ML_SDD  
     T: 2017.8.12
***********************************/

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define A_L  81

//Map这个二位数组用来保存测量好的[RSS1,RSS2,RSS3,X,Y]
unsigned char Map[A_L][5] = {};
int Dis[A_L][3];//Dis的元素分别为RSS的距离,X,Y的坐标
int k = 3;//初始K=3为找最近的3个样本
unsigned char Input[3]={0};//这里是初始化,要放的是AD做完转换后的RSS数据
//全局变量用于保存x,y的数据,以便使用
unsigned char result_x = 0;
unsigned char result_y = 0;

unsigned char knn_predict(unsigned char *Input)
{
    unsigned char i,j,n,p;//for循环控制变量
    unsigned char temp_dis,temp_x,temp_y;//数据暂存变量,冒泡排序用
    unsigned char result_sum_x = 0;
    unsigned char result_sum_y = 0;
    for(i=0;i<A_L;i++)
    {
        Dis[i][0] = sqrt((Map[i][0]-Input[0])^2 + (Map[i][1]-Input[1])^2 + (Map[i][2]-Input[2])^2);
        Dis[i][1] = Map[i][3];
        Dis[i][2] = Map[i][4];
    }
    //冒泡排序
    for(j=0;j<A_L-1;j++)
    {
        for(n=0;n<A_L-j-1;n++)
        {
            if(Dis[n][0]>Dis[n+1][0])
            {
                temp_dis = Dis[n][0];
                Dis[n][0] = Dis[n+1][0];
                Dis[n+1][0] = temp_dis;
                //------------------
                temp_x = Dis[n][1];
                Dis[n][1] = Dis[n+1][1];
                Dis[n+1][1] = temp_x;
                //------------------
                temp_y = Dis[n][2];
                Dis[n][1] = Dis[n+1][2];
                Dis[n+1][2] = temp_y;
            }
        }
    }
    for(p=0;p<k;p++)
    {
        result_sum_x = result_sum_x + Dis[p][1];
        result_sum_y = result_sum_y + Dis[p][2];
    }
    result_x = result_sum_x / k;
    result_y = result_sum_y / k;
}

猜你喜欢

转载自blog.csdn.net/ML_SDD/article/details/77804046
今日推荐