定位分析普遍應用,好比室外基站定位,室內藍牙beacon定位,室內wifi探針定位等,實現方式是三點定位 Trilaterationhtml
這種理想狀況要求3個基站‘同時’採集‘準確’的距離信息,算法
解決方法是:app
獲得未知點座標以後再結合時間能夠作更多應用:軌跡圖,熱力圖等,好比測試
上面的方程是n個2次方程,spa
1)首先嚐試將次數下降,逐個用方程組中第i-1個方程減去第i個方程獲得新方程,這樣n個2次方程轉換爲n-1個1次方程,scala
2)獲得n-1個1次方程(線性方程)以後,問題轉換爲一元線性迴歸問題:3d
即平面中有n個觀察點(x1, y1), (x2, y2), ..., (xn, yn),須要找到一條直線Y=aX+b,計算常數a和常數b使得n個觀察點到直線的距離(偏差)平方和最小(注意原始問題中的未知點座標就是這裏的常數a和常數b);code
一元線性迴歸模型能夠利用最小二乘法(最小平方法)求得最優解,即最小二乘解;最小二乘法詳見:http://www.javashuo.com/article/p-wezqqmww-ha.htmlhtm
(x1, y1, d1)
(x2, y2, d2)
...
(xn, yn, dn)
->
(x, y)blog
輸入
(1.0, 1.0, 1.0)
(2.0, 0.0, 1.0)
(2.0, 2.0, 1.0)
輸出
(2.0,1.0)
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)
實際數據的半徑圖示例:
半徑圖中黑色點表示基站位置,每一個基站都有一個或兩個圓圈,其中兩個圓圈使用數據裏的最大距離和最小距離繪製的;紅色點表示根據算法定位出來的設備位置;