【发布时间】:2019-02-21 22:40:36
【问题描述】:
应@mypetition 的要求,我正在编辑我的问题,尽管我认为这里的天文学细节并不重要。 我有一个格式的文件:
a e q Q i lasc aper M H dist comment i_f i_h i_free
45.23710 0.1394 38.93105 51.54315 5.0300 19.9336 286.2554 164.9683 8.41 51.3773 warm 0.000 62.000 4.796
46.78620 0.1404 40.21742 53.35498 3.1061 148.9657 192.3009 337.5967 7.37 40.8789 cold 0.000 42.000 2.473
45.79450 0.1230 40.16178 51.42722 8.0695 104.6470 348.5004 32.9457 8.45 41.3089 warm 0.000 47.000 6.451
42.95280 0.0145 42.32998 43.57562 2.9273 126.3988 262.8777 163.4198 7.36 43.5518 cold 0.000 161.000 2.186
总共有 1.6e6 行。这些是轨道元素。我需要计算每对轨道之间的最小轨道相交距离 (MOID),例如第 1 行与第 2 行、第 1 行与第 3 行等等,直到我到达文件末尾。然后,我从第二行开始,走到文件的末尾。然后从第三行开始,再次转到文件末尾等。由于我有 1.6e6 轨道,那将是 ~1e12 轨道对。
我不想在 1 个 cpu 上加载所有这些 1e12 计算并永远等待,所以我打算使用集群并启动多个串行作业。
我需要遍历 1.6e6 元素,我从第一个元素开始并到文件末尾,然后从第二个元素开始并到文件末尾等,直到最后我从 @ 开始987654324@ 并转到T。这些将导致10^12 迭代,我计划将它们拆分为多个作业,每个作业都进行C=10^7 计算,因此我可以在计算机集群上运行它们。
我想出了以下嵌套循环:
for i in range( M, N)
for j in range( i+1, T)
M=1 并根据我将拥有的工作数量而变化。 T=1.6e6 是常量(要迭代的行数)。我想找到索引N,这样操作的总数就是C=10^7。这是我解决问题的方法:
[T-(N+1) + T-(M+1)]*(M-N+1)/2=C - 因为运算的数量只是上面算术级数的总和。所以,我求解二次方程并得到根。这是python代码:
import numpy as np
import math
C=1.0e7 # How many calculations per job do you want?
T=1.6e6 # How many orbits do you have?
M=1 # what is the starting index of outer loop?
# N = end index of outer loop (this is to be calculated!)
P=1
l=0
with open('indx.txt','w') as f:
while P<T:
l=l+1
K=np.roots([-1,2*T,M**2-2*T*(M-1)-2*C])
N=int(round(K[1]))
f.write("%s %s\n" % (P,P+N))
M=K[1]+1
P=P+N+1
但是,保持上述解决方案,更新 M=M+N,我注意到条件 C=10^7 不满足。这是前几个索引的列表。
M N
1 7
8 21
22 41
42 67
68 99
100 138
139 183
184 234
235 291
....
....
1583930 1588385
1588386 1592847
1592848 1597316
1597317 1601791
但是,如果您查看最后一对之前的对,i=1592848 - 1597316 和 j=i+1, T 上的循环将产生比 C=10^7 更多的计算,即大致为 (2685+7153)*4468/2 ~ 2.2e7。
关于如何解决这个问题的任何想法,保持 C=1e7 不变,这将提供我需要运行的作业数量(具有相似的运行时间)以迭代 1.6e6 行。
希望根据@mypetition 标准,这个解释就足够了,我希望能解决问题。
我们将非常感谢您的帮助!
【问题讨论】:
-
您能否尝试重新表述您面临的问题?不太清楚你在问什么。
-
用您的说明编辑您的问题。请勿将其发布在 cmets 中。
标签: python while-loop indices