跳轉到內容

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
華夏公益教科書