# Random integers with differing probabilities

This is a follow-up to my last post on random numbers.

My new question is:

Say I want \n to generated (kind of) randomly, such that

\n=1 10% of the time

\n=2 20% of the time

\n=3 30% of the time

\n=4 40% of the time

This code makes each possible value of \n equally likely. How do I weight the probabilities as listed above?

\documentclass{minimal}

\setlength\parindent{0pt}

\usepackage{pgffor}

\begin{document}

\pgfmathdeclarerandomlist{choices}{{1}{2}{3}{4}}
\foreach\x in {1,...,50}
{\pgfmathrandomitem{\n}{choices}\n\\}

\end{document}

• For your example, I would guess using {{1}{2}{2}{3}{3}{3}{4}{4}{4}{4}} as your random list should be enough. Nov 19, 2016 at 23:32

You could do a variation of my answer to your previous question, and nest three ifthenelses.

\documentclass[border=4mm]{article}
\usepackage{pgffor}
\begin{document}
\foreach\x in {1,...,2000} {
\pgfmathsetmacro{\tmp}{rnd}
\pgfmathparse{ifthenelse(\tmp<=0.1,1,ifthenelse(\tmp<=0.3,2,ifthenelse(\tmp<=0.6,3,4)))}\pgfmathresult
}
\end{document}


Borrowing a bit from egreg's answer:

\documentclass{article}
\usepackage{pgffor}
\begin{document}
\newcounter{1}\newcounter{2}\newcounter{3}\newcounter{4}
\foreach\x in {1,...,2000} {
\pgfmathsetmacro{\tmp}{rnd}
\pgfmathparse{ifthenelse(\tmp<=0.1,1,ifthenelse(\tmp<=0.3,2,ifthenelse(\tmp<=0.6,3,4)))}\pgfmathresult
\stepcounter{\pgfmathresult}
}

1: \the\value{1}\par
2: \the\value{2}\par
3: \the\value{3}\par
4: \the\value{4}\par
\end{document}


\documentclass{article}
\usepackage{pgffor}

\newcommand{\myrandom}{%
\expandafter\domyrandom\pdfuniformdeviate 10 \domyrandom
}
\def\domyrandom#1\domyrandom{%
\ifcase#1
1\or
2\or
2\or
3\or
3\or
3\or
4\or
4\or
4\or
4\fi
}

\begin{document}

\foreach \x in {1,...,100}{\myrandom\space}

\newcounter{1}\newcounter{2}\newcounter{3}\newcounter{4}
\foreach \x in {1,...,1000}{\stepcounter{\myrandom}}
1: \the\value{1}\par
2: \the\value{2}\par
3: \the\value{3}\par
4: \the\value{4}\par

\end{document}


• Soon to be available in expl3 ;) Nov 19, 2016 at 17:26

While I'm sure there's a direct method to generate integers from 1 to 4 so that they have probabilities 0.1, 0.2, 0.3, and 0.4, an indirect or two-step method is more straightforward to set up. First, generate an integer between 1 and 10 randomly. (I.e., each integer has P=0.1.) Second, check if the integer is less than 2, 4, and 7, respectively, and assign the numbers "1", "2", "3" accordingly -- and associate the number "4" with the "none of the above" category, i.e. if the integer is between 7 and 10.

Here's a LuaLaTeX-based implementation of this idea.

\documentclass{article}
\newcommand\x{%
\directlua{x=math.random(10) % draw an integer between 1 and 10
if       x<2 then tex.sprint(1) % true if x==1
elseif x<4 then tex.sprint(2) % true if x==2 or 3
elseif x<7 then tex.sprint(3) % true if x==4, 5, or 6
else            tex.sprint(4) % true if x==7, 8, 9, or 10
end}}
\begin{document}
\obeylines % just for this example
\x, \x, \x, \x, \x; \x, \x, \x, \x, \x; \x, \x, \x, \x, \x; \x, \x, \x, \x, \x
\x, \x, \x, \x, \x; \x, \x, \x, \x, \x; \x, \x, \x, \x, \x; \x, \x, \x, \x, \x
\x, \x, \x, \x, \x; \x, \x, \x, \x, \x; \x, \x, \x, \x, \x; \x, \x, \x, \x, \x
\x, \x, \x, \x, \x; \x, \x, \x, \x, \x; \x, \x, \x, \x, \x; \x, \x, \x, \x, \x
\end{document}


https://en.wikipedia.org/wiki/Pseudo-random_number_sampling

create an function that has x values from 0 to 1, with y values that output the integer values you want, in the distribution you want. Then use a random number generator to produce a number between 0 and 1, and then lookup the value of your function. your function can be an 100 element array, in which the "x" value is multiplied by 100 and rounded down...

• Welcome to TeX.SE! Your posting currently reads more like a general statement about generating (pseudo-)random numbers than a LaTeX-based solution to the OP's query. Please consider editing your posting to explain how you would implement your recommendations in a LaTeX document.
– Mico
Nov 20, 2016 at 7:20