-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).
% 將資料分給各個程序,並建立
nodecreater(,pids) -> pids;
nodecreater([hlist|tlists],pids) ->
pid = spawn(?module,handle,[hlist]),
nodecreater(tlists,[pid|pids]).
% 將列表data 分成m份均勻的子列表
divlist(data,m) ->
len = lists:flatlength(data),
perlen = len div m,
dividing(data,perlen,).
dividing(data,perlen,t) ->
sublist = lists:sublist(data, perlen),
len = lists:flatlength(data),
if perlen < len ->
newdata = lists:sublist(data,perlen+1,lists:flatlength(data)-perlen),
dividing(newdata,perlen,[sublist|t]);
true ->
[sublist|t]
end.
% 將程序號列表 告知 所有程序
sendpids(pids,[h]) -> h ! ;
sendpids(pids,[h|t]) ->
h ! ,
sendpids(pids,t).
% 對資料進行取樣
getsample(mypart,m) ->
len = lists:flatlength(mypart),
perlen = len div m,
getsamples(mypart,perlen,).
getsamples(mypart,perlen,t) ->
[h|_t] = mypart,
len = lists:flatlength(mypart),
if perlen < len ->
newdata = lists:nthtail(perlen,mypart),
getsamples(newdata,perlen,[h|t]);
true ->
[h|t]
end.
% 接收其他程序的樣本
receivesample(0,sample) -> sample;
receivesample(m,sample) ->
receive
->
end.
% 從選出的樣本中找到新的樣本
finditem(data,m) ->
len = lists:flatlength(data),
perlen = len div (m+1),
newdata = lists:sublist(data,perlen+1,len-perlen),
finditems(newdata,perlen,).
finditems(data,perlen,t) ->
[h|_t] = lists:sublist(data,perlen),
len = lists:flatlength(data),
if perlen < len ->
newdata = lists:sublist(data,perlen+1,len-perlen),
finditems(newdata,perlen,[h|t]);
true ->
[h|t]
end.
% 告知其他程序主元
senditems(_items,) -> senditemsdone;
senditems(items,[hid|pids]) ->
hid ! ,
senditems(items,pids).
% 按主元進行劃分
partlist(mypart,items) ->
parting(mypart,items,).
parting(lastpart,,t) -> [lastpart|t];
parting(mypart,[h|items],t) ->
= ,parting(lastpart,items,[newpart|t]).
% 全域性交換列表,分成兩步先傳送完自己持有的列表,然後再開始接收
swap(lists,pids) ->
swapsend(lists,lists:reverse(pids)),
swapreceive(lists:flatlength(pids),).
% 傳送: 逐個取出各個列表和各個pid ,將對應列表發給對應程序
swapsend(,) -> swapdone;
swapsend([hlist|newpartlist],[hids|pids]) ->
hids ! ,
swapsend(newpartlist,pids).
% 接收
swapreceive(0,r) -> r;
swapreceive(m,r) ->
receive
->
swapreceive(m-1,[otherlist|r])
end.
% 對排好序的小列表的列表 進行歸併排序
merge_sort(sortedlists) ->
lists:sort(newlist).
% 逐次給輔助程序傳送輸出訊號
merge_inorder(,r) ->r;
merge_inorder([hid|pids],r) ->
receive
->
end.
% 主程序 與輔助程序的區別 主要在取樣 是由主程序做,以及其他協調工作
start(data,m) ->
% 均勻劃分
[firstpart|partlists] = lists:reverse(divlist(data,m)),
%io:format("~w~n",[firstpart|partlists]),
% 建立其他輔助程序
pids = nodecreater(partlists,),
% 使全部程序都知道其他程序的程序號,後來的全域性交換需要
sendpids([self()|pids],pids),
sortlist = lists:sort(firstpart),
sample = getsample(sortlist,m),
% 接收其他程序的樣本,排序選出主元
newsample = receivesample(m-1,sample),
sortsample = lists:sort(newsample),
items = lists:reverse(finditem(sortsample,m-1)),
% 告知其他程序主元
senditems(items,pids),
% 按主元進行劃分
newpartlist = partlist(firstpart,items),
% 全域性交換
sortlists = swap(newpartlist,[self()|pids]),
newsortlist = merge_sort(sortlists),
result = merge_inorder(pids,newsortlist),
io:format("~w~n",[result]).
% 輔助程序
handle(mypart) ->
sortlist = lists:sort(mypart),
% 接受其他程序的pids
receive
->
[master|_pids] = ppids
end,
m = lists:flatlength(ppids),
% 找出樣本
sample = getsample(sortlist,m),
% 向主程序傳送樣本
master ! ,
% 接收主程序篩選出的主元
receive
->
items
end,
newpartlist = partlist(mypart,items),
% 全域性交換
sortlists = swap(newpartlist,ppids),
% 歸併排序
erlang 實現並行快速排序
在保證尾遞迴的情況下,使用乙個輔助函式 handl 對parallel qsort進行包裝,則parallel qsort只管 分發任務即可,計算好了 再進行樹形通訊合併,之前一直在糾 結於是不是要使用程序字典,來儲存有哪些程序,程序字典,在erlang program一書中,不建議採用,因為其提供...
Erlang 奇偶並行排序
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...
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...