2012-06-04 3 views
0

J'ai besoin de générer un histogramme de probabilité du nombre de rouleaux avant qu'une somme de 7 ne survienne lors du lancement de deux dés. L'expérience fonctionne correctement et à travers 10.000 itérations, j'obtiens des données qui ressemblent à ce que vous attendez. J'ai cependant beaucoup de mal à afficher ces données dans un histogramme. Le problème est qu'il y a une grande quantité de données supplémentaires qui semblent être imprimées sur l'histogramme qui n'est pas présent dans le vecteur que j'ai passé à hist(). Cela apparaît comme une grande quantité de bacs infiniment grands à grandes valeurs sur l'axe des x.L'histogramme MATLAB affiche des valeurs supplémentaires

Puisque la probabilité de rouler une somme de 7 est de 6/36 = 1/6, il est typique que cela se produise sur l'un des premiers rouleaux. Ici, j'ai un vecteur ligne "rollbins", où l'entrée ith détient la fréquence de l'expérience nécessitant des rouleaux "i". Après de nombreuses itérations de l'expérience, rollbins a ses premiers éléments de taille importante, chaque entrée ultérieure étant plus petite jusqu'à ce que la 45ème soit généralement nulle.

J'ai utilisé la fonction hist() avec un argument de vecteur de casiers et par this question J'ai utilisé xlim() pour limiter l'affichage à seulement 0-45 sur l'axe des x. Cependant, la sortie n'est pas limitée avec ou sans xlim().

Toute aide est grandement appréciée :)

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) 

modifier: l'appel xlim() doit venir après la fonction hist(). Laisser le point-virgule de la dernière fonction graphique (ylim) permet à ces effets d'avoir lieu.

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

Cependant je me rends compte maintenant que les barres sont beaucoup trop court encore et les bacs apparaissent à des intervalles de 0,1 pas 1 comme je l'avais prévu.

+0

BTW vous ne devriez pas utiliser '' sum' et range' comme noms de variables, il ne fera que causer des maux de tête à l'avenir ... – Amro

Répondre

1

Vous enregistrez la fréquence du nombre de rouleaux, mais vous devez simplement enregistrer le nombre de rouleaux lui-même, puis afficher la fréquence dans un histogramme.

De même, vous devez appliquer xlim après avoir généré l'histogramme (pas avant).

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

et

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

avec

hist(numberofrolls); % Generate histogram 
+0

donc je besoin d'un vecteur ligne 10000 x 1, avec le résultat de chaque expérience individuelle à la place? – xst

+0

Oui.J'ai mis à jour ma réponse avec le code requis (l'efficacité de ceci pourrait être améliorée) – grantnz

0

Voici comment je mettre en œuvre cette simulation:

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]) 

screenshot

Si vous vous sentez un peu aventureux, voici une version entièrement vectorisé de la grande boucle:

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); 
0

ce fut la solution i fini avec (je ne suis pas trop familier avec vectorisation encore tout à fait)

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]) 
Questions connexes