Erlang 奇偶並行排序

2021-07-02 18:21:06 字數 4858 閱讀 9967

-module

(exe9)

. -export

([start/2,handle/4])

. % l=[2,12,14,25,31,42,43,43,13,34,34,41,41,312,352,354].

% 將資料分給各個程序,並建立

nodecreater

(,pids,m,id,master) ->

io:format("pids:~w id:~w master:~w~n",[pids,id,master]),

lists:reverse(pids);

nodecreater

([hlist|tlists],pids,m,id,master) ->

io:format("pids:~w id:~w master:~w~n",[pids,id,master]),

pid = spawn(?module,handle,[hlist,m,id,master]),

nodecreater(tlists,[pid|pids],m,id+1,master).

% 迭代交換奇偶資料

% 策略:當m是偶數時,id 為奇數時,此core從他後面的core接受資料,再進行排序,再將結果等分成兩部分,並將後半部分返回給

% 傳送者,傳送者接收到資料後進入下輪迭代,本核進入下一輪迭代。

% 當m是奇數時,id=1或者id=core數時,直接進入下一輪。

% id為偶數時時(除去id為1和core數時),此core從他後面的core接受資料,再進行排序,再將結果等分成兩部分,並將後半部分返回給

% 傳送者,傳送者接收到資料後進入下輪迭代,本核進入下一輪迭代

% loop

(data,1,id,_frontpid,_nextpid,coren) ->

io:format("id:~w res:~w ~n",[id,data]),

data;

loop

(data,m,id,frontpid,nextpid,coren) ->

io:format("data:~w m:~w id:~w ~n",[data,m,id]),

if% m為偶數時

mrem

2 =:= 0 ->

if %id為奇數

idrem

2 =:=1 ->

receive

->

sorteddata = lists:sort(mergedata),

lenper=length(sorteddata) div

2, frontdata = lists:sublist(sorteddata,lenper),

taildata = lists:sublist(sorteddata,lenper+1,lenper),

nextid !,

loop(frontdata,m-1,id,frontpid,nextid,coren)

end;

%id為偶數

true ->

frontpid!,

receive

->

loop(mydata,m-1,id,frontpid,nextpid,coren)

endend;

true ->

if(id =:= 1) or (id =:= coren) ->

loop(data,m-1,id,frontpid,nextpid,coren);

true ->

ifid

rem2 =:= 0 ->

receive

->

sorteddata = lists:sort(mergedata),

lenper=length(sorteddata) div

2, frontdata = lists:sublist(sorteddata,lenper),

taildata = lists:sublist(sorteddata,lenper+1,lenper),

nextid !,

loop(frontdata,m-1,id,frontpid,nextid,coren)

end;

true -> frontpid!,

receive

->

loop(mydata,m-1,id,frontpid,nextpid,coren)

endendend

end.

handle

(mypart,m,id,master) ->

% 對自己分的的資料進行排序

mydata = lists:sort(mypart),

io:format("handle id:~w data:~w ~n",[id,mydata]),

% 得到該程序後面程序的id

receive

->

nextpid

end,

% 得到該程序前面程序的id

receive

->

frontpid

end,

% 進行m次迭代

res = loop(mydata,m,id,frontpid,nextpid,m),

master ! .

% 逐次接收

merge_inorder

(,r) ->

r;

merge_inorder

([hid|pids],r) ->

receive

->

end.

% 使程序知道緊接其的後續程序pid

sendnextid

(pids) ->

[firstid|newpids] = lists:reverse(pids),

sendgon(newpids,firstid,firstid).

sendgon

(,itsnextid,ownid) ->

%io:format("ownid:~w nextpid:~w~n",[ownid,itsnextid]),

ownid ! ;

sendgon

([nextid|pids],itsnextid,ownid) ->

%io:format("ownid:~w nextpid:~w~n",[ownid,itsnextid]),

ownid ! ,

sendgon(pids,ownid,nextid).

% 使程序知道它前面的程序是什麼

sendfrontid

([firstid|newpids]) ->

sendgof(newpids,firstid,firstid).

sendgof

(,itsfrontid,ownid) ->

%io:format("ownid:~w frontpid:~w~n",[ownid,itsfrontid]),

ownid ! ;

sendgof

([nextid|pids],itsfrontid,ownid) ->

%io:format("ownid:~w frontpid:~w~n",[ownid,itsfrontid]),

ownid ! ,

sendgof(pids,ownid,nextid).

%將data分成m份

divlist

(data,m)->

len = length(data),

perlen = len

divm,

prodiv(data,perlen,m,).

prodiv

(data,perlen,1,l) ->

lists:reverse([data|l]);

prodiv

(data,perlen,m,l) ->

len=length(data),

sub = lists:sublist(data,perlen),

res = lists:sublist(data,perlen+1,len-perlen),

prodiv(res,perlen,m-1,[sub|l]).

start

(data,m) ->

% 均勻劃分

[firstpart|partlists] = divlist(data,m),

io:format("after div:~n~w~n",[[firstpart|partlists]]),

% 建立其他輔助程序

pids = nodecreater(partlists,,m,2,self()),

io:format("pids:~w~n",[pids]),

sendnextid([self()|pids]),

sendfrontid([self()|pids]),

% 主線程的id為1,對自己的資料進行處理.

mydata = lists:sort(firstpart),

receive

->

nextpid

end,

receive

->

frontpid

end,

firstres = loop(mydata,m,1,frontpid,nextpid,m),

result = merge_inorder(pids,firstres),

io:format("~w~n",[result]).

erlang 實現並行快速排序

在保證尾遞迴的情況下,使用乙個輔助函式 handl 對parallel qsort進行包裝,則parallel qsort只管 分發任務即可,計算好了 再進行樹形通訊合併,之前一直在糾 結於是不是要使用程序字典,來儲存有哪些程序,程序字典,在erlang program一書中,不建議採用,因為其提供...

erlang 實現psrs 並行排序演算法

module psrs export start 2,handle 1 測試資料 psrs start 15,46,48,93,39,6,72,91,14,36,69,40,89,61,97,12,21,54,53,97,84,58,32,27,33,72,20 3 將資料分給各個程序,並建立 no...

Erlang 並行梯度積分法

這個 寫了兩天,從沒思路到有思路,還好最終搞定了 不過這個程序數必須為2 n個。先貼乙個執行截圖 子程序求部分和 child proces f,x1,width,0,sum,n1 io format p s result is p n self sum loop send get sum child...