比率に応じた乱数の発生

distribution.tabファイルを

0 1
1 1
2 1
3 1
4 1

とすると、1:1:1:1:1の割合で0、1、2、3、4が出力される。ヒストグラムにすると

f:id:S_E_Hyphen:20170414111552j:plain

同じく

0 1
1 1
2 2
3 1
4 1

にすると、1:1:2:1:1となる。

f:id:S_E_Hyphen:20170414111704j:plain

0 1
1 1
2 1
3 1
4 3
9 1

みたいに間が飛んでいても大丈夫。

 

f:id:S_E_Hyphen:20170414111926j:plain



 


 

#!/bin/bash
# 配列の定義
# 配分表のhirituの割合でitemが出力される
declare -a item=(\
 `cat distribution.tab |\
  awk '{print $1}'`\
)
declare -a hiritu=(\
 `cat distribution.tab |\
  awk '{print $2}'`\
)
declare -a ruiseki
# n_arrayは配列の数
n_array=${#hiritu[*]}

ruiseki[0]=0
for ( ( i=0; i<$n_array; i++ ) )
do
 ruiseki[`expr $i + 1`]=`expr ${ruiseki[$i]} + ${hiritu[$i]}`
done
for ( ( i=0; i<=$n_array; i++ ) )
do
 ruiseki[$i]=`bc  << _BC_
  32767 * ${ruiseki[$i]} / ${ruiseki[${n_array}]}
_BC_`
done
# 配列ruisekiの中には0〜32767をhirituに応じて配分している

for ( ( count=0; count<5000; count++ ) )
do
# 一様乱数randを発生させ、reuiseki(i)<=rand<reuiseki(i+1)なら
# item(i)を表示する
 rand=$( ( $RANDOM ) )
 for ( ( i=0; i<$n_array; i++ ) )
 do
 if [ ${ruiseki[$i]} -le $rand ] && [ $rand -lt ${ruiseki[`expr $i + 1`]} ]
 then
  echo $rand ${item[$i]}
 fi
 done
done |\
 awk '{print $2}' |\
 gmt pshistogram /dev/stdin -W0.2 -L -JX10c/3c -R-1/10/0/2000 -B1/a500g500 > histgram.ps
gmt ps2raster histgram.ps -E100 -P -A

# 最後2行はGMTを使って描画している