一 场景分析

定位分析广泛应用,比如室外基站定位,室内蓝牙beacon定位,室内wifi探针定位等,实现方式是三点定位 Trilateration

理想情况

这种理想情况要求3个基站‘同时’采集‘准确’的距离信息,

实际情况

  • 3个基站采集数据的时间是分开的;
  • 采集数据的距离不准确;

解决方法是:

  • 增加基站数量,即增加采集数据的密度和数量;
  • 不采用一个时间点的数据,而采用一个时间段的数据计算,比如5s内可能只有1个基站的数据,但是30s内可能会有超过3个基站的数据;
  • 在误差范围内,采用数学方法迭代收敛,找出概率上最有可能的未知点的坐标;

得到未知点坐标之后再结合时间可以做更多应用:轨迹图,热力图等,比如

二 问题抽象

已知条件

  • n个点位置坐标:(x1, y1), (x2, y2), (x3, y3), ..., (xn, yn)
  • 未知点到n个点距离:d1, d2, d3, ..., dn

求解

  • 未知点位置坐标(x, y)

方程

解法

上面的方程是n个2次方程,

1)首先尝试将次数降低,逐个用方程组中第i-1个方程减去第i个方程得到新方程,这样n个2次方程转换为n-1个1次方程,

2)得到n-1个1次方程(线性方程)之后,问题转换为一元线性回归问题:

即平面中有n个观察点(x1, y1), (x2, y2), ..., (xn, yn),需要找到一条直线Y=aX+b,计算常数a和常数b使得n个观察点到直线的距离(误差)平方和最小(注意原始问题中的未知点坐标就是这里的常数a和常数b);

一元线性回归模型可以利用最小二乘法(最小平方法)求得最优解,即最小二乘解;最小二乘法详见:https://www.cnblogs.com/barneywill/p/10217349.html

问题模型简化

(x1, y1, d1)
(x2, y2, d2)
...
(xn, yn, dn)
->
(x, y)

三 统计示例

输入
(1.0, 1.0, 1.0)
(2.0, 0.0, 1.0)
(2.0, 2.0, 1.0)

输出
(2.0,1.0)

四 代码实现

scala核心代码

scala

  /**
* @param datas Array(x_coordinates, y_coordinates, distance)
* @return (x_coordinates, y_coordinates)
*/
def detect(datas : Array[(Double, Double, Double)]) : (Double, Double) = {
if (datas == null || datas.isEmpty) (0, 0)
else if (datas.length == 1) return (datas.head._1, datas.head._2)
else if (datas.length == 2) return ((datas.head._1 + datas.last._1) / 2, (datas.head._2 + datas.last._2) / 2)
else {
var data = Array[Array[Double]]()
//X + (y_1 - y_i)/(x_1 - x_i)Y = (sq(d_i) - sq(d_1) + sq(x_1) + sq(y_1) - sq(x_i) - sq(y_i))/2(x_1 - x_i)
for (i <- 1 to (datas.length - 1)) data = data :+ Array((datas.head._2 - datas.apply(i)._2) / (datas.head._1 - datas.apply(i)._1), (Math.pow(datas.apply(i)._3, 2) - Math.pow(datas.head._3, 2) + Math.pow(datas.head._1, 2) + Math.pow(datas.head._2, 2) - Math.pow(datas.apply(i)._1, 2) - Math.pow(datas.apply(i)._2, 2)) / 2 / (datas.head._1 - datas.apply(i)._1))
val regression = new SimpleRegression
regression.addData(data)
(regression.getIntercept, regression.getSlope)
}
}

测试运行

      println(detect(Array((1.0, 1.0, 1.0))))
println(detect(Array((1.0, 1.0, 1.0), (2.0, 2.0, 1.0))))
println(detect(Array((1.0, 1.0, 1.0), (2.0, 0.0, 1.0), (2.0, 2.0, 1.0))))
println(detect(Array((1.0, 1.0, 1.0), (2.0, 0.0, 1.0), (2.0, 3.0, 1.0))))
println(detect(Array((1.0, 1.0, 1.0), (2.0, 0.0, 1.0), (2.0, 3.0, 1.0), (2.0, 3.0, 1.0), (20.0, 30.0, 1.0))))

输出

(1.0,1.0)
(1.5,1.5)
(2.0,1.0)
(2.5,1.5)
(7.728915662650602,3.3674698795180724)

五 半径图效果

实际数据的半径图示例:

半径图中黑色点表示基站位置,每个基站都有一个或两个圆圈,其中两个圆圈使用数据里的最大距离和最小距离绘制的;红色点表示根据算法定位出来的设备位置;

