我正在进行的项目涉及阅读和分析大量数据集(Illustris 1 Dark,大约4,000,000个暗物质晕)。为了获得更好的结果,我想强制实施以下隔离标准:
只保留半径为300kpc的2D圆圈中最大的光晕,并摆脱该圆圈中的其他光晕
现在,我所拥有的当前实现在O(n ^ 2)中运行时间,这意味着代码可以花费天来完成。我真的想做得更好,但无法弄清楚如何做。这就是我到目前为止所做的:
返回Group1邻居列表的功能
def neighbors(Group1, Radius):
Neighbors = []
for Group2 in Groups:
if Distance_2D(Group1, Group2) < Radius:
Neighbors.append(Group2)
return Neighbors
在给定邻居列表的情况下返回最大群组的功能
def biggest(Neighbors):
Biggest = Neighbors[0]
for N in Neighbors:
if N.mass > Biggest.mass:
Biggest = N
return Biggest
全部放在一起
for Group in Groups:
Neighbors = neighbors(Group, 300)
if not Group == Biggest(Neighbors):
Groups.remove(Group)
else:
Groups.remove(Neighbors)
Groups.append(Group)
在for循环之后,Groups应该是在300kpc半径范围内最大的晕圈列表。
我也知道在迭代同一个列表时从列表中删除某些内容并不是一种好习惯,所以如果你的提示/答案处理了这一点,那就太棒了!
提前谢谢大家:)
答案 0 :(得分:0)
质量最大的光环将在一组中。比半径更接近最大光环的光晕不会在一组中。随着算法的大纲是:
result = []
for h in sorted(halos, key=lambda h: h.mass, reverse=True):
if all(distance(h.position, x.position) > 300 for x in result):
result.append(h)
检查距离很棘手。
如果结果列表的预期大小很小,则使用该小列表检查每个光环。该算法具有复杂度O(n*log(n) + n * |result set|)
。
如果结果列表的预期大小很大,则space partition可以提供帮助。
像:
result = []
sp = SpacePartition() # Some space partition
for h in sorted(halos, key=lambda h: h.mass, reverse=True):
if not sp.has_point_close(h.position, 300):
result.append(h)
sp.add(h.position)
该算法的复杂度为O(n*log(n))
,因为检查和添加到分区是log(n)
。