此问题可能不需要并行化:
# Generate a random array of appropriate size for testing
super_array = [[[None for _ in range(30)] for _ in range(529)] for _ in range(529)]
for _ in range(3500):
super_array[random.randint(0, 528)][random.randint(0, 528)][random.randint(0,29)] = random.randint(-65, -45)
第一步是构建填充节点的列表:
filled = []
for x in range(len(super_array)):
for y in range(len(super_array[0])):
for z in range(len(super_array[0][0])):
if super_array[x][y][z] is not None:
filled.append((x, y, z, super_array[x][y][z]))
然后,将列表从高到低排序:
sfill = sorted(filled, key=lambda x: x[3], reverse=True)
现在,生成一个阻塞网格:
block_array = [[None for _ in range(529)] for _ in range(529)]
并遍历该列表,在查找节点时封锁邻居并删除已占用邻居中的节点:
for node in sfill:
x, y, z, _ = node
if block_array[x][y] is not None:
super_array[x][y][z] = None # kill node if it's in the neighborhood of a larger node
else: # Block their neighborhood
for dx in range(5):
for dy in range(5):
cx = x + dx - 2
cy = y + dy - 2
if 529 > cx >= 0 and 529 > cy >= 0:
block_array[cx][cy] = True
一些注意事项:
-
这将使用滑动邻域,因此它将检查以每个节点为中心的5x5。从高到低进行检查很重要,因为这样可以确保移除的节点之前不会强制移除其他节点。
-
通过执行ranges而不是完整的529x529数组,您可以更高效地执行此操作,但邻域阻塞只需不到一秒钟的时间,从生成的数组到修剪的最终列表的整个过程只需1.2秒。
-
只需在任何
z
堆栈如果大量节点最终具有相同的x,y值,这将减少必须排序的列表的大小。
在23x23x30上,大约需要18ms,同样包括构建3d阵列的时间:
timeit.timeit(prune_test, number=1000)
17.61786985397339