场景

有一个神秘门店,有配送服务,给很多人(N<20)配送过商品,但是配送单上只有配送目标地点坐标(x,y)和配送距离(D,存在误差,但保证只多不少),现在我们收集到了这些配送单,要求反找出这个门店的位置。(大致能估算出来就行,要求这个位置满足)

解决思路

这个问题最开始想到的是质心定位,但第一次定位肯定存在定位不准,所以就需要迭代优化,考虑到被配送点反推距离是个圆,于是迭代方案就选择了力引导迭代,把迭代时的步进因子设置一下。

和大佬交流了一下,大佬表示如果数据真的比较干净的话(保证存在交集)可以使用拉格朗日乘子算法,找到零点最近(min(x^2+y^2) or min(x+y))的那个,每个采样点d(x0-x,y0-y)-R < 0 作为约束条件,但是假如约束条件太多的话容易导致优化器迭代很慢,不过有现有的优化器可以直接调包,是一种快捷的思路。

另一个大佬有对于初始点定位有新的思路:先把经纬坐标映射到平面坐标系上,然后将所有的圆(或者椭圆,这个映射方式无所谓,后面会说)扩展为一个经纬平行方向的矩形,对于圆来说,找交集很困难,但是对于矩形来说,找交集很简单,所以将这些矩形从小到大排列,然后依次叠加交集,过滤掉后来的没有交集的矩形,最后留下的矩形交集的几何中心就是初始点。

关于为什么映射成圆或者椭圆无所谓,因为这种算法省略了计算任意两点距离的麻烦,只需要计算经向纬向的最远距离,独立两个纬度的线性可逆变换最后都能很简单反映射回去。

生成模拟数据

模拟数据分为两种,一种是保证有交集的干净数据,一种是不保证有交集的脏数据。干净数据生成方式可以逆向思维,先确定一个交集,在去生成覆盖这个交集的圆,脏数据生成就是让干净数据随机偏移就可以了。

设计细节

拉格朗日乘子有现有方案,要注意一下不同迭代器的参数配置。

对于矩形交集初始点,这个方案很清晰明了,算起来也很快,所以不多说了,注意一下矩形是需要排个序的,最小的权重最大,交集一定是最小的矩形的子集。

说到质心+力导向:

  • 关于质量权重的选择,显然圆越大越不准,所以质量权重应该越低,把质量定义为半径的平方倒数,生成初始点期望更靠近小的圆。
  • 关于力的定义,采用圆内 F = 0,圆外 F = (d-r)^2 ,首先这样可以尽可能保证圆外的点都能尽快回到圆内,另一个就是希望离圆越远就靠近越快。
  • 经纬度算距离和平面距离不太一样,建议距离计算单独写一个函数便于更改。

实验结果

PS:每批做了十万次实验

实验批号 采样点数量 最大采样距离
(误差25m)
耗时 迭代上限 步长因子 失败率 平均迭代
01 4 20km 3129ms 5000 0.003 0.0 85.95243
02 7 20km 3798ms 5000 0.003 0.0 83.55214
03 15 20km 2860ms 5000 0.003 0.0 29.99788
04 25 20km 2714ms 5000 0.003 0.0 15.66433
05 25 20km 2013ms 5000 0.005 0.0 9.49053

实验日志

Start==========Finished
Circle Num=4
Step Radio:0.003
迭代上限:5000
Lab Num=100000
Time:3129ms
Fails Ratio=0.0
Fails Avg Distance=NaNm
Max Delivery Distance = 20.0km
平均迭代:85.95243

Start==========Finished
Circle Num=7
Step Radio:0.003
迭代上限:5000
Lab Num=100000
Time:3798ms
Fails Ratio=0.0
Fails Avg Distance=NaNm
Max Delivery Distance = 20.0km
平均迭代:83.55214

Start==========Finished
Circle Num=15
Step Radio:0.003
迭代上限:5000
Lab Num=100000
Time:2860ms
Fails Ratio=0.0
Fails Avg Distance=NaNm
Max Delivery Distance = 20.0km
平均迭代:29.99788

Start==========Finished
Circle Num=25
Step Radio:0.003
迭代上限:5000
Lab Num=100000
Time:2714ms
Fails Ratio=0.0
Fails Avg Distance=NaNm
Max Delivery Distance = 20.0km
平均迭代:15.66433

Start==========Finished
Circle Num=25
Step Radio:0.005
迭代上限:5000
Lab Num=100000
Time:2013ms
Fails Ratio=0.0
Fails Avg Distance=NaNm
Max Delivery Distance = 20.0km
平均迭代:9.49053