erlang 实现并行奇偶排序

来源:互联网 发布:苏州园区网络托管 编辑:程序博客网 时间:2024/04/30 05:42
-module (jiousort).-export ([start/2,handle/4]).% 测试数据:jiousort:start([15,11,9,16,3,14,8,7,4,6,12,10,5,2,13,1],4).% 将数据分给各个进程,并创建nodecreater([],Pids,_M,_Id,_Master) -> Pids;nodecreater([Hlist|TLists],Pids,M,Id,Master) ->Pid = spawn(?MODULE,handle,[Hlist,M,Id,Master]),nodecreater(TLists,[Pid|Pids],M,Id+1,Master).% 将列表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),ifPerLen <  Len ->NewData = lists:sublist(Data,PerLen+1,lists:flatlength(Data)-PerLen),dividing(NewData,PerLen,[Sublist|T]);true ->[Sublist|T]end.% 迭代交换奇偶数据loop(Data,0,_Id,_FrontPid,_NextPid) -> Data;loop(Data,M,Id,FrontPid,NextPid) ->A = M rem 2,B = Id rem 2,if A =:= B ->FrontPid ! {nextdata,Data,self()};true ->NextPid ! {frontdata,Data,self()}end, receive{nextdata,OtherData,From} ->if From =:= self() ->NewData = Data,loop(NewData,M-1,Id,FrontPid,NextPid);true ->NewData = lists:sublist(lists:sort(Data++OtherData),1,length(Data)),loop(NewData,M-1,Id,FrontPid,NextPid)end;{frontdata,OtherData,From} ->if From =:= self() ->NewData = Data,loop(NewData,M-1,Id,FrontPid,NextPid);true ->NewData = lists:sublist(lists:sort(Data++OtherData),length(OtherData)+1,length(Data)),loop(NewData,M-1,Id,FrontPid,NextPid)endend.handle(MyPart,M,Id,Master) ->% 对自己分的的数据进行排序MyData = lists:sort(MyPart),% 得到该进程后面进程的Idreceive{next,NextPid} ->NextPidend,% 得到该进程前面进程的Idreceive{front,FrontPid} ->FrontPidend,% 进行M次迭代Res = loop(MyData,M,Id,FrontPid,NextPid),Master ! {result,self(),Res}.% 逐次接收merge_inorder([],R) ->R;merge_inorder([Hid|Pids],R) ->receive{result,Hid,Res} ->merge_inorder(Pids,lists:append(R,Res))end.% 使进程知道紧接其的后续进程pidsendnextid(Pids) ->[Firstid|NewPids] = lists:reverse(Pids),sendgon(NewPids,Firstid,Firstid).sendfrontid([Firstid|NewPids]) ->sendgof(NewPids,Firstid,Firstid).sendgon([],ItsNextid,Ownid) -> Ownid ! {next,ItsNextid};sendgon([Nextid|Pids],ItsNextid,Ownid) ->Ownid ! {next,ItsNextid},sendgon(Pids,Ownid,Nextid).sendgof([],ItsFrontid,Ownid) -> Ownid ! {front,ItsFrontid};sendgof([Nextid|Pids],ItsFrontid,Ownid) ->Ownid ! {front,ItsFrontid},sendgof(Pids,Ownid,Nextid).start(Data,M) -> % 均匀划分[FirstPart|PartLists] = lists:reverse(divList(Data,M)), % 创建其他辅助进程Pids = lists:reverse(nodecreater(PartLists,[],M,2,self())),sendnextid([self()|Pids]),sendfrontid([self()|Pids]),% 对自己的数据进行处理MyData = lists:sort(FirstPart),receive{next,NextPid} ->NextPidend,receive{front,FrontPid} ->FrontPidend,FirstRes = loop(MyData,M,1,FrontPid,NextPid) ,Result = merge_inorder(Pids,FirstRes),io:format("~w~n",[Result]).

0 0
原创粉丝点击