0

これは、Erlang の経験がある人にとってはおそらく簡単なことですが、私にはありません。プロセスのフィボナッチ ツリーを作成しようとしています。次に、メッセージを受け取り、そのメッセージを渡したノードの下にあるすべてのノードの合計を計算できます。

create_fibtree(N) when N > 1 ->
Child1 = spawn(fun() -> create_fibtree(N-1) end),
Child2 = spawn(fun() -> create_fibtree(N-2) end),

receive 
    Sum ->
        Child1 ! sum + 1,
        Child2 ! sum + 1,
        io:format ("sum is ~p.~n", [Sum])
end;
create_fibtree(N) when N =< 1 ->
    ok.

これを実行すると:

c(fib_tree2).
{ok,fib_tree2}
2> fib_tree2:create_fibtree(10).

Erlang コンソールがハングします。理由がわかりませんが、受信句が正しくありますか?

はい、これは宿題です。先生は今週不在です。そのため、インターネットで代役を探しています。

4

2 に答える 2

1

そうです、 receive 句はメッセージをまったく受信しないため、関数をブロックします。しかし、このコードは一般に、fib 数を計算するのにあまり適した方法ではありません。生成プロセスを必要とせずに、単純な再帰関数で実行できます。

PS Child1 ! sum + 1は、アトムと整数を追加しようとすると失敗します

于 2012-11-19T22:08:28.513 に答える
1

最初のメッセージが必要です。私も割り当てを持っているので、いくつかのヒントを入れることができます:

  • ツリーの作成を合計計算から分離するようにしてください。ツリーを作成してから、メッセージを送受信する別の関数に移動します。

  • メッセージを受信するには、誰かがメッセージを送信する必要があります。

  • メッセージがどの方向に渡されるかについて混乱しているようです。おそらく、1 つのメッセージをツリーの下方向 (ノードを数えていることを子供たちに伝えるため) と、別のメッセージ (各ノードからの結果) をツリーの上方向に送信する必要があります。アルゴリズムの提案は次のとおりです。

各ノードで:

  1. 両方の子にメッセージを送信します{get_sum, Id, Pid}。ここで Id はランダムな一意の識別子です。たとえば、now/0関数からのもので、Pidからのものself/0です。
  2. フォームで正確に 2 つの回答 (各子供から 1 つ) を受け取ります ({sum, Id, Sum}Id以前と同じです)。
  3. 2 つの合計が加算され、現在のノードに 1 を加算します。
  4. 答えをツリーの親に送り返します。

このタイプのトラブルシューティングに最適なErlang デバッガーをチェックしてください。

> c(modulename, [debug_info]).
> debugger:start().
(Module -> Interpret -> Pick the .erl file for the module you just compiled)
于 2012-11-19T22:43:50.080 に答える