erlang中并行快速排序的问题

时间:2010-09-04 18:54:23

标签: erlang

我在erlang中编写quicksort时遇到问题。我正在做的是我产生两个进程,然后阻止当前进程,直到我从左右子阵列得到响应。获取这两个响应后,我向其父级发送一条消息,为其提供计算列表。 Parent ! {self(), Lone ++ [H] ++ Ltwo}

但是我在两个子流程中都遇到了取消undef的错误。 这是代码。

  quick(Parent, []) -> Parent ! {self(), []};
  quick(Parent, [H | T]) ->
      Pone = spawn_link(main, quick, [ self(), [ X || X <- T, H >= X ] ]) ,
      Ptwo = spawn_link(main, quick, [ self(), [ Y || Y <- T, H < Y ] ]) ,
      receive
          {Pone, Lone} ->
              receive
                  {Ptwo, Ltwo} -> Parent ! {self(), Lone ++ [H] ++ Ltwo}
              end;
          {Ptwo, Ltwo} ->
              receive
                  {Pone, Lone} -> Parent ! {self(), Lone ++ [H] ++ Ltwo}
              end
      end.

  sortquick(List) ->
      quick(self(), List).

称为:

main:sortquick([12,4,7,22,25]).

3 个答案:

答案 0 :(得分:12)

代码本身不是问题。快速排序工作正常。原因可能是你在子进程中获得undef的原因是因为函数quick / 2根本没有被导出。当您使用模块和函数调用spawn_link时,需要导出该函数。

您可以通过添加

来解决此问题
-export([quick/2]).

或者将spawn_links更改为

spawn_link(fun() -> quick(Self, [Y || Y <- T, H < Y]) end

虽然如果你采用后一种方式,你需要创建一个变量

Self = self()

在您拨打电话之前,否则它将无法返回正确的流程。

答案 1 :(得分:1)

上面的代码通过导出quick / 2函数正常工作。

后来我比较了衍生的快速排序与未发布的快速排序的运行时间。 衍生的快速排序需要15秒到32秒之间的任意时间来排序范围内的100万个随机数列表(1,1000000)。

未公开的快速排序是(下面的代码):

 55 quicksort([]) -> [];
 56 quicksort([H]) -> [H];
 57 quicksort([H | T]) ->
 58     [Headnew | Tailnew] = [H | T],
 59     quicksort([ X || X <- Tailnew, Headnew >= X ]) ++ [Headnew] ++ quicksort([ Y || Y <- Tailnew, Headnew < Y ]).

需要5秒到8秒之间的任何时间来对100万个随机数的相同列表进行排序。

我在我的旧Thinkpad,1.7 Ghz处理器(单核)和512 Mb RAM上测试代码。

生成快速排序的任何解释都比没有生成的快速排序更差?

答案 2 :(得分:0)

我对代码稍作修改,以防止它产生到许多进程。当它在树中达到某个级别时,它会切换到顺序。

qsort([]) ->
    [];
qsort([H | T]) -> 
    qsort([ X || X <- T, X < H ]) ++ [H] ++ qsort([ X || X <- T, X >= H ]).

quick(Parent, [], _) -> Parent ! {self(), []};
quick(Parent, [H | T], C) when C > 0->
   Pone = spawn_link(test, quick, [ self(), [ X || X <- T, H >= X ], C-1 ]) ,
   Ptwo = spawn_link(test, quick, [ self(), [ Y || Y <- T, H < Y ], C-1 ]) ,
   receive
       {Pone, Lone} ->
              receive
                  {Ptwo, Ltwo} -> Parent ! {self(), Lone ++ [H] ++ Ltwo}
              end;
          {Ptwo, Ltwo} ->
              receive
                  {Pone, Lone} -> Parent ! {self(), Lone ++ [H] ++ Ltwo}
              end
      end;
quick(Parent, [H | T], _) -> 
    Parent ! {self(), qsort([ X || X <- T, X < H ]) ++ [H] ++ qsort([ X || X <- T, X >= H ])}.

sortquick(List) ->
    quick(self(), List, 4).