我需要能够在2013年到2044年之间生成一个随机数(包括在内)。我已经尝试了下面的两个脚本,但在任何一种情况下输出都不是很随机。许多数字都在重复,其他人则丢失了。有办法解决这个问题吗?
这是第一个脚本:
i="1"
x="2014"
y="2044"
while [ $i != 32 ]; do
var=$RANDOM
var=$[ $x + $var % ($y + 1 -$x) ]
echo $var
i=$[$i+1]
done
这是第二个
i="1"
while [ $i != 32 ]; do
var=$(shuf -i 2014-2044 -n1)
echo $var
i=$[$i+1]
done
谢谢, 席亚拉
答案 0 :(得分:2)
在 [y,z] 和 x>范围内生成 x 随机数时z-y ,你会有一些重复。您可能还会在连续的插槽中遇到一些重复的数字,因为当您使用mod时,其中一些随机数实际上会映射到相同的数字。如果您增加范围,您会注意到这些数字更多是随机。
答案 1 :(得分:2)
这是随机数的本质。让我们试试3100次迭代。我们期望在[2014,2044]中为每个号码获得100个条目:
#!/bin/bash
x=2014
y=2044
n=()
for ((i=1; i<=3100; i++)); do
(( n[x + RANDOM % (y-x+1)] += 1 ))
done
for ((i=x; i<=y; i++)); do
printf "%d\t%d\n" $i ${n[i]}
done
2014 95
2015 96
2016 98
2017 87
2018 96
2019 82
2020 111
2021 105
2022 113
2023 100
2024 102
2025 95
2026 89
2027 110
2028 102
2029 93
2030 107
2031 109
2032 115
2033 92
2034 108
2035 96
2036 94
2037 109
2038 91
2039 113
2040 90
2041 123
2042 82
2043 102
2044 95
答案 2 :(得分:0)
由于您需要随机排列,因此您要生成的随机数实际上是 indices 到剩余未选数的列表中。像
这样的东西unselected=( {2014..2044} )
while (( ${#unselected[@]} > 0 )); do
# Pick a random index
index=$(( $RANDOM % ${#unselected[@]} ))
echo ${unselected[index]}
# Remove the value at that index
unset unselected[index]
unselected=( "${unselected[@]}" )
done
答案 3 :(得分:0)
seq 2014 2044 | sort -R
这会使用seq
创建数字范围,然后随机重新排序。