以下功能:
sortByDist :: (Ord a, Floating a, RealFrac a) => [V2 a] -> Map (V2 a) [V2 a]
sortByDist graph = Map.fromList $ map sort graph where
sort point = (point, sortBy (comparing (distance point)) graph)
将列表上的每个点P映射到按其到P的距离排序的点列表。例如,sortByDist [a, b, c, d] Map.! b
是列表[b,a,c,d],如果a
是距离b最近的点,c
是距离第二近的点,d
是第3点。
由于它为每个元素执行n * log n
排序,因此复杂度为n^2 * log n
。这与对N个点列表进行排序所需时间的基准一致:
points time
200 0m0.086s
400 0m0.389s
600 0m0.980s
800 0m1.838s
1000 0m2.994s
1200 0m4.350s
1400 0m6.477s
1600 0m8.726s
3200 0m39.216s
理论上可以改善多少?是否可以将其降为N * log N
?
答案 0 :(得分:3)
作为luqui commented,使用四叉树或类似物可能会有所帮助。构建树应该采用O(n log n):log n遍,每个都是O(n)选择和分区。获得树后,可以遍历它以构建列表。节点及其子节点的列表之间的差异通常应该很小,而当某些节点很大时,应该倾向于强迫其他节点小。因此,使用自适应排序(例如,自适应合并排序或自适应展开排序)应该提供良好的性能,但分析复杂性并不容易。如果您想尝试进行一些共享,则必须使用序列类型(例如Data.Sequence
)表示列表,然后尝试找出各种比例的正方形之间的关系。我对这种降低时间复杂性的方法的可能性表示严重怀疑。