【问题标题】:MATLAB histogram displays extra valuesMATLAB 直方图显示额外的值
【发布时间】:2012-06-08 04:29:09
【问题描述】:

我需要在掷两个骰子时产生 7 的总和之前生成掷骰数的概率直方图。实验正常运行,通过 10,000 次迭代,我得到的数据看起来与您预期的一样。然而,我在直方图中显示这些数据时遇到了很多麻烦。问题是有大量额外数据似乎打印到直方图上,而这些数据在我传递给hist() 的向量中不存在。这在 x 轴上显示为大量无限大的 bin。

由于掷出 7 的总和的概率是 6/36 = 1/6,因此这通常发生在前几次掷出的其中之一上。这里我有一个行向量“rollbins”,其中第 i 个条目保存需要“i”个滚动的实验的频率。经过多次实验迭代后,rollbins 的前几个元素较大,随后的每个元素都较小,直到第 45 个元素通常为零。

我使用了带有 bins 向量参数的 hist() 函数,并且根据 this 问题,我使用了 xlim() 将 x 轴上的显示限制为仅 0-45。但是输出不受xlim()的限制。

非常感谢任何帮助:)

iters = 1000;
% do not consider extreme results
maxrolls = 45;
% rollbins(i) is how many experiments occured with i rolls
rollbins = zeros(1, maxrolls);

for r=1 : 1 : iters
    % roll die until get sum of 7, note times taken
    sum = 0;
    % the amount of rolls the experiment takes
    rolls = 0;
    while sum ~= 7
        rolls = rolls + 1;
        % sum two rolls of a die (same as one roll two dies)
        sum = floor( 6*rand(1) + 1 ) + floor( 6*rand(1) + 1 );
    end

    % assign if within the vector's limits; discards outliers
    if rolls < maxrolls
        rollbins(rolls) = rollbins(rolls) + 1;
    end
end

% 1,2,3...45
range = 1:1:maxrolls;
% limit the values on x-axis to 0-45
xlim([0 maxrolls]);
% the histogram shows more than 45 vertical bars
hist(rollbins, range)

编辑:xlim() 调用应该在 hist() 函数之后。去掉最后一个图形函数的分号 (ylim) 可以实现这些效果。

hist(rollbins, range);
xlim([0 maxrolls-1]);
ylim([0 iters / 5])

但是我现在意识到,条形仍然太短,并且 bin 以 0.1 的间隔出现,而不是我预期的 1。

【问题讨论】:

  • 顺便说一句,你不应该使用sumrange作为变量名,它只会在未来引起头痛......

标签: matlab probability histogram


【解决方案1】:

这是我最终得到的解决方案(我还不太熟悉矢量化)

iters = 10000;
% preallocation of experiments row vector, one element for every experiment
experiments = zeros(1,iters);
for i=1 : 1 : iters
    % roll die until get sum of 7, note times taken
    sum = 0;
    rolls = 0;
    while sum ~= 7
        rolls = rolls + 1;
        sum = floor(6*rand(1)+1) + floor(6*rand(1)+1);
    end

    % save the number of rolls this experiment took
    experiments(i) = rolls;
end

% do not plot experiments that took more than 50 rolls
bins = 0:1:50;
hist(experiments, bins);
xlim([0 50]);
ylim([0 1750])

【讨论】:

    【解决方案2】:

    以下是我将如何实现此模拟:

    iters = 1000;               %# number of times to run simulation
    maxrolls = 45;              %# max number of rolls to consider
    numRolls = nan(iters,1);    %# store number of rolls in each run
    for r=1:iters
        %# rolls dice "maxrolls"-times, and compute the sums
        diceSums = sum(randi([1 6],[maxrolls 2]), 2);
    
        %# find the first occurence of a sum of 7
        ind = find(diceSums==7, 1, 'first');
    
        %# record it if found (otherwise noted as NaN)
        if ~isempty(ind)
            numRolls(r) = ind;
        end
    end
    
    %# compute frequency of number of rolls, and show histogram
    counts = histc(numRolls, 1:maxrolls);
    bar(1:maxrolls, counts, 'histc'), grid on
    xlabel('Number of dice rolls to get a sum of 7')
    ylabel('Frequency')
    xlim([1 maxrolls])
    

    如果您觉得有点冒险,这里是大循环的完全矢量化版本:

    numRolls = cellfun(@(v) find(v,1,'first'), ...
        num2cell(sum(randi([1 6],[iters maxrolls 2]),3) == 7, 2), ...
        'UniformOutput',false);
    numRolls(cellfun(@isempty,numRolls)) = {NaN};
    numRolls = cell2mat(numRolls);
    

    【讨论】:

      【解决方案3】:

      您正在记录滚动计数的频率,但您应该只记录滚动计数本身,然后让 hist 在直方图中显示频率。

      此外,您需要在生成直方图后(而不是之前)应用 xlim。

      rollbins = zeros(1, maxrolls);
      numberofrolls = [];   % Initialise numberofrolls
      

      if rolls < maxrolls
          rollbins(rolls) = rollbins(rolls) + 1;
          numberofrolls (end+1) = rolls;  % Record # of rolls
      end
      

      hist(numberofrolls);    % Generate histogram
      

      【讨论】:

      • 所以我需要一个 10000 x 1 行向量,而不是每个单独实验的结果?
      • 是的。我已经用所需的代码更新了我的答案(可以提高效率)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-08-07
      • 2013-01-18
      • 2021-11-02
      • 1970-01-01
      • 2013-07-25
      • 2018-06-10
      相关资源
      最近更新 更多