Concurrency Erlang并发Montecarlo Pi估计

Concurrency Erlang并发Montecarlo Pi估计,concurrency,erlang,spawn,montecarlo,pi,Concurrency,Erlang,Spawn,Montecarlo,Pi,对于赋值,我需要使用Montecarlo方法估计Erlang中的pi,但需要指定数量的参与者和迭代。我有一个不使用并发的工作版本(改编自),因此采用一个参数,N=迭代次数(点)。我试图通过创建另一个montecarlo()函数来添加它,该函数包含两个参数:迭代次数的N=#和参与者的X=#。我很难弄清楚如何使用(伪)循环来产生每个参与者 前一个版本返回pi估计,但在我计算出生成后,我假设我必须为最终pi估计平均每个参与者的返回值 以下是我所拥有的: -module(pi). -export([mo

对于赋值,我需要使用Montecarlo方法估计Erlang中的pi,但需要指定数量的参与者和迭代。我有一个不使用并发的工作版本(改编自),因此采用一个参数,N=迭代次数(点)。我试图通过创建另一个montecarlo()函数来添加它,该函数包含两个参数:迭代次数的N=#和参与者的X=#。我很难弄清楚如何使用(伪)循环来产生每个参与者

前一个版本返回pi估计,但在我计算出生成后,我假设我必须为最终pi估计平均每个参与者的返回值

以下是我所拥有的:

-module(pi).
-export([montecarlo/1, montecarlo/2]).

montecarlo(N, X)->
    NumIterPerActor = N div X,
    %io:fwrite("Number of actors = ~w~n",[X]),
    %io:fwrite("Number of iterations per actor = ~w~n",[NumIterPerActor]),
    lists:seq(1, X),
    spawn(pi, montecarlo, [NumIterPerActor]).

montecarlo(N)->
    montecarlo(N,0,0).

montecarlo(0,InCircle,NumPoints)->
    PiEst = 4*InCircle / NumPoints,
    io:fwrite("Pi = ~w~n", [PiEst]);

montecarlo(N,InCircle,NumPoints)->
    Xcoord = rand:uniform(),
    Ycoord = rand:uniform(),
    montecarlo(N-1,if Xcoord*Xcoord + Ycoord*Ycoord < 1 -> InCircle + 1; true -> InCircle end,NumPoints + 1).
-模块(pi)。
-出口([montecarlo/1,montecarlo/2])。
蒙地卡罗(北,西)->
NumIterPerActor=N第X部分,
%io:fwrite(“参与者数量=~w~n,[X]),
%io:fwrite(“每个参与者的迭代次数=~w~n,[NumIterPerActor]),
列表:序号(1,X),
繁殖(pi,蒙特卡洛,[NumIterPerActor])。
蒙地卡罗(北)->
蒙特卡洛(N,0,0)。
蒙特卡洛(0,内圆,整数)->
PiEst=4*内圆/整数,
io:fwrite(“Pi=~w~n,[PiEst]);
蒙地卡罗(北,内圆,整数)->
Xcoord=rand:uniform(),
Ycoord=rand:uniform(),
蒙特卡洛(N-1,如果Xcoord*Xcoord+Ycoord*Ycoord<1->内圆+1;true->内圆结束,NumPoints+1)。
通过研究这个问题,我看到了如何使用map(),但据我所知,您是在map()中创建一个新函数,而不是使用已经实现的函数

编辑:

我在截止日期之前没有收到任何建议(我等了这么长时间,这是我的错),因此我向一位同学寻求帮助,并提出了一个递归解决方案:

-module(pi).
-export([montecarlo/1, montecarlo/2, assign/3, compute/2, addPi/3]).

montecarlo(N, X)->
    NumIterPerActor = N div X,  %number of iterations for each actor
    io:fwrite("Number of actors = ~w~n",[X]),
    io:fwrite("Number of iterations per actor = ~w~n",[NumIterPerActor]),
    %Actors = lists:seq(1, X),   %generate desired number of actors
    %Pi1 = spawn(pi, montecarlo, [NumIterPerActor]),
    %Pi2 = spawn(pi, montecarlo, [NumIterPerActor]).
    ReceiverID = spawn(pi, addPi, [0, X, X]),
    assign(ReceiverID, X, NumIterPerActor).

assign(ReceiverID, 1, Iter)->
    spawn(pi, compute, [Iter, ReceiverID]);

assign(ReceiverID, X, Iter)->
    spawn(pi, compute, [Iter, ReceiverID]),
    assign(ReceiverID, X-1, Iter).

compute(Iter, ReceiverID)->
    Est = montecarlo(Iter),
    ReceiverID ! {Est}.

addPi(Pies, X, 0)->
    FinalPi = Pies/X,
    io:fwrite("Pi = ~w~n", [FinalPi]);

addPi(Pies, X, Rem)->
    receive
        {Estimate} ->
            addPi(Pies+Estimate, X, Rem-1)  
    end.

montecarlo(N)->
    montecarlo(N,0,0).

montecarlo(0,InCircle,NumPoints)->
    4*InCircle / NumPoints;
    %io:fwrite("Pi = ~w~n", [PiEst]);

montecarlo(N,InCircle,NumPoints)->
    Xcoord = rand:uniform(),
    Ycoord = rand:uniform(),
    montecarlo(N-1,if Xcoord*Xcoord + Ycoord*Ycoord < 1 -> InCircle + 1; true -> InCircle end,NumPoints + 1).
-模块(pi)。
-导出([montecarlo/1、montecarlo/2、assign/3、compute/2、addPi/3])。
蒙地卡罗(北,西)->
NumIterPerActor=N div X,每个参与者的迭代次数百分比
io:fwrite(“参与者数量=~w~n,[X]),
io:fwrite(“每个参与者的迭代次数=~w~n,[NumIterPerActor]),
%参与者=列表:seq(1,X),%生成所需数量的参与者
%Pi1=繁殖(pi,montecarlo,[NumIterPerActor]),
%Pi2=繁殖(pi,montecarlo,[NumIterPerActor])。
ReceiverID=spawn(pi,addPi,[0,X,X]),
分配(接收方ID、X、NumIterPerActor)。
分配(接收方ID,1,Iter)->
生成(pi、计算、[Iter、接收方]);
分配(接收方、X、Iter)->
生成(pi、计算、[Iter、接收方],
分配(接收方,X-1,Iter)。
计算(国际热核实验堆,接收方)->
Est=蒙特卡洛(Iter),
破产管理人!{Est}。
addPi(Pies,X,0)->
FinalPi=Pies/X,
io:fwrite(“Pi=~w~n,[FinalPi]);
addPi(Pies,X,Rem)->
接收
{估计值}->
addPi(Pies+估算,X,Rem-1)
结束。
蒙地卡罗(北)->
蒙特卡洛(N,0,0)。
蒙特卡洛(0,内圆,整数)->
4*内圆/内点;
%io:fwrite(“Pi=~w~n,[PiEst]);
蒙地卡罗(北,内圆,整数)->
Xcoord=rand:uniform(),
Ycoord=rand:uniform(),
蒙特卡洛(N-1,如果Xcoord*Xcoord+Ycoord*Ycoord<1->内圆+1;true->内圆结束,NumPoints+1)。

当您需要以迭代方式执行某些具有副作用的操作(如生成进程)时,
列表:foreach/2
似乎非常适合

您可以
map/2
NumIterPerActor
映射到
IterList
列表中,并使用
foreach/2
在其上迭代生成进程

montecarlo(N, X) ->
    NumIterPerActor = N div X,
    IterList = lists:map(fun(_) -> NumIterPerActor end, lists:seq(1, X)),
    lists:foreach(fun(IPA) -> spawn(?MODULE, montecarlo, [IPA]) end, IterList).

要回答上一个问题,请注意,在
map/2
foreach/2
中,您可以将任何函数调用包装在lambda函数中,并将相关参数传递给它。

您是否尝试过
列表:foreach/2
?感谢您的建议;我最终使用了递归(见编辑)(截止日期是几天前)。