【原创】大叔案例分享(4)定位分析--见证scala的强大的更多相关文章

  1. 【原创】大叔案例分享(3)用户行为分析--见证scala的强大

    一 场景分析 用户行为分析应用的场景很多,像线上网站访问统计,线下客流分析(比如图像人脸识别.wifi探针等),比较核心的指标有几个: PV | UV | SD | SC 指标说明: PV(Page ...

  2. 老李案例分享:定位JAVA内存溢出

    老李案例分享:定位JAVA内存溢出   poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.在poptest的loadrunner的培 ...

  3. 老李案例分享:MAT分析应用程序服务出现内存溢出过程

    老李案例分享:MAT分析应用程序服务出现内存溢出过程   poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.在poptest的loa ...

  4. 【原创】大叔案例分享(5)id打通

    经常有一些需要做id打通的场景,比如用户id打通等, 问题抽象是每条数据都可以解析出一个或多个kv pair:(id_type,id),然后需要将某一个kv pair匹配的多条数据进行merge: 比 ...

  5. mysql的"双1设置"-数据安全的关键参数(案例分享)

    mysql的"双1验证"指的是innodb_flush_log_at_trx_commit和sync_binlog两个参数设置,这两个是是控制MySQL 磁盘写入策略以及数据安全性 ...

  6. MySQL数据库详解之"双1设置"的数据安全的关键参数案例分享

    mysql的"双1验证"指的是innodb_flush_log_at_trx_commit和sync_binlog两个参数设置,这两个是是控制MySQL 磁盘写入策略以及数据安全性 ...

  7. 前端案例分享(一):CSS+JS实现流星雨动画

    目录 引言 1.效果图 2.源码 3.案例解析 4.小问题 5.结语 引言        平常会做一些有意思的小案例练手,通常都会发到codepen上,但是codepen不能写分析.        所 ...

  8. Office 2010 KMS激活原理和案例分享

    Office 2010 KMS激活原理和案例分享     为了减低部署盗版(可能包含恶意软件.病毒和其他安全风险)的可能性,Office 2010面向企业客户推出了新的批量激活方式:KMS和MAK.这 ...

  9. Office 2010 KMS激活原理和案例分享 - Your Office Solution Here - Site Home - TechNet Blogs

    [作者:葛伟华.张玉工程师 ,  Office/Project支持团队, 微软亚太区全球技术支持中心 ] 为了减低部署盗版(可能包含恶意软件.病毒和其他安全风险)的可能性,Office 2010面向企 ...

随机推荐

  1. 03-JavaScript之数据类型

    JavaScript之数据类型 1.介绍 JavaScript数据类型分为两类:原始类型(primitive type)和对象类型(object type) 2.原始类型 数字 - number.字符 ...

  2. Linux重启命令

    Linux和windows不同,linux后台运行着许多进程,所以强制关机可能会导致进程的数据丢失使系统处于不稳定的状态.甚至在有的系统中会损坏硬件设备.而在系统关机前使用shutdown命令,系统管 ...

  3. Day8 信号检测与估值

    检测:接收机或处理器根据在[0,T]内观测到的信号r(t)的统计特性,按照一定准则 判断信源发送的是某个已知信号集中的哪个信号. 如:调制信号的检测问题 估计:接收机或处理器根据在[0,T]内观测到的 ...

  4. opentack-openstack组件及功能(1)

    一. OpenStack各组件间的关系 图22.1 OpenStack各组件间的关系 1.基础管理服务包含Keystone,Glance,Nova,Neutron,Horizon五个服务 (1)Key ...

  5. Linux(Ubuntu)使用日记------自定义命令的使用

    Linux如何自定义自己的命令呢?修改 系统中的 ~/.bashrc 文件即可 在这个文件最后面使用alias命令重定义命令. 例如: # novel-git begin alias n.r='les ...

  6. Shell命令-文件及内容处理之sort、uniq

    文件及内容处理 - sort.unip 1. sort:对文件的文本内容排序 sort命令的功能说明 sort 命令用于将文本文件内容加以排序.sort 可针对文本文件的内容,以行为单位来排序. so ...

  7. ASP.NET MVC系列:web.config中ConnectionString aspnet_iis加密与AppSettings独立文件

    1. web.config中ConnectionString aspnet_iis加密 web.config路径:E:\Projects\Libing.Web\web.config <conne ...

  8. hihoCoder #1770 : 单调数(数位dp)

    题面 我们定义一个数是单调数,当且仅当构成这个数每一个数位都是单调不降或不增的. 例如 \(123\) 和 \(321\) 和 \(221\) 和 \(111\) 是单调的,而 \(312\) 不是单 ...

  9. 位运算之——按位与(&)操作——(快速取模算法)

    学习redis 字典结构,hash找槽位 求槽位的索引值时,用到了 hash值 & sizemask操作, 其后的scan操作涉及扫描顺序逻辑,对同模的槽位 按一定规则扫描! 其中涉及位运算 ...

  10. JSTL和EL的使用

    JSTL和EL的使用 使用JSTL前的准备 想要使用JSTL,首先需要给工程导入JSTL的包(JSTL.jar和standard.jar). JSTL标签库 在JSTL中分为以下五个标签 核心标签 格 ...