⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 randomvar.html

📁 一本完整的描述Unix Shell 编程的工具书的所有范例
💻 HTML
📖 第 1 页 / 共 2 页
字号:
 147&nbsp; 148&nbsp;displacement=$((0-minimum)) 149&nbsp;for ((i=${minimum}; i&#60;=${maximum}; i+=divisibleBy)); do 150&nbsp;   answer[i+displacement]=0 151&nbsp;done 152&nbsp; 153&nbsp; 154&nbsp;# Now loop a large number of times to see what we get. 155&nbsp;loopIt=1000   #  The script author suggests 100000, 156&nbsp;              #+ but that takes a good long while. 157&nbsp; 158&nbsp;for ((i=0; i&#60;${loopIt}; ++i)); do 159&nbsp; 160&nbsp;   #  Note that we are specifying min and max in reversed order here to 161&nbsp;   #+ make the function correct for this case. 162&nbsp; 163&nbsp;   randomBetween ${max} ${min} ${divisibleBy} 164&nbsp; 165&nbsp;   # Report an error if an answer is unexpected. 166&nbsp;   [ ${randomBetweenAnswer} -lt ${min} -o ${randomBetweenAnswer} -gt ${max} ] &#38;&#38; echo MIN or MAX error - ${randomBetweenAnswer}! 167&nbsp;   [ $((randomBetweenAnswer%${divisibleBy})) -ne 0 ] &#38;&#38; echo DIVISIBLE BY error - ${randomBetweenAnswer}! 168&nbsp; 169&nbsp;   # Store the answer away statistically. 170&nbsp;   answer[randomBetweenAnswer+displacement]=$((answer[randomBetweenAnswer+displacement]+1)) 171&nbsp;done 172&nbsp; 173&nbsp; 174&nbsp; 175&nbsp;# Let's check the results 176&nbsp; 177&nbsp;for ((i=${minimum}; i&#60;=${maximum}; i+=divisibleBy)); do 178&nbsp;   [ ${answer[i+displacement]} -eq 0 ] &#38;&#38; echo "We never got an answer of $i." || echo "${i} occurred ${answer[i+displacement]} times." 179&nbsp;done 180&nbsp; 181&nbsp; 182&nbsp;exit 0</PRE></TD></TR></TABLE><HR></DIV><P>Just how random is <TTCLASS="VARNAME">$RANDOM</TT>? The best	  way to test this is to write a script that tracks	  the distribution of <SPANCLASS="QUOTE">"random"</SPAN> numbers	  generated by <TTCLASS="VARNAME">$RANDOM</TT>. Let's roll a	  <TTCLASS="VARNAME">$RANDOM</TT> die a few times . . .</P><DIVCLASS="EXAMPLE"><HR><ANAME="RANDOMTEST"></A><P><B>Example 9-27. Rolling a single die with RANDOM</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">   1&nbsp;#!/bin/bash   2&nbsp;# How random is RANDOM?   3&nbsp;   4&nbsp;RANDOM=$$       # Reseed the random number generator using script process ID.   5&nbsp;   6&nbsp;PIPS=6          # A die has 6 pips.   7&nbsp;MAXTHROWS=600   # Increase this if you have nothing better to do with your time.   8&nbsp;throw=0         # Throw count.   9&nbsp;  10&nbsp;ones=0          #  Must initialize counts to zero,  11&nbsp;twos=0          #+ since an uninitialized variable is null, not zero.  12&nbsp;threes=0  13&nbsp;fours=0  14&nbsp;fives=0  15&nbsp;sixes=0  16&nbsp;  17&nbsp;print_result ()  18&nbsp;{  19&nbsp;echo  20&nbsp;echo "ones =   $ones"  21&nbsp;echo "twos =   $twos"  22&nbsp;echo "threes = $threes"  23&nbsp;echo "fours =  $fours"  24&nbsp;echo "fives =  $fives"  25&nbsp;echo "sixes =  $sixes"  26&nbsp;echo  27&nbsp;}  28&nbsp;  29&nbsp;update_count()  30&nbsp;{  31&nbsp;case "$1" in  32&nbsp;  0) let "ones += 1";;   # Since die has no "zero", this corresponds to 1.  33&nbsp;  1) let "twos += 1";;   # And this to 2, etc.  34&nbsp;  2) let "threes += 1";;  35&nbsp;  3) let "fours += 1";;  36&nbsp;  4) let "fives += 1";;  37&nbsp;  5) let "sixes += 1";;  38&nbsp;esac  39&nbsp;}  40&nbsp;  41&nbsp;echo  42&nbsp;  43&nbsp;  44&nbsp;while [ "$throw" -lt "$MAXTHROWS" ]  45&nbsp;do  46&nbsp;  let "die1 = RANDOM % $PIPS"  47&nbsp;  update_count $die1  48&nbsp;  let "throw += 1"  49&nbsp;done    50&nbsp;  51&nbsp;print_result  52&nbsp;  53&nbsp;exit 0  54&nbsp;  55&nbsp;#  The scores should distribute fairly evenly, assuming RANDOM is fairly random.  56&nbsp;#  With $MAXTHROWS at 600, all should cluster around 100, plus-or-minus 20 or so.  57&nbsp;#  58&nbsp;#  Keep in mind that RANDOM is a pseudorandom generator,  59&nbsp;#+ and not a spectacularly good one at that.  60&nbsp;  61&nbsp;#  Randomness is a deep and complex subject.  62&nbsp;#  Sufficiently long "random" sequences may exhibit  63&nbsp;#+ chaotic and other "non-random" behavior.  64&nbsp;  65&nbsp;# Exercise (easy):  66&nbsp;# ---------------  67&nbsp;# Rewrite this script to flip a coin 1000 times.  68&nbsp;# Choices are "HEADS" and "TAILS".</PRE></TD></TR></TABLE><HR></DIV><P>As we have seen in the last example, it is best to	  <SPANCLASS="QUOTE">"reseed"</SPAN> the <TTCLASS="VARNAME">RANDOM</TT>	  generator each time it is invoked. Using the same seed	  for <TTCLASS="VARNAME">RANDOM</TT> repeats the same series	  of numbers.	    <ANAME="AEN5208"HREF="#FTN.AEN5208">[2]</A>	  (This mirrors the behavior of the	  <TTCLASS="REPLACEABLE"><I>random()</I></TT> function in	  <ICLASS="FIRSTTERM">C</I>.)</P><DIVCLASS="EXAMPLE"><HR><ANAME="SEEDINGRANDOM"></A><P><B>Example 9-28. Reseeding RANDOM</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">   1&nbsp;#!/bin/bash   2&nbsp;# seeding-random.sh: Seeding the RANDOM variable.   3&nbsp;   4&nbsp;MAXCOUNT=25       # How many numbers to generate.   5&nbsp;   6&nbsp;random_numbers ()   7&nbsp;{   8&nbsp;count=0   9&nbsp;while [ "$count" -lt "$MAXCOUNT" ]  10&nbsp;do  11&nbsp;  number=$RANDOM  12&nbsp;  echo -n "$number "  13&nbsp;  let "count += 1"  14&nbsp;done    15&nbsp;}  16&nbsp;  17&nbsp;echo; echo  18&nbsp;  19&nbsp;RANDOM=1          # Setting RANDOM seeds the random number generator.  20&nbsp;random_numbers  21&nbsp;  22&nbsp;echo; echo  23&nbsp;  24&nbsp;RANDOM=1          # Same seed for RANDOM...  25&nbsp;random_numbers    # ...reproduces the exact same number series.  26&nbsp;                  #  27&nbsp;                  # When is it useful to duplicate a "random" number series?  28&nbsp;  29&nbsp;echo; echo  30&nbsp;  31&nbsp;RANDOM=2          # Trying again, but with a different seed...  32&nbsp;random_numbers    # gives a different number series.  33&nbsp;  34&nbsp;echo; echo  35&nbsp;  36&nbsp;# RANDOM=$$  seeds RANDOM from process id of script.  37&nbsp;# It is also possible to seed RANDOM from 'time' or 'date' commands.  38&nbsp;  39&nbsp;# Getting fancy...  40&nbsp;SEED=$(head -1 /dev/urandom | od -N 1 | awk '{ print $2 }')  41&nbsp;#  Pseudo-random output fetched  42&nbsp;#+ from /dev/urandom (system pseudo-random device-file),  43&nbsp;#+ then converted to line of printable (octal) numbers by "od",  44&nbsp;#+ finally "awk" retrieves just one number for SEED.  45&nbsp;RANDOM=$SEED  46&nbsp;random_numbers  47&nbsp;  48&nbsp;echo; echo  49&nbsp;  50&nbsp;exit 0</PRE></TD></TR></TABLE><HR></DIV><P><ANAME="URANDOMREF"></A></P><DIVCLASS="NOTE"><TABLECLASS="NOTE"WIDTH="100%"BORDER="0"><TR><TDWIDTH="25"ALIGN="CENTER"VALIGN="TOP"><IMGSRC="common/note.png"HSPACE="5"ALT="Note"></TD><TDALIGN="LEFT"VALIGN="TOP"><P>The <TTCLASS="FILENAME">/dev/urandom</TT> device-file provides	  a method of generating much more <SPANCLASS="QUOTE">"random"</SPAN>	  pseudorandom numbers than the <TTCLASS="VARNAME">$RANDOM</TT>	  variable.  <TTCLASS="USERINPUT"><B>dd if=/dev/urandom of=targetfile	  bs=1 count=XX</B></TT> creates a file of well-scattered	  pseudorandom numbers.  However, assigning these numbers	  to a variable in a script requires a workaround, such as	  filtering through <AHREF="extmisc.html#ODREF">od</A> (as in	  above example and <AHREF="textproc.html#RND">Example 12-13</A>), or using <AHREF="extmisc.html#DDREF">dd</A> (see <AHREF="extmisc.html#BLOTOUT">Example 12-55</A>),	  or even piping to <AHREF="filearchiv.html#MD5SUMREF">md5sum</A>	  (see <AHREF="colorizing.html#HORSERACE">Example 33-14</A>).</P><P><ANAME="AWKRANDOMREF"></A></P><P>There are also other ways to generate pseudorandom          numbers in a script. <BCLASS="COMMAND">Awk</B> provides a	  convenient means of doing this.</P><DIVCLASS="EXAMPLE"><HR><ANAME="RANDOM2"></A><P><B>Example 9-29. Pseudorandom numbers, using <AHREF="awk.html#AWKREF">awk</A></B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">   1&nbsp;#!/bin/bash   2&nbsp;# random2.sh: Returns a pseudorandom number in the range 0 - 1.   3&nbsp;# Uses the awk rand() function.   4&nbsp;   5&nbsp;AWKSCRIPT=' { srand(); print rand() } '   6&nbsp;#            Command(s) / parameters passed to awk   7&nbsp;# Note that srand() reseeds awk's random number generator.   8&nbsp;   9&nbsp;  10&nbsp;echo -n "Random number between 0 and 1 = "  11&nbsp;  12&nbsp;echo | awk "$AWKSCRIPT"  13&nbsp;# What happens if you leave out the 'echo'?  14&nbsp;  15&nbsp;exit 0  16&nbsp;  17&nbsp;  18&nbsp;# Exercises:  19&nbsp;# ---------  20&nbsp;  21&nbsp;# 1) Using a loop construct, print out 10 different random numbers.  22&nbsp;#      (Hint: you must reseed the "srand()" function with a different seed  23&nbsp;#+     in each pass through the loop. What happens if you fail to do this?)  24&nbsp;  25&nbsp;# 2) Using an integer multiplier as a scaling factor, generate random numbers   26&nbsp;#+   in the range between 10 and 100.  27&nbsp;  28&nbsp;# 3) Same as exercise #2, above, but generate random integers this time.</PRE></TD></TR></TABLE><HR></DIV><P>The <AHREF="timedate.html#DATEREF">date</A> command also lends	  itself to <AHREF="timedate.html#DATERANDREF">generating pseudorandom	  integer sequences</A>.</P></TD></TR></TABLE></DIV></DIV><H3CLASS="FOOTNOTES">Notes</H3><TABLEBORDER="0"CLASS="FOOTNOTES"WIDTH="100%"><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="5%"><ANAME="FTN.AEN5174"HREF="randomvar.html#AEN5174">[1]</A></TD><TDALIGN="LEFT"VALIGN="TOP"WIDTH="95%"><P>True <SPANCLASS="QUOTE">"randomness,"</SPAN> insofar as	    it exists at all, can only be found in certain	    incompletely understood natural phenomena such as	    radioactive decay. Computers can only simulate	    randomness, and computer-generated sequences of	    <SPANCLASS="QUOTE">"random"</SPAN> numbers are therefore referred to as	    <ICLASS="EMPHASIS">pseudorandom</I>.</P></TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="5%"><ANAME="FTN.AEN5208"HREF="randomvar.html#AEN5208">[2]</A></TD><TDALIGN="LEFT"VALIGN="TOP"WIDTH="95%"><P>The <ICLASS="FIRSTTERM">seed</I> of a	      computer-generated pseudorandom number series	      can be considered an identification label. For	      example, think of the pseudorandom series with a	      seed of <ICLASS="EMPHASIS">23</I> as <ICLASS="EMPHASIS">series	      #23</I>.</P><P>A property of a pseurandom number series is the length of	      the cycle before it starts repeating itself. A good pseurandom	      generator will produce series with very long cycles.</P></TD></TR></TABLE><DIVCLASS="NAVFOOTER"><HRALIGN="LEFT"WIDTH="100%"><TABLEWIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top"><AHREF="ivr.html">Prev</A></TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="index.html">Home</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top"><AHREF="dblparens.html">Next</A></TD></TR><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top">Indirect References to Variables</TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="variables2.html">Up</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top">The Double Parentheses Construct</TD></TR></TABLE></DIV></BODY></HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -