異なる確率を持つランダムな整数

異なる確率を持つランダムな整数

これは、乱数に関する私の最後の投稿

私の新しい質問は次のとおりです:

\n(ある程度)ランダムに生成したいとします。

\n=1 10%の確率

\n=2 20%の確率で

\n=3 30%の時間

\n=4 40%の時間

このコードは、 の各可能な値を\n等しく確率にします。 上記のように確率に重み付けするにはどうすればよいでしょうか?

\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}

答え1

前回の質問に対する私の回答のバリエーションとして、3 つの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}

egreg さんの回答を少し拝借します:

\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}

ここに画像の説明を入力してください

答え2

\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}

ここに画像の説明を入力してください

答え3

1から4までの整数を0.1、0.2、0.3、0.4の確率で生成する直接的な方法があるのは確かですが、間接的または、2 段階方式の方が設定が簡単です。まず、1 から 10 までの整数をランダムに生成します (つまり、各整数は ですP=0.1)。次に、その整数がそれぞれ 2、4、7 未満かどうかを確認し、それに応じて数字「1」、「2」、「3」を割り当てます。そして、数字「4」を「上記のいずれでもない」カテゴリ (つまり、整数が 7 から 10 の間) に関連付けます。

以下は、このアイデアの LuaLaTeX ベースの実装です。

ここに画像の説明を入力してください

\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}

答え4

https://en.wikipedia.org/wiki/擬似乱数サンプリング

0 から 1 までの x 値と、必要な分布で必要な整数値を出力する y 値を持つ関数を作成します。次に、乱数ジェネレータを使用して 0 から 1 までの数値を生成し、関数の値を検索します。関数は 100 要素の配列にすることができ、その場合、「x」値は 100 倍されて切り捨てられます...

関連情報