|
- Sub kagawa()
- Dim i&, j&, k&, l&, m&, k1&, k2&, j1#, w1#, t#, cnt&
- tms = Timer
-
- [e1].CurrentRegion.Sort [f2], 1, [g2], , 1, , , 1
- 'B组数据先按经度、维度排序 以便排除经度差距大距离肯定较远的值,可减少80%计算量
-
- m = [e1].End(4).Row - 1 '得到B组数据个数m
- nr2 = [e2].Resize(m) 'B组序号
- jr2 = [f2].Resize(m) 'B组经度值
- wr2 = [g2].Resize(m) 'B组维度值
-
- arr = [a1].CurrentRegion '获取A组原始数据
- ' For i = 2 To 1000 '测试时遍历检查A组1000行
- For i = 2 To UBound(arr) '遍历检查A组各行
- j1 = arr(i, 2): w1 = arr(i, 3) '经度1、维度1数据存入变量
- k1 = Application.Match(j1 - 0.02, jr2, 1) '检查比经度1小0.02的起始位置k1
- k2 = Application.Match(j1 + 0.02, jr2, 1) '检查比经度1大0.02的结束位置k2
- cnt = cnt + k2 - k1 + 1 '累计本次对比检查B组的次数k2-k2+1
-
- ReDim br(10, 1): l = 0 '定义存放10个最小值数据的临时数组br
- For j = k1 To k2 '遍历B组中k1 to k2 范围 (这样就已经减少了85%左右的计算量)
-
- t = f(j1, w1, jr2(j, 1), wr2(j, 1)) '用经验公式f计算两点坐标间距离
- '这个方法可以提速 5-6倍
- For k = l - 1 To 0 Step -1
- If t > br(k, 1) Then
- Exit For
- Else
- br(k + 1, 1) = br(k, 1)
- br(k + 1, 0) = br(k, 0)
- End If
- Next
- br(k + 1, 1) = t: br(k + 1, 0) = j
- If l < 10 Then l = l + 1
- '以上部分为比较法排序筛选得到最小的10个值,以及它们的B组行位置
- Next
- For k = 0 To l - 1
- '仅仅对这10个最小值,用精确公式重新计算其距离值
- If br(k, 1) Then br(k, 1) = ff(j1, w1, jr2(br(k, 0), 1), wr2(br(k, 0), 1))
- Next
- ' [i1].Resize(l, 2) = br '结果可以随时输出
- Next
- MsgBox Format(Timer - tms, "0.000s ") & cnt '最后统计耗时以及A组B组实际交互检查比对的次数
- End Sub
- Function f(j1, w1, j2, w2) '粗略经验公式
- f = (((j1 - j2) * 110965) ^ 2 + ((w1 - w2) * 95839) ^ 2) ^ 0.5
- End Function
- Function ff(j1, w1, j2, w2) '精确计算公式
- ' t = Sin(w1) * Sin(w2) + Cos(w1) * Cos(w2) * Cos(j1 - j2)
- ' If Round(t, 12) = 1 Then ff = 0 Else ff = Application.Acos(t) * 111195
- ff = Application.Acos(Sin(w1) * Sin(w2) + Cos(w1) * Cos(w2) * Cos(j1 - j2)) * 111195
- End Function
复制代码 |
|