跳转到内容

Erlang 编程/自治代理

来自维基教科书,开放的书籍,开放的世界

自治代理

[编辑 | 编辑源代码]

基于动态超时的主动权切换

[编辑 | 编辑源代码]

jungle.erl 代码解释

[编辑 | 编辑源代码]

这里我们有一个简单的聊天机器人代理,称为 person/4。我们创建了它的两个实例,称为 Tarzan 和 Jane。他们互相交谈。每个都有一个超时时间。超时时间是等待发起对话的时间长度。Jane 的初始超时时间设置为 10 秒。Tarzan 的初始超时时间设置为 8 秒。由于初始值,Tarzan 会先说话,Jane 会回应。两个超时时间都会重新开始,但保持相同的数值。再次,Tarzan 会先说话,Jane 会回应。现在事情变得有趣了。代理可以判断对话是否重复。如果对话重复,就会发送特殊的訊息来交换相对的超时时间级别。现在 Tarzan 比 Jane 等待的时间更长,Jane 有机会先说话。现在,Jane 会先说两次。然后他们再次交换主动权。由于进程是自治的,我们需要使用一个名为 jungle:quit() 的退出程序来停止它们。注意:超时时间长度的變化是翻倍或减半。超时时间變化类似于以太网冲突的指数二进制回退。外部链接:[1] 指数回退。

示例程序列表:jungle.erl

[编辑 | 编辑源代码]
-module( jungle ).
-compile(export_all).
   
%% This program shows how chat-bot agents can exchange initiative(lead) while in conversation.
%%   Start with start().
%%   End with quit().
 
start() ->
    register( tarzan, spawn( jungle, person, [ tarzan,  8000, "", jane ]   ) ),
    register( jane, spawn( jungle, person,   [ jane,   10000, "", tarzan ] ) ),
    "Dialog will start in 5ish seconds, stop program with jungle:quit().".
                                                                                         
quit() ->
    jane ! exit,
    tarzan ! exit.
 
%% Args for person/4
%%   Name:  name of agent being created/called
%%   T:     timeout to continue conversation
%%   Last:  Last thing said
%%   Other: name of other agent in conversation
  
person( Name, T, Last, Other ) ->
    receive
        "hi" -> 
            respond( Name, Other, "hi there \n " ),
            person( Name, T, "", Other );
        "slower" -> 
            show( Name, "i was told to wait more " ++ integer_to_list(round(T*2/1000))),
            person( Name, T*2, "", Other );
        "faster" -> 
            NT = round( T/2 ),
            show( Name, "I was told to wait less " ++ integer_to_list(round(NT/1000))),
            person( Name, NT, "", Other );
        exit ->
            exit(normal);
        _AnyWord -> 
            otherwise_empty_the_queue,
            person( Name, T, Last, Other )
    after T -> 
       respond( Name, Other, "hi"),
       case Last of
           "hi" ->
           self() ! "slower",
           sleep( 2000),                  % give the other time to print
           Other ! "faster",
           person( Name, T, "", Other );
       _AnyWord ->
           person( Name, T, "hi", Other )
       end
   end.
                                                                                             %
respond( Name, Other, String ) ->
    show( Name, String ),
    Other ! String.
                                                                                             %
show( Name, String ) ->
    sleep(1000),
    io:format( " ~s -- ~s \n ", [ Name, String ] ).
                                                                                             %
sleep(T) ->
    receive 
    after T ->
        done
    end.
% ===========================================================>%

来自 jungle.erl 的示例输出

[编辑 | 编辑源代码]
Sample output:
 	
 18> c(jungle).
 {ok,jungle}
  
 19> jungle:start().
 jane_and_tarzan_will_start_in_5_seconds
  
 tarzan—hi 
 jane—hi there 
 
 tarzan—hi 
 jane—hi there 
 
 jane—I was told to wait less: 5 
 tarzan—I was told to wait more: 16 
  
 jane—hi 
 tarzan—hi there 
 
 jane—hi 
 tarzan—hi there 
 
 tarzan—I was told to wait less: 8 
 jane—I was told to wait more: 10 
 
 tarzan—hi 
 jane—hi there 
 
 tarzan—hi 
 jane—hi there 
 
 jane—I was told to wait less: 5 
 tarzan—I was told to wait more: 16 
 
 jane—hi 
 tarzan—hi there 
 
20> jungle:quit(). 
exit
华夏公益教科书