【发布时间】:2016-04-22 08:10:07
【问题描述】:
假设我们有一个带有离散点的 3D 网格。 3 个维度(包括区间端点)的范围是:
在 x 中:[4000, 7000],在 y 中步长 1000:[0.0, 2.0],在 z 中步长 1.0:[-0.75, 0.75],步长 0.25
现在应该对 [4000, 7000, 100], [0.0, 2.0, 0.1], [-0.75, 0.75, 0.05] 范围内的所有点完成以下任务(大约 20000 = 31 * 21 * 31 点):
找到包含该点的最小长方体。然而,网格中有孔(每个点都应该有一个“物理”对应的文件,但有些没有)。我尝试了以下非常简单的代码(我将长方体称为“立方体”):
def findcubesnew(startvalues, endvalues, resols, \
loopvalues, refvalues, modelpath):
cubearray = []
startvalue1 = startvalues[0]
endvalue1 = endvalues[0]
resol1 = resols[0]
refvalue1 = refvalues[0]
loopstop1 = loopvalues[0][0]
loopstart1 = loopvalues[1][0]
startvalue2 = startvalues[1]
endvalue2 = endvalues[1]
resol2 = resols[1]
refvalue2 = refvalues[1]
loopstop2 = loopvalues[0][1]
loopstart2 = loopvalues[1][1]
startvalue3 = startvalues[2]
endvalue3 = endvalues[2]
resol3 = resols[2]
refvalue3 = refvalues[2]
loopstop3 = loopvalues[0][2]
loopstart3 = loopvalues[1][2]
refmass = refvalues[3]
refveloc = refvalues[4]
for start1 in numpy.arange(startvalue1, loopstop1 + resol1, resol1):
for end1 in numpy.arange(loopstart1, endvalue1 + resol1, resol1):
for start2 in numpy.arange(startvalue2, loopstop2 + resol2, resol2):
for end2 in numpy.arange(loopstart2, endvalue2 + resol2, resol2):
for start3 in numpy.arange(startvalue3, loopstop3 + resol3, resol3):
for end3 in numpy.arange(loopstart3, endvalue3 + resol3, resol3):
if glob.glob(*start1*start2*start3) and \
if glob.glob(modelpath/*start1*start2*end3) and \
if glob.glob(modelpath/*start1*end2*start3) and \
if glob.glob(modelpath/*start1*end2*end3) and \
if glob.glob(modelpath/*end1*start2*start3) and \
if glob.glob(modelpath/*end1*start2*end3) and \
if glob.glob(modelpath/*end1*end2*start3) and \
if glob.glob(modelpath/*end1*end2*end3):
cubearray.append((start1, end1, start2, end2, start3, end3))
else:
pass
return cubearray
foundcubearray = findcubesnew([metalstart, tempstart, loggstart], \
[metalend, tempend, loggend], [metalresol, tempresol, loggresol], \
looplimitarray, [refmetal, reftemp, reflogg, refmass, refveloc], \
modelpath)
if foundcubearray:
bestcube = findsmallestcubenew(foundcubearray, \
[metalresol, tempresol, loggresol])
....
因此,我在 x 方向上从较低的网格边界到我们想要获取长方体的所需点下方的最大值进行循环,并在另一个循环中从该点之后的最小值到较高的网格边界。类似地,对于 y 方向和 z 方向,循环彼此嵌套。 if 部分是没有格式字符串等的伪代码,并检查具有这些值的所有文件(文件名中可能还有其他数量)确实存在(长方体的所有角都存在)。
如果点的一个或多个坐标与我们网格中的值重合,此代码还会找到点、线或矩形,但这不是问题(并且实际上是需要的)。
这里的瓶颈是搜索长方体需要相当长的时间(然后可以轻松快速地找到最小的长方体,如果有多个相同(最小)大小的长方体,我不在乎选择哪一个)。我还需要读取网格的开始值和结束值、步长、我的点的参考值(坐标)和其他一些变量。有什么办法可以优化代码?每点大约需要 1.4 秒,所以 ~ 20000 点需要 8 小时,这太长了。
我知道如果我找到最小的长方体,例如对于点 4500, 0.5, 0.1,我可以立即看出立方体内的所有其他点的限制为 [4000, 5000; 0.0, 1.0; 0, 0.25] 具有相同的最小长方体。我仍然对优化所有 20000 次运行的计算时间的解决方案感兴趣。它的应用是恒星模型的插值程序,其中需要在插值点周围有 8 个长方体形状的网格点。
P.S.:我希望续行换行和缩进是正确的。在我的代码中它们不存在,尽管每行超过 80 个字符并不是一种好的风格:)。
【问题讨论】:
标签: python for-loop optimization