Matlab生成随机数和重叠检查

时间:2018-12-16 18:34:23

标签: matlab random

我编写了一个代码,用于在指定域内的Matlab上生成随机数量的棒,然后将输出保存在文本文件中。我想寻求有关在代码中添加以下选项的帮助; (i)如果随机产生的棒超过了规定的区域尺寸,则应缩短该棒的长度,以使其保持在该特定区域内。 (ii)我想避免新生成的编号(棒)与前一个编号重叠,如果出现重叠,请为新棒生成另一个位置。

我不知道该怎么办。如果有人可以帮助我为这两个选项编写代码,那将有很大帮助。 谢谢

% myrandom.m  
% Units are mm.

% domain size
bx = 160;
by = 40;
bz = 40;

lf = 12; % rod length
nf = 500; % Number of rods

rns = rand(nf,3);      % Start
rne = rand(nf,3)-0.5;  % End

% Start Points
for i = 1:nf
    rns(i,1) = rns(i,1)*bx;
    rns(i,2) = rns(i,2)*by;
    rns(i,3) = rns(i,3)*bz;
end

% Unit Deltas
delta = zeros(nf,1);
for i = 1:nf
   temp = rne(i,:);
   delta(i) = norm(temp);
end

% Length Deltas
rne = lf*rne./delta;

% End Points
rne = rns + rne;


fileID = fopen('scfibers.txt','w');
for i = 1:nf
    fprintf(fileID,'%12.8f %12.8f %12.8f\r\n',rns(i,1),rns(i,2),rns(i,3));
    fprintf(fileID,'%12.8f %12.8f %12.8f\r\n\r\n',rne(i,1),rne(i,2),rne(i,3));
end
fclose(fileID);

1 个答案:

答案 0 :(得分:2)

我将从编写创建随机棒的函数开始:

function [rns,rne] = myrandom(domain,len,N)

rns = rand(N,3).*domain; % Start  --> rns = bsxfun(@times,rand(N,3),domain)
rne = rand(N,3)-0.5;  % End

% Unit Deltas
delta = zeros(N,1);
for k = 1:N
  delta(k) = norm(rne(k,:));
end

% Length Deltas
rne = len*rne./delta; % --> rne = len*bsxfun(@rdivide,rne,delta)

% End Points
rne = rns + rne;

% remove rods the exceed the domain:
notValid = any(rne>domain,2); % --> notValid = any(bsxfun(@gt,rne,domain),2);
rns(notValid,:)=[];
rne(notValid,:)=[];
end

此函数将domain设为[bx by bz],将杆的长度设为len,并将N的杆数生成。请注意,使用逐元素乘法(.*),我消除了第一个for循环。
如果您使用2016b之前的MATLAB版本,则需要使用bsxfun

  

在MATLAB®R2016b和更高版本中,此表中列出的内置二进制函数独立支持隐式扩展。

受影响的行在代码中用-->标记(以及备用行)。

该函数的最后三行从结果中删除所有超出域大小的圆标(我希望我对此有正确的理解)。

接下来,我在脚本中调用此函数:

% domain size
bx = 160;
by = 40;
bz = 40;
domain = [bx by bz];
lf = 12; % rod length
nf = 500; % Number of rods

[rns,rne] = myrandom(domain,lf,nf);
u = unique([rns rne],'rows');
remain = nf-size(u,1);
while remain>0
    [rns_temp,rne_temp] = myrandom(domain,lf,remain);
    rns = [rns;rns_temp];
    rne = [rne;rne_temp];
    u = unique([rns rne],'rows');
    remain = nf-size(u,1);
end

在基本定义之后,该函数将被调用并返回rnerns,它们可能比nf小。然后我们检查重复项,并将所有唯一的棒存储在u中。我们计算要计算的剩余棒,并根据需要使用while循环生成新棒。在循环的每次迭代中,我们将新创建的棒添加到rnerns中的棒中,并检查我们现在有多少个唯一矢量,以及是否有足够的数量退出循环(然后您可以在文件中添加打印内容。

请注意:

  1. 我不确定您的意思是“如果出现重叠,则为新杆生成另一个位置” -如果某些杆,您是否想要多于nf条杆是重复的,nf从那里是唯一的(上面的代码做什么)?还是要删除重复项并仅保留nf个唯一棒?对于后一种选择,我将把unique函数部分插入创建棒myrandom的函数中。

  2. 由于未完成内存的预分配,因此如上所述的wile循环效率不高。如果您只想创建更多标尺但保留重复项,则不确定是否可行(如果不是)(上面1中的第二个选项),并且如果要使用此分配,则强烈建议进行预分配。 / p>