如何使给定的随机函数更均匀地分布? [英] How to make a given random function more equally distributed?

查看:84
本文介绍了如何使给定的随机函数更均匀地分布?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题与Debian或Ubuntu等Linux,bash和使用RANDOM的给定函数有关.

The question is related on Linux like Debian or Ubuntu, bash and a given function which use RANDOM.

每个改进都应仅使用bash.

Every improvement should use bash only.

给出以下功能:

getRND(){
    min="${1:-1}"   ## min is the first parameter, or 1 if no parameter is given           
    max="${2:-100}" ## max is the second parameter, or 100 if no parameter is given
    rnd_count=$((RANDOM%(max-min+1)+min));
    echo "$rnd_count"
}

var=$(getRND -10 10) # Call the function
echo $var # output

可以在以下方面进行改进:

It can be its possible to improved on follow:

  • 接受更大范围的数字
  • 随机进行更多

正在为尚未安装bash 5.1的Linux系统寻求解决方案,因此到目前为止,尚不能使用SRANDOM.

The solution is sought for Linux systems on which no bash 5.1 is installed already and therefore no SRANDOM can be used up to now.

如果可能的话,如何提高上述功能的随机性?

How to improve the randomness of the fuction above, if possible ?

推荐答案

在给定的随机函数上可以进行哪些改进以使其更加随机,范围更大或其他?

what can be improved on a given random function to make it more random or for a bigger range or something else?

,因此到目前为止无法使用SRANDOM.

and therefore no SRANDOM can be used up to now.

如果可能的话,如何提高上述功能的随机性?

How to improve the randomness of the fuction above, if possible ?

Sooo用您自己的语义编写您自己的SRANDOM.例如:

Sooo write your own SRANDOM with your own semantics. Ex:

srandom() {
   # should be random number from /dev/urandom
   # we take 4 bytes - one number 2^32
   echo "$((0x$(dd if=/dev/urandom of=/dev/stdout bs=4 count=1 status=none | xxd -p)))"
}

然后:

normalize_value(){
   ...
   rnd=$(srandom)
   rnd_count=$((rnd / ...))
}

接受更大范围的数字

Accepting a wider range of numbers

如果您对Shell算术扩展的工作方式不满意,请使用其他工具. bc 计算器具有无限范围.

If you are not happy with the way shell arithmetic expansion works, then... use a different tool. bc calculator has unlimited range.

rnd_count=$(echo "
     # see https://superuser.com/questions/31445/gnu-bc-modulo-with-scale-other-than-0
     scale=0; 
     # super big random number from three 2^32 numbers
     rnd = $(srandom) * 2^(32*2) +  $(srandom) * 2^32 + $(srandom)
     rnd % ($max - $min + 1) + $min
     " | bc)

您可以使用 getrandom()编写自己的C程序,并即时对其进行编译.}"|gcc -xc-&&./a.out;rm ./a.out 基本上会授予您所需的任何语义.还有其他脚本语言,例如perl,python,ruby,它们全都可能具有自己的大数库和urandom数生成实现.超越极限.

You can write your own C program with getrandom() and compile it on the fly echo "int main() { stuff(); }" | gcc -xc - && ./a.out; rm ./a.out basically granting you any semantics you want. There are also other scripting languages, like perl, python, ruby, all most probably with their own big-number libraries and urandom number generation implementations. Sky the limit.

每个改进都应仅使用bash.

Every improvement should use bash only.

从我的角度来看,这是毫无意义的限制-总的来说,我是为结果付费,而不是真正的如何"付费.我解决问题.无论如何,您可以给您一些如何进行的想法:

Is from my perspective a pointless limitation - overall, I am paid for results, not really "how" I solve problems. Anyway, you could, giving you a bunch of ideas how to proceed:

  • 首先编写一个将从/dev/urandom 读取的函数,并将字节转换为数字.
    • 我不知道如何将纯随机的bash保持在合理水平的同时进行.我怀疑输入会很快耗尽.
    • 您可以从urandom中读取一个字节.您必须忽略 read 退出状态,因为该字节可能是零字节或换行符.
    • 然后检查该字节是否为数字.如果不是,请重复上一步.
    • 处理这种算法可将其视为0-9范围内的随机数生成器.从这些数字中建立更大的数字.
    • First write a function that would read from /dev/urandom and convert the bytes into a number.
      • I have no good idea how to do it in pure bash while keeping the randomness at sane levels. I suspect the input will drain fast.
      • You could read one byte from urandom. You'll have to ignore read exit status, cause the byte may be zero byte or newline.
      • Then check if that byte is a digit. If it's not, repeat previous step.
      • Treat such algorithm treat as a generator of random number within the range of 0-9. Build bigger numbers from those digits.
      • 似乎毫无意义,因为 bc 普遍可用.
      • 这将与通常的大型数字图书馆一样工作.
      • 我建议将数字存储为最大2 ^ 16的数字数组.为了获得启发,请研究使用C和C ++语言编写的类似库,并将其转换为bash.

      这篇关于如何使给定的随机函数更均匀地分布?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