Nickyhw

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

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

          2012年6月27日 #

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

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

          M1:形式為<1,i>;

          M2:形式為<2,i>。

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

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

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

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

          1. 如果imax(v)則發(fā)送消息<2,i>,并且將i復制給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程。

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

           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 }
              該模型描述了每個進程節(jié)點的行為,通過該算法,可以找出網絡中的領導者。算法的計算復雜度為2nlogn+O(n) 。
          posted @ 2012-06-27 00:47 Nickyhw 閱讀(629) | 評論 (0)編輯 收藏

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

              它的具體定義是:

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

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

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


              讓我們來看一下這個圖:

           


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

           1 /**
           2  * 利用蒙特卡洛算法(Mente Carlo Method)計算單位圓面積
           
          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個隨機點。通過判斷生成的隨機點距離圓心點的距離來判斷生成的點是否在單位圓內。
              運行10次,結果如下:
              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數值為3.14159265……
              所以即使計算機已經模擬到100000000個隨機點,也只能大致精確到小數點后3位,而為了模擬這100000000個點,我的Y560筆記本也平均要花費5秒的時間來進行運算,如果再增加幾個0……

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

           

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

          僅列出標題  
          主站蜘蛛池模板: 高碑店市| 余江县| 湖南省| 吉安市| 井冈山市| 论坛| 香河县| 黄冈市| 浑源县| 广元市| 亳州市| 宜良县| 汾阳市| 青冈县| 高要市| 蒲城县| 阿拉善盟| 绥江县| 江北区| 黄冈市| 南通市| 绥中县| 教育| 剑川县| 平远县| 和龙市| 扎囊县| 长宁县| 靖宇县| 易门县| 淳安县| 云安县| 水富县| 门源| 博兴县| 通渭县| 寿阳县| 湖州市| 铜鼓县| 凤阳县| 公安县|