【发布时间】:2018-03-27 13:22:41
【问题描述】:
我正面临一个问题,我在微积分时间和约束之间陷入困境......
- 简单案例:
我在 3D 网格上有点均匀分布的点网格(第一张图片)。
注意:您在那里看不到它,但有一个垂直于网格的第三轴 - 有 125 个点(每边 5 x 5 x 5)
3D grid with dots distributed ~ equally
我的目标是,采用噪声统计数据给出的距离(在这种情况下我们将采用 0.03),用这些条件填充网格:
- 点是随机生成的,并通过距离条件测试发送,这将决定它是否保留它
- 距离条件:如果一个点与其他点的距离为 0.03 +/- 10%,则可以将其放入网格中,否则将其移除。
这是一个填充网格的示例:
Badly filled grid (still in 3D)
问题是,这里有很多我想删除的空白。
更多细节,这里是从一个点到它最近的邻居的所有距离图:
Histogram of distances from dots their closest neighbour
红色矩形是我希望所有蓝色条堆叠的位置,在这种情况下,介于 0.03 - 10% 和 0.03 + 10% 之间。
主要问题是,因为它是随机生成的,所以我必须生成很多点才能希望即使只有一个也能符合约束条件。这是一个相对“简单的案例”,因为之后,我将不得不将其应用于:
-
硬盒:
- 点分布不均成超过10个轴
- 点数最多 1000 个或更多
我不是 python 专家,我只知道基础知识(numpy、matplotlib.pyplot),并且对图表、数组、循环非常熟悉,但是我的代码在计算时间方面并未针对这些进行优化任务类型:
- 生成一个点
- 它与点的距离是针对每个其他点计算的(我不知道还能做些什么来防止扫描整个列表..)
- 如果一个点距离前一个点更近,则成为“最近的一个”
- 如果与“最近的”的距离在约束中,则不会删除。
如果有人有一个简单的想法或一些建议,那就太好了,我也希望我能解释清楚(我尽量只保留最重要的东西,并尝试用正确的英文写:))。
感谢阅读,
内森。
编辑:这里简化了代码,因为它可能有助于更轻松地回答! 我直接添加了非均布网格(A,B)。
import numpy as np
import matplotlib.pyplot as plt
plt.close("all")
A = np.random.rand(100)
B = np.random.rand(100)
plt.figure()
plt.plot(A, B,".")
plt.grid()
Nfillers = 10000
SNRD = 0.03
for i in range(Nfillers):
a, b = np.random.rand(2)
A = np.hstack((A, np.atleast_1d(a)))
B = np.hstack((B, np.atleast_1d(b)))
DCN = 1E+308 # Distance Closest Neighbor
for j in range(len(A)): # len(A) is updated with each iteration
D1 = A[j] - a
D2 = B[j] - a
distance = np.sqrt(D1**2 + D2**2)
if distance != 0:
if distance < DCN:
DCN = distance
if DCN < 0.9*SNRD or DCN > 1.1*SNRD:
A = np.delete(A, len(A)-1)
B = np.delete(B, len(B)-1)
print i
plt.figure()
plt.plot(A, B, ".")
plt.grid()
编辑 2:更快的代码:
import numpy as np
import matplotlib.pyplot as plt
A = np.random.rand(100)
B = np.random.rand(100)
plt.figure()
plt.plot(A, B,".")
plt.grid()
Nfillers = 100000
SNRD = 0.03
for i in range(Nfillers):
a, b = np.random.rand(2)
DCN = np.min(np.sqrt((A - a)**2 + (B - b)**2))
if DCN > 0.9*SNRD and DCN < 1.1*SNRD:
A = np.hstack((A, np.atleast_1d(a)))
B = np.hstack((B, np.atleast_1d(b)))
print(i)
plt.figure()
plt.plot(A, B, ".")
plt.grid()
【问题讨论】:
-
很好的问题,很有趣。但是缺少一件事,代码!无论如何,你是如何随机生成点的?我想这是一个正态分布,所以只需更改平均值以在您需要的区域中有更多点。对于距离计算,如果你想真正加快计算速度,不要在列表上循环,而是计算一个 numpy ndarray 的距离。没有代码真的无法提供更多建议。
-
我不完全理解的是,您希望这些点是随机的,但彼此之间有一定的距离。所以我要做的就是:生成一个随机点,然后在给定距离内生成下一个随机点等。你这样做 1000 次,瞧,在给定距离内到其最近邻居的 1000 个半随机点。
-
感谢您的想法,对于循环提示,然后我将尝试使用 ndarrays 来完成(我从来没有真正了解哪种方式在计算速度方面更快。对于“半随机“提示,它可能在这里适用,但我想翻译到我的代码的第一层,因为:1] 生成 3 个随机数 2] 它们被组合以创建一个样本 3] 样本被投影到基础中。它可能会工作:) 好主意!
标签: python optimization grid distance