【问题标题】:Building array from conditions on another array从另一个数组上的条件构建数组
【发布时间】:2013-10-24 21:53:08
【问题描述】:

我是 matlab 新手。我想做以下事情:

  • 在三个备选方案 A、B 和 C 之间生成一个包含一千次随机抽签的数组,其中在每次抽签时,每个备选方案都有相同的被选中概率。

所以最终我需要像 P = [ A A B C B B B C A C A C C ... ] 之类的东西,其中数组中的每个元素都是在三个可能的结果中随机选择的。

我想出了一个解决方案,这正是我想要的,即

% Generating random pick among doors 1,2,3, where 1 stands for A, 2 for B,
% 3 for B.

I = rand(1);

if I < 1/3
    PP = 1;
elseif 1/3 <= I & I < 2/3
    PP = 2;
else 
    PP = 3;
end 

% Generating a thousand random picks among dors A,B,C

I = rand(999);

for i=1:999    
if I(i) < 1/3
    P = 1;
elseif 1/3 <= I(i) & I(i) < 2/3
    P = 2;
else 
    P = 3;
end 
PP = [PP  P]
end

正如我所说,它可以工作,但是当我运行该程序时,我认为这是一项简单的任务需要一段时间。同时,我长这样一个任务是“应该”在matlab中承担的。所以我有三个问题:

  1. 这真的是一个缓慢的过程来产生预期的结果吗?
  2. 如果是,为什么这个过程特别慢?
  3. 产生预期结果的更有效方法是什么?

【问题讨论】:

  • 不确定我完全理解你在做什么,但听起来你可以制作一个数组并使用array(i)=randi(3) 来获得你想要的东西。 randi(x) 应该在区间 [0,x) 上给你一个随机整数(Bas Swinckels 打败了我。看看他的答案)

标签: arrays matlab if-statement for-loop


【解决方案1】:

使用randi 可以更轻松地完成此操作

>> PP = randi(3,1,10)
PP =
     2     1     3     3     2     2     2     3     2     1

如果您真的想在 3 个选项之间进行选择,您可以直接使用 randi 的输出来索引另一个矩阵。

>> options = [13,22,77]
options =
    13    22    77
>> options(randi(3,1,10))
ans =
    22    13    77    13    77    13    22    22    77    13

至于你的解决方案慢的原因,你做类似这样的事情:

x = [];
for i=1:10
    x = [x i^2]; %size of x grows on every iteration
end

这不是很好,因为在每次迭代中,Matlab 都需要为更大的向量 x 分配空间。在旧版本的 Matlab 中,这会导致二次行为(如果将问题的大小加倍,则需要 4 倍的时间)。在较新的版本中,Matlab 足够聪明,可以避免这个问题。但是,如果您事先知道数组有多大,预分配空间仍然被认为是好的:

x = zeros(1,10); % space for x is preallocated. can also use nan() or ones()
for i = 1:length(x)
    x(i) = i^2;
end

但在许多情况下,使用不使用任何 for 循环的 矢量化 代码会更快:

x = (1:10).^2;

所有 3 种解决方案都给出相同的结果:

x =    1     4     9    16    25    36    49    64    81   100

【讨论】:

  • 很高兴了解空间预分配和randi。兰迪肯定更容易。就计算时间而言,一旦预先分配了空间,我提出的过程的变体也能很好地完成工作:% Generating 1000 random pick among doors 1,2,3, where 1 stands for A, 2 for B, 3 for B % P = zeros(1,1000); I = rand(1000); for i=1:1000 if I(i) &lt; 1/3 P(i) = 1; elseif 1/3 &lt;= I(i) &amp; I(i) &lt; 2/3 P(i) = 2; else P(i) = 3; end end
  • 其矢量化版本为:I = rand(1,1000); P = ones(1,1000); P(1/3 &lt;= I &amp; I &lt; 2/3) = 2; P(I &gt;= 2/3) = 3;
【解决方案2】:
cnt=10;
option={'a','b','c'}
x=option([randi(numel(option),cnt,1)])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-11
    • 2023-02-21
    • 1970-01-01
    • 2012-12-16
    • 2017-05-06
    • 2013-08-21
    • 2021-06-24
    • 1970-01-01
    相关资源
    最近更新 更多