-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...