2007/07/27

[Erlang] 待ち行列問題

情報処理試験でよくでてくる待ち行列問題を Erlang でシミュレートしようと思ってやってみました。
でも、ポアソン分布を理解してないためか、思ったような結果になりまんでした。また今度勉強しなおして挑戦してみます。
とりあず、コードは次のとおり。このてのものは Erlang だと書きやすいですね。


-module(wait).
-compile(export_all).

-define(SIZE, 200).

start() ->
case whereis('行列') of
undefined ->
ok;
_ ->
unregister('行列')
end,
register('行列', spawn(?MODULE, '行列', [[]])),
spawn(?MODULE, '窓口', []),
List = lists:map(
fun(_) ->
Sleep = random:uniform(100),
io:format("間隔 ~p~n", [Sleep]),
timer:sleep(Sleep),
spawn(?MODULE, 'お客さん', [self()])
end,
lists:seq(1, ?SIZE)),
Avg = lists:foldl(fun(X, Acc) ->
receive
{Time, X} ->
Time + Acc
end
end,
0,
List) / ?SIZE,
io:format("平均 ~p~n", [Avg]).

'お客さん'(From) ->
Start = now(),
'行列' ! {'並ぶ', self()},
receive
'おつかれさま' ->
ok
end,
Time = timer:now_diff(now(), Start),
io:format("~p~n", [Time]),
From ! {Time, self()}.

'行列'([]) ->
io:format("行列の長さ 0~n"),
receive
{'並ぶ', From} ->
'行列'([From])
end;
'行列'(Queue) ->
io:format("行列の長さ ~p~n", [length(Queue)]),
receive
{'次の方', From} ->
Last = lists:last(Queue),
From ! Last,
'行列'(Queue -- [Last]);
{'並ぶ', From} ->
'行列'([From|Queue])
end.

'窓口'() ->
'行列' ! {'次の方', self()},
receive
From ->
timer:sleep(40),
From ! 'おつかれさま'
end,
'窓口'().

0 件のコメント: