Nickyhw

          研究Java技術(shù),算法設(shè)計(jì)以及移動開發(fā)

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            2 隨筆 :: 0 文章 :: 0 評論 :: 0 Trackbacks

          2012年6月27日 #

          Danny Dolev等在1982年提及了一種未改進(jìn)的extreme-find算法,該算法過程簡要描述如下:

          算法中使用的消息類型有兩種:

          M1:形式為<1,i>;

          M2:形式為<2,i>。

          其中,i表示存儲在進(jìn)程中的一個數(shù)字。每個進(jìn)程v都含有一個變量max(v),當(dāng)該進(jìn)程是激活(active)狀態(tài)時,該變量可以用來存儲位于當(dāng)前進(jìn)程左邊的另一個激活的進(jìn)程的變量。

          被動的(passive)進(jìn)程僅僅是簡單的傳遞它們接收到的消息。對于算法的描述,我們可以僅僅對其中一個進(jìn)程的行為進(jìn)行描述就可以了。

          算法     A0. 發(fā)送消息<1,max(v)>.

          A1. 如果接收到一條消息<1,i>,則執(zhí)行以下操作:

          1. 如果imax(v)則發(fā)送消息<2,i>,并且將i復(fù)制給left(v)。

          2. 否則,終止——max(v)是全局最大值。

          A2. 如果接受到一條消息<2,i>,則執(zhí)行以下操作:

          1. 如果left(v)大于j和max(v)則將left(v)賦值給max(v),然后發(fā)送消息<1,    max(v)>

          2. 否則,變?yōu)楸粍舆M(jìn)程。

              基于以上的算法描述,我們可以利用Spin建模語言Promela對其進(jìn)行建模如下:

           1 mtype = { one, two, winner };
           2 chan q[N] = [L] of { mtype, byte};
           3 
           4 proctype node (chan inoutbyte mynumber)
           5 {    bit Active = 1, know_winner = 0;
           6      byte nr, maximum = mynumber, neighbourR;
           7 
           8     xr in;
           9     xs out;
          10 
          11     printf("MSC: %d\n", mynumber);
          12     out!one(mynumber);
          13 end:    do
          14     :: in?one(nr) ->
          15         if
          16         :: Active -> 
          17             if
          18             :: nr != maximum ->
          19                 out!two(nr);
          20                 neighbourR = nr
          21             :: else ->
          22                 know_winner = 1;
          23                 out!winner,nr;
          24             fi
          25         :: else ->
          26             out!one(nr)
          27         fi
          28 
          29     :: in?two(nr) ->
          30         if
          31         :: Active -> 
          32             if
          33             :: neighbourR > nr && neighbourR > maximum ->
          34                 maximum = neighbourR;
          35                 out!one(neighbourR)
          36             :: else ->
          37                 Active = 0
          38             fi
          39         :: else ->
          40             out!two(nr)
          41         fi
          42     :: in?winner,nr ->
          43         if
          44         :: nr != mynumber ->
          45             printf("MSC: LOST\n");
          46         :: else ->
          47             printf("MSC: LEADER\n");
          48             nr_leaders++;
          49             assert(nr_leaders == 1)
          50         fi;
          51         if
          52         :: know_winner
          53         :: else -> out!winner,nr
          54         fi;
          55         break
          56     od
          57 }
              該模型描述了每個進(jìn)程節(jié)點(diǎn)的行為,通過該算法,可以找出網(wǎng)絡(luò)中的領(lǐng)導(dǎo)者。算法的計(jì)算復(fù)雜度為2nlogn+O(n) 。
          posted @ 2012-06-27 00:47 Nickyhw 閱讀(629) | 評論 (0)編輯 收藏

              1946年,美國拉斯阿莫斯國家實(shí)驗(yàn)室的三位科學(xué)家John von Neumann,Stan Ulam 和 Nick Metropolis共同發(fā)明,被稱為蒙特卡洛方法。

              它的具體定義是:

              在廣場上畫一個邊長一米的正方形,在正方形內(nèi)部隨意用粉筆畫一個不規(guī)則的形狀,現(xiàn)在要計(jì)算這個不規(guī)則圖形的面積,怎么計(jì)算列?蒙特卡洛(Monte Carlo)方法告訴我們,均勻的向該正方形內(nèi)撒N(N 是一個很大的自然數(shù))個黃豆,隨后數(shù)數(shù)有多少個黃豆在這個不規(guī)則幾何形狀內(nèi)部,比如說有M個,那么,這個奇怪形狀的面積便近似于M/N,N越大,算出來的 值便越精確。在這里我們要假定豆子都在一個平面上,相互之間沒有重疊。

              蒙特卡洛方法可用于近似計(jì)算圓周率:讓計(jì)算機(jī)每次隨機(jī)生成兩 個0到1之間的數(shù),看這兩個實(shí)數(shù)是否在單位圓內(nèi)。生成一系列隨機(jī)點(diǎn),統(tǒng)計(jì)單位圓內(nèi)的點(diǎn)數(shù)與總點(diǎn)數(shù),(圓面積和正方形面積之比為PI:1,PI為圓周率), 當(dāng)隨機(jī)點(diǎn)取得越多(但即使取10的9次方個隨機(jī)點(diǎn)時,其結(jié)果也僅在前4位與圓周率吻合)時,其結(jié)果越接近于圓周率。

              (以上摘自《20世紀(jì)最偉大的10個算法》)


              讓我們來看一下這個圖:

           


              圖中黃色區(qū)域?yàn)橐粏挝粓A,半徑r=1。其外接正方形邊長為2。我們可以看到,外接正方形與坐標(biāo)軸將該單位圓切成四等分,而每個小正方形的面積為1*1=1。這樣,為了求出小正方形里的扇形面積,我們利用計(jì)算機(jī)強(qiáng)大的計(jì)算能力,往小正方形里投入無數(shù)個隨機(jī)點(diǎn)。假設(shè)投進(jìn)扇形里的點(diǎn)總數(shù)為c_sum,投進(jìn)小正方形里的點(diǎn)(包含投進(jìn)扇形的點(diǎn))總數(shù)為sum,那么根據(jù)公式c_sum / sum = area / 1,即可計(jì)算出該扇形的面積 = c_sum / sum。由此可得到圓的面積area = c_sum / sum * 4。
              我們知道,單位圓的半徑r=1,所以實(shí)際上求單位圓的面積就是求出PI的數(shù)值。隨機(jī)點(diǎn)數(shù)量取值越大,那么PI值就越精確。

           1 /**
           2  * 利用蒙特卡洛算法(Mente Carlo Method)計(jì)算單位圓面積
           
          3  *
           4  */
           5 
           6 import java.util.Random;
           7 
           8 public class MonteCarloMethodTest
           9 {
          10     public static void main(String[] args)
          11     {
          12         int sum = 0;                    
          13         int c_sum = 0;                    
          14         double x;                        
          15         double y;                        
          16         Random ra = new Random();        
          17         
          18         int i = 0;
          19         while (i != 100000000)            
          20         {
          21             x = ra.nextDouble();
          22             y = ra.nextDouble();
          23             
          24             if (x * x + y * y <= 1)    
          25                 ++c_sum;
          26             ++sum;
          27             ++i;
          28         }
          29         
          30         double area = (double)c_sum / sum * 4;    
          31         System.out.println("area = " + area);
          32     }
          33 }

              在這個程序中,總共在小正方形里生成了100000000個隨機(jī)點(diǎn)。通過判斷生成的隨機(jī)點(diǎn)距離圓心點(diǎn)的距離來判斷生成的點(diǎn)是否在單位圓內(nèi)。
              運(yùn)行10次,結(jié)果如下:
              area = 3.14172004
              area = 3.14182308
              area = 3.14190064
              area = 3.14139992
              area = 3.14176768
              area = 3.14177084
              area = 3.14142864
              area = 3.14176596
              area = 3.14191927
              area = 3.14172096
              我們知道,較為精確的PI數(shù)值為3.14159265……
              所以即使計(jì)算機(jī)已經(jīng)模擬到100000000個隨機(jī)點(diǎn),也只能大致精確到小數(shù)點(diǎn)后3位,而為了模擬這100000000個點(diǎn),我的Y560筆記本也平均要花費(fèi)5秒的時間來進(jìn)行運(yùn)算,如果再增加幾個0……

              蒙特卡洛算法是1946年提出來的,當(dāng)時沒有運(yùn)行速度如此快的現(xiàn)代計(jì)算機(jī)。不過由于現(xiàn)代計(jì)算機(jī)的運(yùn)算速度不斷提高,借助于其強(qiáng)大的計(jì)算能力,我們可以將蒙特卡洛運(yùn)用在工程中的很多需要近似求解的地方。

           

          posted @ 2012-06-27 00:30 Nickyhw 閱讀(4820) | 評論 (0)編輯 收藏

          主站蜘蛛池模板: 扎赉特旗| 锡林浩特市| 灵山县| 抚州市| 鄢陵县| 阳江市| 明水县| 台前县| 保山市| 株洲市| 司法| 浏阳市| 始兴县| 开江县| 云南省| 襄汾县| 信丰县| 香河县| 五寨县| 且末县| 丰都县| 都安| 安平县| 花莲市| 隆昌县| 鄂伦春自治旗| 崇仁县| 调兵山市| 三原县| 台前县| 温泉县| 庄河市| 防城港市| 西藏| 抚顺县| 巴林右旗| 万州区| 凤庆县| 肃宁县| 胶南市| 玉林市|