那里。 我将在matlab中使用此特定字符生成10 ^ 6个随机点。 这些点应该在一个25级的球体里面,它们是3-D所以我们有x,y,z或r,theta,phi。 每个点之间的距离最小。 首先,我决定生成点,然后检查距离,然后省略没有这些条件的点。但是,它可能会省略许多要点。 另一种方法是使用RSA(随机顺序加法),它意味着它们之间的最小距离逐一产生点。例如,生成第一个点,然后从点1的最小距离中随机生成第二个点,并继续直到达到10 ^ 6个点。 但是需要很多时间才能达到10 ^ 6分,因为为新点搜索合适位置的速度需要很长时间。
现在我正在使用这个程序:
Nmax=10000;
R=25;
P=rand(1,3);
k=1;
while k<Nmax
theta=2*pi*rand(1);
phi=pi*rand(1);
r = R*sqrt(rand(1));
% convert to cartesian
x=r.*sin(theta).*cos(phi);
y=r.*sin(theta).*sin(phi);
z=r.*cos(theta);
P1=[x y z];
r=sqrt((x-0)^2+(y-0)^2+(z-0)^2);
D = pdist2(P1,P,'euclidean');
% euclidean distance
if D>0.146*r^(2/3)
P=[P;P1];
k=k+1;
end
i=i+1;
end
x=P(:,1);y=P(:,2);z=P(:,3); plot3(x,y,z,'.');
如何通过这些条件有效地生成积分? 谢谢。
答案 0 :(得分:4)
我仔细研究了你的算法,并得出结论,没有任何方法可以工作 - 至少如果你真的想在这个领域获得一百万分的话。有一个简单的图片解释了为什么不 - 这是你需要测试的点数(使用你的RSA技术)来获得一个额外的“好”点。正如你所看到的,这只是几千点的渐近(我运行了一个稍快的算法,反对200k点来产生这个):
我不知道你是否曾经尝试计算你的球体中可以适合的理论点数,但是我已经开始怀疑这个数字比1E6小得多。< / p>
我可以找到用于调查此问题的完整代码及其生成的输出here。我从来没有达到我在之前的答案中所描述的技术......在你描述的设置中还有太多的其他事情。
编辑: 我开始认为,即使采用“完美”安排,也可能无法达到1M点。我为自己制作了一个简单的模型如下:
想象一下,你从“外壳”开始(r = 25),并尝试以相等的距离拟合点。如果将“shell”的面积除以一个“排除磁盘”(半径为r_sub_crit)的区域,则可以得到该位置点数的(高)估计值:
numpoints = 4*pi*r^2 / (pi*(0.146 * r^(2/3))^2) ~ 188 * r^(2/3)
下一个“shell”应该在半径为0.146 * r ^(2/3)的范围内 - 但是如果你认为这些点是非常仔细的排列,你可能会更接近一点点。再说一遍,让我们慷慨,并说贝壳可以比标准更接近1 / sqrt(3)。然后,您可以使用一个简单的python脚本从外壳启动并继续工作:
import scipy as sc
r = 25
npts = 0
def rc(r):
return 0.146*sc.power(r, 2./3.)
while (r > rc(r)):
morePts = sc.floor(4/(0.146*0.146)*sc.power(r, 2./3.))
npts = npts + morePts
print morePts, ' more points at r = ', r
r = r - rc(r)/sc.sqrt(3)
print 'total number of points fitted in sphere: ', npts
这个输出是:
1604.0 more points at r = 25
1573.0 more points at r = 24.2793037966
1542.0 more points at r = 23.5725257555
1512.0 more points at r = 22.8795314897
1482.0 more points at r = 22.2001865995
1452.0 more points at r = 21.5343566722
1422.0 more points at r = 20.8819072818
1393.0 more points at r = 20.2427039885
1364.0 more points at r = 19.6166123391
1336.0 more points at r = 19.0034978659
1308.0 more points at r = 18.4032260869
1280.0 more points at r = 17.8156625053
1252.0 more points at r = 17.2406726094
1224.0 more points at r = 16.6781218719
1197.0 more points at r = 16.1278757499
1171.0 more points at r = 15.5897996844
1144.0 more points at r = 15.0637590998
1118.0 more points at r = 14.549619404
1092.0 more points at r = 14.0472459873
1066.0 more points at r = 13.5565042228
1041.0 more points at r = 13.0772594652
1016.0 more points at r = 12.6093770509
991.0 more points at r = 12.1527222975
967.0 more points at r = 11.707160503
943.0 more points at r = 11.2725569457
919.0 more points at r = 10.8487768835
896.0 more points at r = 10.4356855535
872.0 more points at r = 10.0331481711
850.0 more points at r = 9.64102993012
827.0 more points at r = 9.25919600154
805.0 more points at r = 8.88751153329
783.0 more points at r = 8.52584164948
761.0 more points at r = 8.17405144976
740.0 more points at r = 7.83200600865
718.0 more points at r = 7.49957037478
698.0 more points at r = 7.17660957023
677.0 more points at r = 6.86298858965
657.0 more points at r = 6.55857239952
637.0 more points at r = 6.26322593726
618.0 more points at r = 5.97681411037
598.0 more points at r = 5.69920179546
579.0 more points at r = 5.43025383729
561.0 more points at r = 5.16983504778
542.0 more points at r = 4.91781020487
524.0 more points at r = 4.67404405146
506.0 more points at r = 4.43840129415
489.0 more points at r = 4.21074660206
472.0 more points at r = 3.9909446055
455.0 more points at r = 3.77885989456
438.0 more points at r = 3.57435701766
422.0 more points at r = 3.37730048004
406.0 more points at r = 3.1875547421
390.0 more points at r = 3.00498421767
375.0 more points at r = 2.82945327223
360.0 more points at r = 2.66082622092
345.0 more points at r = 2.49896732654
331.0 more points at r = 2.34374079733
316.0 more points at r = 2.19501078464
303.0 more points at r = 2.05264138052
289.0 more points at r = 1.91649661498
276.0 more points at r = 1.78644045325
263.0 more points at r = 1.66233679273
250.0 more points at r = 1.54404945973
238.0 more points at r = 1.43144220603
226.0 more points at r = 1.32437870508
214.0 more points at r = 1.22272254805
203.0 more points at r = 1.1263372394
192.0 more points at r = 1.03508619218
181.0 more points at r = 0.94883272297
170.0 more points at r = 0.867440046252
160.0 more points at r = 0.790771268402
150.0 more points at r = 0.718689381062
140.0 more points at r = 0.65105725389
131.0 more points at r = 0.587737626612
122.0 more points at r = 0.528593100237
113.0 more points at r = 0.473486127367
105.0 more points at r = 0.422279001431
97.0 more points at r = 0.374833844693
89.0 more points at r = 0.331012594847
82.0 more points at r = 0.290676989951
75.0 more points at r = 0.253688551418
68.0 more points at r = 0.219908564725
61.0 more points at r = 0.189198057381
55.0 more points at r = 0.161417773651
49.0 more points at r = 0.136428145311
44.0 more points at r = 0.114089257597
38.0 more points at r = 0.0942608092113
33.0 more points at r = 0.0768020649149
29.0 more points at r = 0.0615717987589
24.0 more points at r = 0.0484282253244
20.0 more points at r = 0.0372289153633
17.0 more points at r = 0.0278306908104
13.0 more points at r = 0.0200894920319
10.0 more points at r = 0.013860207063
8.0 more points at r = 0.00899644813842
5.0 more points at r = 0.00535025545232
total number of points fitted in sphere: 55600.0
这似乎证实,无论你如何尝试,你真的无法达到一百万......
答案 1 :(得分:3)
你可以做很多事情来改进你的程序 - 包括算法和代码。
在代码方面,真正让你慢下来的事情之一就是不仅你使用for
循环(这很慢),而且在行中
P = [P;P1];
将元素追加到数组中。每次发生这种情况时,Matlab都需要找到一个新的位置来放置数据,复制过程中的所有点。这很快变得很慢。使用
预先分配数组P = zeros(1000000, 3);
跟踪到目前为止找到的点数N,并将距离计算更改为
D = pdist2(P1, P(1:N, :), 'euclidean');
至少会解决这个问题......
另一个问题是你针对所有先前找到的点检查新点数 - 所以当你得到100分时,检查大约100x100,1000为1000x1000。你可以看到这个算法至少是O(N ^ 3)......不计算随着密度的增加你会得到更多的“未命中”这一事实。 N = 10E6的O(N ^ 3)算法至少需要10E18个周期;如果你有一台4 GHz机器,每次比较一个时钟周期,你需要2.5E9秒=大约80年。您可以尝试并行处理,但这只是蛮力 - 谁想要这个?
我建议您考虑将问题分解成更小的部分(非常简单):例如,如果将球体划分为大小与最大距离相近的小盒子,并且对于每个盒子,您可以跟踪什么分数在其中,那么你只需要检查“这个”框中的点及其直接邻居 - 总共27个盒子。如果你的盒子是2.5毫米,你将有100x100x100 = 1M盒子。这似乎很多,但现在你的计算时间将大大减少,因为你将(在算法结束时)每盒平均只有1点......当然,根据您使用的距离标准,你将在中心附近有更多的点,但这是一个细节。
您需要的数据结构是100x100x100的单元格数组,每个单元格包含到目前为止“在该单元格中”找到的优点的索引。单元阵列的问题在于它不适合矢量化。如果你有内存,你可以将它分配为10x100x100x100的4D数组,假设每个单元不超过10个点(如果你这样做,你将不得不单独处理它;在这里与我合作......) 。对尚未找到的点使用-1
的索引
然后你的检查会是这样的:
% initializing:
bigList = zeros(10,102,102,102)-1; % avoid hitting the edge...
NPlist = zeros(102, 102, 102); % track # valid points in each box
bottomcorner = [-25.5, -25.5, -25.5]; % boxes span from -25.5 to +25.5
cellSize = 0.5;
% in your loop:
P1= [x, y, z];
cellCoords = ceil(P1/cellSize);
goodFlag = true;
pointsSoFar = bigList(:, cellCoords(1)+(-1:1), cellCoords(2)+(-1:1), cellCoords(3)+(-1:1));
pointsToCheck = find(pointsSoFar>0); % this is where the big gains come...
r=sum(P1.^2);
D = pdist2(P1,P(pointsToCheck, :),'euclidean'); % euclidean distance
if D>0.146*r^(2/3)
P(k,:) = P1;
% check the syntax of this line...
cci = ind2sub([102 102 102], cellCoords(1), cellCoords(2), cellCoords(3));
NP(cci)=NP(cci)+1; % increasing number of points in this box
% you want to handle the case where this > 10!!!
bigList(NP(cci), cci) = k;
k=k+1;
end
....
我不知道你是否可以从这里拿走它;如果你不能,请在笔记中这样说,我本周末可能会有一些时间更详细地编写代码。有一些方法可以通过一些矢量化来加快速度,但很快就会变得难以管理。
我认为在太空中随机放置更多的点,然后使用上面的方法进行巨型矢量化剔除,可能就是这样。但我建议先采取一些措施......如果你能够完成上述工作,那么你可以进一步优化(数组大小等)。
答案 2 :(得分:2)
我发现the reference - “使用三维细胞自动机模拟脑肿瘤生长动力学”,Ansal等(2000)。
我同意这是令人费解的 - 直到你意识到一件重要的事情。他们在mm
报告了结果,但您的代码是用cm
编写的。虽然这似乎无关紧要,但“临界半径”的公式rc = 0.146r^(2/3)
包含一个常数0.146
,即维度 - 维度为mm^(1/3)
,而不是cm^(1/3)
。< / p>
当我在我的python代码中进行更改以评估可能的网格站点的数量时,它会跳过10倍。现在他们声称他们使用了0.38的“干扰限制” - 你真正找不到的数字更多网站。如果你包括那个限制,我预计可以找到不超过200k点 - 仍然不及他们的1.5M,但不是那么疯狂。
您可以考虑与作者联系,与他们讨论这个问题吗?如果您想将我加入对话,您可以发送电子邮件至:my handle name
点united states
处的SO(仅两个字母)。与我在上面发布链接的域名相同...