?? cannon.sh
字號:
#!/bin/bash# cannon.sh: Approximating PI by firing cannonballs.# 這事實(shí)上是一個"Monte Carlo"蒙特卡洛模擬的非常簡單的實(shí)例:#+ 蒙特卡洛模擬是一種由現(xiàn)實(shí)事件抽象出來的數(shù)學(xué)模型,#+ 由于要使用隨機(jī)抽樣統(tǒng)計(jì)來估算數(shù)學(xué)函數(shù), 所以使用偽隨機(jī)數(shù)來模擬真正的隨機(jī)數(shù).# 想象有一個完美的正方形土地, 邊長為10000個單位.# 在這塊土地的中間有一個完美的圓形湖,#+ 這個湖的直徑是10000個單位.# 這塊土地的絕大多數(shù)面積都是水, 當(dāng)然只有4個角上有一些土地.# (可以把這個湖想象成為這個正方形的內(nèi)接圓.)## 我們將使用老式的大炮和鐵炮彈#+ 向這塊正方形的土地上開炮.# 所有的炮彈都會擊中這塊正方形土地的某個地方.#+ 或者是打到湖上, 或者是打到4個角的土地上.# 因?yàn)檫@個湖占據(jù)了這個區(qū)域大部分地方,#+ 所以大部分的炮彈都會"撲通"一聲落到水里.# 而只有很少的炮彈會"砰"的一聲落到4個#+ 角的土地上.## 如果我們發(fā)出的炮彈足夠隨機(jī)的落到這塊正方形區(qū)域中的話,#+ 那么落到水里的炮彈與打出炮彈總數(shù)的比率,#+ 大概非常接近于PI/4.## 原因是所有的炮彈事實(shí)上都#+ 打在了這個土地的右上角,#+ 也就是, 笛卡爾坐標(biāo)系的第一象限.# (之前的解釋只是一個簡化.)## 理論上來說, 如果打出的炮彈越多, 就越接近這個數(shù)字.# 然而, 對于shell 腳本來說一定會做些讓步的,#+ 因?yàn)樗隙ú荒芎湍切﹥?nèi)建就支持浮點(diǎn)運(yùn)算的編譯語言相比.# 當(dāng)然就會降低精度.DIMENSION=10000 # 這塊土地的邊長. # 這也是所產(chǎn)生隨機(jī)整數(shù)的上限. MAXSHOTS=1000 # 開炮次數(shù). # 10000或更多次的話, 效果應(yīng)該更好, 但有點(diǎn)太浪費(fèi)時間了.PMULTIPLIER=4.0 # 接近于PI的比例因子.get_random (){SEED=$(head -1 /dev/urandom | od -N 1 | awk '{ print $2 }')RANDOM=$SEED # 來自于"seeding-random.sh" #+ 的例子腳本.let "rnum = $RANDOM % $DIMENSION" # 范圍小于10000.echo $rnum}distance= # 聲明全局變量.hypotenuse () # 從"alt-bc.sh"例子來的,{ # 計(jì)算直角三角形的斜邊的函數(shù).distance=$(bc -l << EOFscale = 0sqrt ( $1 * $1 + $2 * $2 )EOF)# 設(shè)置 "scale" 為 0 , 好讓結(jié)果四舍五入為整數(shù)值,#+ 這也是這個腳本中必須折中的一個地方.# 不幸的是, 這將降低模擬的精度.}# main() {# 初始化變量. shots=0splashes=0thuds=0Pi=0while [ "$shots" -lt "$MAXSHOTS" ] # 主循環(huán).do xCoord=$(get_random) # 取得隨機(jī)的 X 與 Y 坐標(biāo). yCoord=$(get_random) hypotenuse $xCoord $yCoord # 直角三角形斜邊 = #+ distance. ((shots++)) printf "#%4d " $shots printf "Xc = %4d " $xCoord printf "Yc = %4d " $yCoord printf "Distance = %5d " $distance # 到湖中心的 #+ 距離 -- # 起始坐標(biāo)點(diǎn) -- #+ (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) # 將比例乘以4.0. echo -n "PI ~ $Pi" echodoneechoecho "After $shots shots, PI looks like approximately $Pi."# 如果不太準(zhǔn)的話, 那么就提高一下運(yùn)行的次數(shù). . .# 可能是由于運(yùn)行錯誤和隨機(jī)數(shù)隨機(jī)程度不高造成的.echo# }exit 0# 要想知道一個shell腳本到底適不適合對計(jì)算應(yīng)用進(jìn)行模擬的話?#+ (一種需要對復(fù)雜度和精度都有要求的計(jì)算應(yīng)用).## 一般至少需要兩個判斷條件.# 1) 作為一種概念的驗(yàn)證: 來顯示它可以做到. # 2) 在使用真正的編譯語言來實(shí)現(xiàn)一個算法之前, #+ 使用腳本來測試和驗(yàn)證這個算法.
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -