一、算法详解
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值进行排序。
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();
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.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;
}
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算法计算出估计坐标。
map<string, double> mapap = Util::StringToMap(rssiap);
map<string, double> currssiMap;
int apnum = 0;
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++;
}
将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);