使用随机步骤定义一个向量。

6

我想创建一个具有递增随机步骤的数组,我使用了这个简单的代码。

t_inici=(0:10*rand:100);

问题是随机数在步骤之间保持不变。有没有简单的方法在每个步骤中更改随机数的种子?

2
有趣的问题,但你的尝试显示出了很少的理解。你正在创建一个线性间隔向量,其步长是恒定的随机值。你的限制是什么?是否有最大/最小步长?最大/最小样本数?通过给定固定值的起始和停止点,你已经在限制你的随机性了。 - Ander Biguri
1
这是一个更高维度的泛化... https://www.mathworks.com/matlabcentral/fileexchange/50480-continuous-sampling-in-an-interval--linearly--randomly-and-from-the-simplex - bla
4个回答

5
如果你有一个固定数量的点,比如说nPts,那么你可以按照以下方式操作。
nPts = 10;         % Could use 'randi' here for random number of points
lims = [0, 10]     % Start and end points
x = rand(1, nPts); % Create random numbers  
% Sort and scale x to fit your limits and be ordered 
x = diff(lims) * ( sort(x) - min(x) ) / diff(minmax(x)) + lims(1) 

这种方法总是包括您的终点,而0:dx:10的方法则不一定包括。


如果您有一些最大点数限制,比如nPtsMax,那么您可以执行以下操作:

nPtsMax = 1000;      % Max number of points
lims = [0,10];       % Start and end points
% Could do 10* or any other multiplier as in your example in front of 'rand'
x = lims(1) + [0 cumsum(rand(1, nPtsMax))];     
x(x > lims(2)) = []; % remove values above maximum limit

这种方法可能会慢一些,但仍然相当快,并更好地代表了您问题中的行为。


比我的好,把随机点移动到所需的角落比添加更有意义。 - Ander Biguri
1
我认为应该让它更随机一些?这意味着你不能在一行中调用它,因为x需要在多个地方使用,所以必须预先定义。我实际上认为我的更新的cumsum版本甚至更好,似乎更能反映出所期望的行为... - Wolfie

3
我的第一种方法是生成N-2个样本,其中N是所需的随机样本数量,将它们排序,然后添加极值。
N=50;
endpoint=100;
initpoint=0;
randsamples=sort(rand(1, N-2)*(endpoint-initpoint)+initpoint);
t_inici=[initpoint randsamples endpoint];

然而我不确定这样做是否真正是“均匀随机”的,因为你在“伪造”最后2个数据,以包括极值。这将在某种程度上扭曲纯随机性(我想)。如果您不一定要包含极值,那么只需删除最后一行并生成N个点即可。这将确保它们确实是随机的(或者尽可能接近MATLAB可以创建的随机数)。


3
这里提供一种“均匀随机”的替代方案。
[initpoint,endpoint,coef]=deal(0,100,10);
t_inici(1)=initpoint;
while(t_inici(end)<endpoint)
  t_inici(end+1)=t_inici(end)+rand()*coef;
end
t_inici(end)=[];

从我的角度来看,这与你的尝试很相符。虽然步骤不确定,但可以从0开始,并且不一定要以100结束。

谢谢,我没有很好地解释我需要实现什么,但这是更适合的,因为我不想设置步数。也感谢所有其他答案。 - Joan
很高兴能够帮助,我的荣幸。@Joan - Hunter Jiang

2
从你的代码看来,似乎你想要一个在每两个条目之间变化的均匀随机步骤。这意味着向量将拥有的条目数量事先是未知的。
一种实现方法如下所示。这类似于Hunter Jiang's answer,但是批量添加条目而不是逐个添加,以减少循环迭代次数。
  1. 猜测所需的条目数n。任何值都可以,但大的值会导致更少的迭代次数,可能更有效。
  2. 将结果初始化为第一个值。
  3. 生成n个条目并将它们连接到(临时)结果中。
  4. 查看当前的条目是否已经太多了。
  5. 如果是,则按需要剪切并输出(最终)结果。否则返回步骤3。

代码:

lower_value = 0;
upper_value = 100;
step_scale = 10;
n = 5*(upper_value-lower_value)/step_scale*2; % STEP 1. The number 5 here is arbitrary.
% It's probably more efficient to err with too many than with too few
result = lower_value; % STEP 2
done = false;
while ~done
    result = [result result(end)+cumsum(step_scale*rand(1,n))]; % STEP 3. Include
    % n new entries
    ind_final = find(result>upper_value,1)-1; % STEP 4. Index of first entry exceeding
    % upper_value, if any
    if ind_final % STEP 5. If non-empty, we're done
        result = result(1:ind_final-1);
        done = true;
    end
end

谢谢,这是另一个有趣的答案,可以减少执行时间。 - Joan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接