定位算法

本文详细介绍了指纹数据处理和定位算法,包括序列最大化匹配、皮尔逊相关系数计算以及欧式距离导数作为权重的计算过程。通过举例说明了如何从终端发送的指纹RSSI地图与数据库中的指纹数据进行匹配,最终计算出估计坐标。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、算法详解

1、指纹数据处理

    首先是通过函数得到终端发来的指纹数据,存入rssimap,而后通过比较数据库中的ap的mac全库排除新加入ap(也就是构建了新的currssiMap)计算出currssiMap的ap个数(也就是指纹序列长度),通过对信号强度value排序,得到最大信号强度的两个ap的mac值(也就是key)。
    代码实现主要是util.app, Util::split是将指纹数据string分割为mac地址和信号强度,Util::StringToMap是调用Util::split将指纹数据中对应的mac地址和信号强度存入rssimap为对应的key和value,Util::MapToString则相反。
    Util::stringToNum和Util::numToString主要完成key值的string和double的相互转换(为了比较两个mac是否相同),供Util::StringToMap和Util::MapToString调用。
    将map的key和value组成一个新的结构PAIR,一个PAIR型的vector存储map中的所有内容,对vector按照value值进行排序。
//string和double相互转换
double Util::stringToNum(const string& str)
{
    istringstream iss(str);
    double num;
    iss >> num;
    return num;
}
string Util::numToString(const double& num){
    int prec = numeric_limits<double>::max(); // 18
    ostringstream out;
    out.precision(prec);//覆盖默认精度
    out << num;
    string str = out.str();
    return str;
}   
//分割指纹字符串
vector<string> Util::split(const string& s, const char splitchar){
    vector<string> vec;
    if (vec.size()>0)//保证vec是空的
        vec.clear();
    int length = s.length();
    int start = 0;
    for (int i = 0; i<length; i++)
    {
        if (s[i] == splitchar && i == 0)//第一个就遇到分割符的情况
        {
            start += 1;
        }
        else if (s[i] == splitchar)
        {
            vec.push_back(s.substr(start, i - start));
            start = i + 1;
        }
        else if (i == length - 1)//到达尾部的情况
        {
            vec.push_back(s.substr(start, i + 1 - start));
        }
    }
    return vec;
}
//指纹数据中mac地址和信号强度存入map
map<string, double> Util::StringToMap(string content){
    map<string, double> smap;
    vector<string> vec = Util::split(content, ';');
    for (vector<string>::iterator it = vec.begin(); it != vec.end(); it++){
        vector<string> tmpv = Util::split(*(it), ',');
        smap.insert(map<string, double>::value_type(tmpv[0], Util::stringToNum(tmpv[1])));
    }
    return smap;
}

2.指纹的比较

   主要根据currssiMap计算出apnum(指纹在ap全库中的ap的个数),提取出最大信号强度的2个ap的mac(mac1和mac2)。然后将从指纹库中提取符合最大信号强度为mac1和mac2的指纹数据curFinger,具体方法是Location::getCurFinger,rssiMap2为curFinger中的每一条数据。通过比较currssiMap和rssiMap2相同ap个数(也就是指纹序列长度),符合L>apnum-a的接着计算出皮尔逊相似度(具体是将两者相同ap的RSSI值存入vector进行计算),如果符合相似度大于0.8的再计算出两者的欧式距离导数作为该指纹(数据库中的指纹)对应点的权重,而后根据点的权重利用nn算法计算出估计坐标。
//计算出终端发送的指纹中ap个数(属于ap全库的)
map<string, double> mapap = Util::StringToMap(rssiap);
    map<string, double> currssiMap; 
    int apnum = 0;
    //比对ap的mac全库
    while (iter!=rssiMap.end())
    {
        string key = iter->first;  
        map<string, double>::const_iterator iterap = mapap.find(key);
        if (iterap != mapap.end())
        {
            currssiMap.insert(*iter);
            apnum++;
        }
        iter++;
    }   
//排序提取最大信号强度的ap的mac  map的key和value组成一个新的结构PAIR,一个PAIR型的vector存储map中的所有内容,对vector按照value值进行排序。  
    vector<PAIR> pair_vec;
    for (map<string, double>::iterator iter = currssiMap.begin(); iter != currssiMap.end(); ++iter)  
       {  
           pair_vec.push_back(make_pair(iter->first, iter->second));  
       }  
        sort(pair_vec.begin(), pair_vec.end(), cmp); 
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值