?? cannon.sh
字號:
#!/bin/bash# cannon.sh: Approximating PI by firing cannonballs.# This is a very simple instance of a "Monte Carlo" simulation:#+ a mathematical model of a real-life event,#+ using pseudorandom numbers to emulate random chance.# Consider a perfectly square plot of land, 10000 units on a side.# This land has a perfectly circular lake in its center,#+ with a diameter of 10000 units.# The plot is actually mostly water, except for land in the four corners.# (Think of it as a square with an inscribed circle.)## We will fire iron cannonballs from an old-style cannon#+ at the square.# All the shots impact somewhere on the square,#+ either in the lake or on the dry corners.# Since the lake takes up most of the area,#+ most of the shots will SPLASH! into the water.# Just a few shots will THUD! into solid ground#+ in the four corners of the square.## If we take enough random, unaimed shots at the square,#+ Then the ratio of SPLASHES to total shots will approximate#+ the value of PI/4.## The reason for this is that the cannon is actually shooting#+ only at the upper right-hand quadrant of the square,#+ i.e., Quadrant I of the Cartesian coordinate plane.# (The previous explanation was a simplification.)## Theoretically, the more shots taken, the better the fit.# However, a shell script, as opposed to a compiled language#+ with floating-point math built in, requires a few compromises.# This tends to lower the accuracy of the simulation, of course.DIMENSION=10000 # Length of each side of the plot. # Also sets ceiling for random integers generated.MAXSHOTS=1000 # Fire this many shots. # 10000 or more would be better, but would take too long.PMULTIPLIER=4.0 # Scaling factor to approximate PI.get_random (){SEED=$(head -1 /dev/urandom | od -N 1 | awk '{ print $2 }')RANDOM=$SEED # From "seeding-random.sh" #+ example script.let "rnum = $RANDOM % $DIMENSION" # Range less than 10000.echo $rnum}distance= # Declare global variable.hypotenuse () # Calculate hypotenuse of a right triangle.{ # From "alt-bc.sh" example.distance=$(bc -l << EOFscale = 0sqrt ( $1 * $1 + $2 * $2 )EOF)# Setting "scale" to zero rounds down result to integer value,#+ a necessary compromise in this script.# This diminshes the accuracy of the simulation, unfortunately.}# main() {# Initialize variables.shots=0splashes=0thuds=0Pi=0while [ "$shots" -lt "$MAXSHOTS" ] # Main loop.do xCoord=$(get_random) # Get random X and Y coords. yCoord=$(get_random) hypotenuse $xCoord $yCoord # Hypotenuse of right-triangle = #+ distance. ((shots++)) printf "#%4d " $shots printf "Xc = %4d " $xCoord printf "Yc = %4d " $yCoord printf "Distance = %5d " $distance # Distance from #+ center of lake -- # the "origin" -- #+ coordinate (0,0). if [ "$distance" -le "$DIMENSION" ] then echo -n "SPLASH! " ((splashes++)) else echo -n "THUD! " ((thuds++)) fi Pi=$(echo "scale=9; $PMULTIPLIER*$splashes/$shots" | bc) # Multiply ratio by 4.0. echo -n "PI ~ $Pi" echodoneechoecho "After $shots shots, PI looks like approximately $Pi."# Tends to run a bit high . . . # Probably due to round-off error and imperfect randomness of $RANDOM.echo# }exit 0# One might well wonder whether a shell script is appropriate for#+ an application as complex and computation-intensive as a simulation.## There are at least two justifications.# 1) As a proof of concept: to show it can be done.# 2) To prototype and test the algorithms before rewriting#+ it in a compiled high-level language.
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -