extensions [table] breed [nodes node] breed [walkers walker] breed [halos halo] globals [message_box seconds regions_hash_table update_clock? total_messages_counter searching_messages_counter ack_messages_counter notifications_messages_counter ;; needed for zrp procative updates lost_messages_counter average_messageBufferSize algorithm ] ;;we assume 3 skills (A,B,C) walkers-own [ ID location range skills_list ;;own the skills needs_list ;; need another walker with skill founds_list ;;matched items caption current_groupRow ;;indexer for containing region (column and row) current_groupCol old_groupRow ;; old position in previous tick old_groupCol recieved_messagesBufferList ;; messages recived to reply or broadcast requests ;; requests not replied yet has_send_last_request? is_waiting_reply? ;;is waiting for reply to a broadcasted request max_tick_to_wait ;; max timestamp to wait for myHandledRequests ;; hashtable of returned responses (timestamp, filled (yes,no, partial)) failed_requests_count ;; requests failed partial_success_count ;; partial success succeeded_requests_count ;; requests achieved original_requirements_to_restore; the original requirements list to restore from (reset in place) has_recieved_at_least_one_response? ;; needed to distinguis complete failure from partial failure (success) original_x original_y zoneSkillsHashTable temp_distance ;; volatile field (temporay) for sorting and zone calculations only myNeighborsConnectionLife ;;hashtable of connection times in ALARAM ] ;; holds a node nodes-own [groupx groupy ] ;;========================================================= to restore_requests_to_original ask walkers [ set failed_requests_count 0 set succeeded_requests_count 0 set partial_success_count 0 set max_tick_to_wait 0 ;; no waiting so far set is_waiting_reply? false ;;init lists set requests (list) set skills_list (list) set needs_list (list) set founds_list (list) set recieved_messagesBufferList (list) set myHandledRequests table:make ;; empty hash table set needs_list original_requirements_to_restore ;restore set zoneSkillsHashTable table:make set has_recieved_at_least_one_response? false set xcor original_x ;restore location set ycor original_y ] clear-output reset-timer set seconds 0 set update_clock? true init_messages_counters reset-ticks end ;=============================================== to setup [ need_proactiveMessages?] clear-all ;; the "thin ring" shape was made using the shapes editor; set-default-shape halos "thin ring" set-default-shape nodes "hex" ;; --------create a hex grid of nodes ask patches [ sprout-nodes 1 [ set color white ;; dark gray set size 1.4 ;; shift even columns down if pxcor mod 2 = 0 [ set ycor ycor - 0.5 ] ] ] ;; ---------connect the nodes to make a lattice ask nodes [ ifelse pxcor mod 2 = 0 [ create-links-with nodes-on patches at-points [[0 1] [1 0] [1 -1]] ] [ create-links-with nodes-on patches at-points [[0 1] [1 1] [1 0]] ] ] ask links [ hide-link ] ;;----------Hex Nodes --------------- ask patches with [pxcor mod GridWidth = 0 OR pycor mod GridWidth = 0] [set pcolor gray ] ask nodes with [pxcor mod GridWidth = 0 OR pycor mod GridWidth = 0 ] [ set shape "hex_border"] ask nodes [ set groupx floor (pxcor / GridWidth) set groupy floor (pycor / GridWidth) ] ;; put some "walker" turtles on the lattice create-walkers Count_of_Walkers [ set color blue set location one-of nodes set range 1 + random MaxRange move-to location set failed_requests_count 0 set succeeded_requests_count 0 set partial_success_count 0 set max_tick_to_wait 0 ;; no waiting so far set is_waiting_reply? false ;;init lists set requests (list) set skills_list (list) set needs_list (list) set founds_list (list) set recieved_messagesBufferList (list) set original_requirements_to_restore (list) set myHandledRequests table:make ;; empty hash table set zoneSkillsHashTable table:make set myNeighborsConnectionLife table:make set has_recieved_at_least_one_response? false ] ;;----------put halo ask walkers [make-halo range] let ID_start 0 ask walkers [ set ID ID_start set ID_start ID_start + 1 set original_x xcor set original_y ycor ] set regions_hash_table table:make ask walkers [ set current_groupCol floor (xcor / GridWidth) set current_groupRow floor (ycor / GridWidth) register_walker_to_region current_groupCol current_groupRow ID ] ;;------------- random samples for skills let quarter floor (Count_of_Walkers / 4) if queryGeneratorsCount > Count_of_Walkers [ set queryGeneratorsCount Count_of_Walkers] ;;sample data set init_messages_counters ;;init ask n-of quarter walkers [ set skills_list ["A" "B" "D"] ; proactive_update_zone [ node_id skills zoneRow zoneCol] ;notifiy region with updates if need_proactiveMessages?[ proactive_update_zone ID skills_list current_groupRow current_groupCol ]] ask n-of queryGeneratorsCount walkers [ ifelse best_case? [set needs_list ["A" "B" "C" "D" ]] [ set needs_list ["A" "B" "C" "NO"] ] set original_requirements_to_restore needs_list ;keep to restore later ] ask n-of quarter walkers [ set skills_list ["A" "C"] if need_proactiveMessages?[ proactive_update_zone ID skills_list current_groupRow current_groupCol ]] ask n-of quarter walkers [ set skills_list [ "B" "C"] if need_proactiveMessages?[ proactive_update_zone ID skills_list current_groupRow current_groupCol ]] ;;;FOR DEBUGGING ONLY ; let III 0 ; ask n-of 1 walkers [ set needs_list ["A" "B"] ; show who ; show ID ; set III who] ; ask n-of quarter walkers [ set skills_list ["A" "B" "C"] ] ; ask walkers with [ not empty? needs_list] [set color green] ; watch walker III reset-timer set seconds 0 set update_clock? true reset-ticks end ;------------------------------------------ to init_messages_counters set total_messages_counter 0 set searching_messages_counter 0 set ack_messages_counter 0 set lost_messages_counter 0 set notifications_messages_counter 0 end ;;===================================== ;; returns new message for algorithm start ;to-report generate-new-row-message [ source source_id ttl request_time_stamp requirementsList messageType] ; let t1 table:make ;;empty table row ; table:put t1 "source" source ; table:put t1 "requesterID" source_id ; table:put t1 "ttl" ttl ; table:put t1 "type" messageType ;;"searching" or "ack" ; table:put t1 "requirements_vector" requirementsList ;; current unstastified needed skills ; table:put t1 "original_requirements_vector" requirementsList ;; needed skills (to restor to compare another algorithm) ; table:put t1 "match_vector" (list) ;; found matches so far ; table:put t1 "provider_nodes" (list) ;; nodes that provides found matches ; table:put t1 "path_nodes" (list) ; table:put t1 "source_region" (list);; row , col of source node ; table:put t1 "request_timestamp" request_time_stamp ;; time of original request ; table:put t1 "returnBackPath" (list) ; table:put t1 "is_broken_return_path?" false ;true if ack message finds return path changed (e.g.move of intermediate nodes) ; report t1 ;; return message row ;end ;======================================================= to-report generate-new-row-message_zrp [ source source_id ttl request_time_stamp requirementsList messageType region_Row region_Col] let t1 table:make ;;empty table row table:put t1 "source" source table:put t1 "requesterID" source_id table:put t1 "ttl" ttl table:put t1 "type" messageType ;;"searching" or "ack" table:put t1 "requirements_vector" requirementsList ;; current unstastified needed skills table:put t1 "original_requirements_vector" requirementsList ;; needed skills (to restor to compare another algorithm) table:put t1 "match_vector" (list) ;; found matches so far table:put t1 "provider_nodes" (list) ;; nodes that provides found matches table:put t1 "path_nodes" (list) table:put t1 "source_region" (list region_Row region_Col);; row , col of source node table:put t1 "request_timestamp" request_time_stamp ;; time of original request table:put t1 "returnBackPath" (list) table:put t1 "is_broken_return_path?" false ;true if ack message finds return path changed (e.g.move of intermediate nodes) report t1 ;; return message row end ;================================================== ;to-report getEquivalentTotalMatchForMessageSoFar [currentMessage myHandledRequestsHashTable] ; let timestamp table:get currentMessage "request_timestamp" ; ;;test if another node replied to same request ; ifelse table:has-key? myHandledRequestsHashTable timestamp ; [ ; let oldRow table:get myHandledRequestsHashTable timestamp ; let oldMatch table:get oldRow "match_vector" ; report oldMatch ; ] ; [report (list)] ;end ;;=============================================== to-report addToHandledHashTable [currentMessage myHandledRequestsHashTable] ;get request_timestamp of message let timestamp table:get currentMessage "request_timestamp" ;;test if another node replied to same request ifelse table:has-key? myHandledRequestsHashTable timestamp [ let oldRow table:get myHandledRequestsHashTable timestamp ;;merge ;get current message content let currentMatch table:get currentMessage "match_vector" let currentProviders table:get currentMessage "provider_nodes" ;old let oldtMatch table:get oldRow "match_vector" let oldProviders table:get oldRow "provider_nodes" ;SIMPLE but not perfect (TODO: enhance and more special cases) let at_least_one_extra? false foreach currentMatch [ if not member? ? oldtMatch [ set oldtMatch lput ? oldtMatch set at_least_one_extra? true ] if at_least_one_extra? [ table:put oldRow "match_vector" oldtMatch ;;prepare union of providers foreach currentProviders [ if not member? ? oldProviders [ set oldProviders lput ? oldProviders]] table:put oldRow "provider_nodes" oldProviders ;replace old row table:put myHandledRequestsHashTable timestamp oldRow ] ] ] [ ;else ;add as first response let cumulativeResult table:make ;store original requirements let org_requirements table:get currentMessage "original_requirements_vector" table:put cumulativeResult "original_requirements_vector" org_requirements ;;consider match vector of message as cummulative table:put cumulativeResult "match_vector" table:get currentMessage "match_vector" table:put cumulativeResult "provider_nodes" table:get currentMessage "provider_nodes" table:put myHandledRequestsHashTable timestamp cumulativeResult ] ;;toDO : count failures, partials, and successes ; let oldRow table:get myHandledRequestsHashTable timestamp let original table:get oldRow "original_requirements_vector" let oldtMatch table:get oldRow "match_vector" let oringinalCount length original let resultedCount length oldtMatch ifelse oringinalCount = resultedCount ;;total success [ table:put oldRow "eval" "total_success" report "success" ] [ if resultedCount = 0 ;;failed [ table:put oldRow "eval" "partial" report "partial" ] ] ; ; end ;;============================================== ;update success-partial-failed counters to update-eval-counters ;partial_success_count ;; partial success ;succeeded_requests_count ; ask walkers [ ;;get all stores timestamped so far let p 0 ;partial let s 0 ;success let keys table:keys myHandledRequests foreach keys [ let row table:get myHandledRequests ? ; timestamp as key let eval table:get row "eval" ifelse eval = "total_success" [ set s s + 1] [set p p + 1 ] ] set partial_success_count p set succeeded_requests_count s if p > 0 or s > 0 [set has_recieved_at_least_one_response? true] ] end ;============================================== ;update nodes inside region to proactive_update_zone [ node_id skills zoneRow zoneCol] ask walkers with [ current_groupRow = zoneRow and current_groupCol = zoneCol] [ ;increase notifications & total messages count set notifications_messages_counter notifications_messages_counter + 1 set total_messages_counter total_messages_counter + 1 ;merge skills foreach skills [ ifelse table:has-key? zoneSkillsHashTable ? ;does hashTable contains that current skill [ ;add let currentlist table:get zoneSkillsHashTable ? set currentlist lput node_id currentlist table:put zoneSkillsHashTable ? currentlist ] [;new skill table:put zoneSkillsHashTable ? (list node_id) ] ] ] end ;======================================== to-report getZoneSkillsHashTable[ zoneRow zoneCol] ask one-of walkers with [ current_groupRow = zoneRow and current_groupCol = zoneCol] [report zoneSkillsHashTable] end ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ;;move messages between nodes ;MAIN Protocol method to update_messages_alarm [ AAge_threshold] ;;********************************* ACK SECTION ;;handle ack messages ask walkers with [ not empty? recieved_messagesBufferList ] [ ;;extract forward or self messages let copyRecievedMessage recieved_messagesBufferList;; clone of list to avoid loop-and-delete problems foreach copyRecievedMessage [ let tType table:get ? "type" show ( word "message type:---------------------------------" tType) ;;_______________________________________________ if tType = "ack" ;;acknowlege [ ifelse table:get ? "is_broken_return_path?" = false ; return path still valid [ let currentMessage ? set recieved_messagesBufferList remove ? recieved_messagesBufferList ;;remove from list ;;test if message to this node let destID table:get currentMessage "requesterID" ;;get request source ifelse destID = ID ;; this.id [ show "reply to me" if is_waiting_reply?;if waiting then process response, else drop out dated message [ ;;mark this message as returned handled request set is_waiting_reply? false let eval addToHandledHashTable currentMessage myHandledRequests if eval = "success" [;no more waiting set max_tick_to_wait 0 set is_waiting_reply? false ] ];;if waiting ] [ ;;else (request to forward) (message not to me) ;;----------------------------forwarding ;;note: Difference from normal routing is trial to go in reverse path if still available let toForwardMessage clone_table ? ;; get neighbors let n ObtainMyNeighbors_alarm AAge_threshold ;; get next to go back node id let rPath table:get toForwardMessage "returnBackPath" ;remove me from reverse path set rPath remove ID rPath table:put toForwardMessage "returnBackPath" rPath show (word "reverse path" rPath ", neighbors:" n) if not empty? rPath [ ;obtain next from path let next first rPath let nextN n with [ ID = next ] ifelse any? nextN ;; if previous node is still neihgbor, forward to it [ ask nextN [ ;;decrease ttl let stillValid? not decrease_ttl_of_message toForwardMessage ifelse stillValid? [ ;;send set recieved_messagesBufferList lput clone_table toForwardMessage recieved_messagesBufferList ;increase counters set total_messages_counter total_messages_counter + 1 set ack_messages_counter ack_messages_counter + 1 ] [ show "lost reply" set total_messages_counter total_messages_counter + 1 set lost_messages_counter lost_messages_counter + 1 ] ];;ask ] [;;else ;;TODO: HANDLE return NEIBoIRs has dispeared and need to broadcast table:put toForwardMessage "is_broken_return_path?" true ;; ;; ;; ;; show "need new routing for callback response,possible mobile node(s) location change, broadcast to neighbors" ;;TOdo: simplified broadcast to neighbors ask n [ ;;decrease ttl let stillValid? not decrease_ttl_of_message toForwardMessage ifelse stillValid? [ ;;send set recieved_messagesBufferList lput clone_table toForwardMessage recieved_messagesBufferList ;increase counters set total_messages_counter total_messages_counter + 1 set ack_messages_counter ack_messages_counter + 1 ] [ show "lost reply" set total_messages_counter total_messages_counter + 1 set lost_messages_counter lost_messages_counter + 1 ] ];;ask ] ];;if not empty rPath ] ];if not broken [;else broken return path ;; get neighbors let n ObtainMyNeighbors_alarm AAge_threshold show "need new routing for callback response,possible mobile node(s) location change, broadcast to neighbors" ;;TOdo: simplified broadcast to neighbors let toForwardMessage ? ask n [ ;;decrease ttl let stillValid? not decrease_ttl_of_message toForwardMessage ifelse stillValid? [ ;;send set recieved_messagesBufferList lput clone_table toForwardMessage recieved_messagesBufferList ;increase counters set total_messages_counter total_messages_counter + 1 set ack_messages_counter ack_messages_counter + 1 ] [ show "lost reply" set total_messages_counter total_messages_counter + 1 set lost_messages_counter lost_messages_counter + 1 ] ];;ask ] ];if type == ACK ];;foreach ];;ask about ACK ;************************************************************ ;;______________________________________________ ;;********************************* Searching SECTION ;; send requests for the first time ask walkers with [ not empty? requests] [ ;; get neighborsdone let n ObtainMyNeighbors_alarm AAge_threshold let messageToTransfer first requests ;;don't remove from list ;;decrease ttl let expires? decrease_ttl_of_message messageToTransfer set max_tick_to_wait ticks + 2 * requests_ttl_value; set timeout ;add current node to path ; addNodeToPath messageToTransfer ID current_groupRow current_groupCol ifelse not expires? and table:get messageToTransfer "type" = "searching" [ ask n [ ;commented: adding next future node to path c ;;addNodeToPath [ message_table nodeID regionRow regionCol ] ;addNodeToPath messageToTransfer ID current_groupRow current_groupCol ;;send message (clone to next hop) set recieved_messagesBufferList lput clone_table messageToTransfer recieved_messagesBufferList show "clone to next hop" ;increase counters set total_messages_counter total_messages_counter + 1 set searching_messages_counter searching_messages_counter + 1 ] ] [ ;;else show "dropping expired message" ] ;; remove from queue set requests remove messageToTransfer requests ];ask for first time request sending ;;_________________________________________________ ;; TODO : forward or process recieved messages ;; ;; ;; ;;try ask walkers with [ not empty? recieved_messagesBufferList] [ ;; get neighbors let n ObtainMyNeighbors_alarm AAge_threshold ;; nieghbors in paths let copuOfRecivedMessages recieved_messagesBufferList ;; clone to avoid deletion in loop-list foreach copuOfRecivedMessages [ let messageToTransfer clone_table ? show (word "message type:________" table:get messageToTransfer "type") if table:get messageToTransfer "type" = "searching" [ ;;remove message from future processing in same pc set recieved_messagesBufferList remove messageToTransfer recieved_messagesBufferList ;;TODO ; process requirements for skills let currentNeeds table:get messageToTransfer "requirements_vector" let filteredNeeds match_skills_to_requirementsList currentNeeds skills_list ;;MATCHING table:put messageToTransfer "requirements_vector" filteredNeeds ;;test if at least 1 requirement is filled if length currentNeeds != length filteredNeeds [ AddNodeToProvidersList messageToTransfer ID ];; add me as provider addNodeToPath messageToTransfer ID current_groupRow current_groupCol let completePath table:get messageToTransfer "path_nodes" ;;to go back move from first to last in reverse list table:put messageToTransfer "returnBackPath" reverse completePath ifelse length filteredNeeds = 0 ;; no more unsatified needs [ ;;if show ( word ID ":full stistfaction, returning to source" table:get messageToTransfer "requesterID") ;;to do reply table:put messageToTransfer "type" "ack" ;;back to recived message if table:get messageToTransfer "ttl" > 0 [ set recieved_messagesBufferList lput clone_table messageToTransfer recieved_messagesBufferList] ;table:put messageToTransfer "ttl" requests_ttl_value ;;re-new ttl ] [ ;; else not full satisfaction ;;get path nodes let pathList getMessagePathList messageToTransfer show (word ID "sending to " pathList ", neighbors are:" n) ;;exclude previous nodes in each message path to avoid loops let newNeighbors n with [ not member? ID pathList] ifelse not any? newNeighbors ;; dead end [ ;;if show "dead end,returning back" ;;to do reply table:put messageToTransfer "type" "ack" table:put messageToTransfer "ttl" requests_ttl_value ;;re-new ttl ;add back to messages list to send later set recieved_messagesBufferList lput clone_table messageToTransfer recieved_messagesBufferList ] [ ;else (not dead end) let current_ttl table:get messageToTransfer "ttl" ifelse current_ttl <= 0 [ show "dropping expired request" ] [ ;else ;not expired request ;;else ;;addNodeToPath [ message_table nodeID regionRow regionCol ] addNodeToPath messageToTransfer ID current_groupRow current_groupCol ;;decrease ttl let expires? decrease_ttl_of_message messageToTransfer if not expires? [ ask newNeighbors [ ;;send message set recieved_messagesBufferList lput clone_table messageToTransfer recieved_messagesBufferList show "forwarding message" ;increase counters set total_messages_counter total_messages_counter + 1 set searching_messages_counter searching_messages_counter + 1 ] ] ];else note expired request ] ;;TODO: handle replies "ack" ;; ;; ;; ;; ] ; else not satisfaction ];;not ack ] ] ;********************************************************* ;; TODO process request of requirements vs skills *provide needs* ask walkers with [ max_tick_to_wait > 1 and max_tick_to_wait < ticks ] [ if table:length myHandledRequests = 0 [ ;;drop request (timeout) show "timeout of waiting" ] set max_tick_to_wait 0 ;;exclude first in queue (actually not needed in the current scope of simulation) if not empty? requests [ set requests but-first requests] if not has_recieved_at_least_one_response? ;due to a problem in simulation, this extra condition is tested [ ;increase failures set failed_requests_count failed_requests_count + 1 ] set is_waiting_reply? false ] ;update countes update-eval-counters end ;;+++++++++++++++++++++++++++++++++++++++++++++++++++++= to update_messages ;;********************************* ACK SECTION ;;handle ack messages ask walkers with [ not empty? recieved_messagesBufferList ] [ ;;extract forward or self messages let copyRecievedMessage recieved_messagesBufferList;; clone of list to avoid loop-and-delete problems foreach copyRecievedMessage [ let tType table:get ? "type" show ( word "message type:---------------------------------" tType) ;;_______________________________________________ if tType = "ack" ;;acknowlege [ ifelse table:get ? "is_broken_return_path?" = false ; return path still valid [ let currentMessage ? set recieved_messagesBufferList remove ? recieved_messagesBufferList ;;remove from list ;;test if message to this node let destID table:get currentMessage "requesterID" ;;get request source ifelse destID = ID ;; this.id [ show "reply to me" if is_waiting_reply?;if waiting then process response, else drop out dated message [ ;;mark this message as returned handled request set is_waiting_reply? false let eval addToHandledHashTable currentMessage myHandledRequests if eval = "success" [;no more waiting set max_tick_to_wait 0 set is_waiting_reply? false ] ];;if waiting ] [ ;;else (request to forward) (message not to me) ;;----------------------------forwarding ;;note: Difference from normal routing is trial to go in reverse path if still available let toForwardMessage clone_table ? ;; get neighbors let n ObtainMyNeighbors ;; get next to go back node id let rPath table:get toForwardMessage "returnBackPath" ;remove me from reverse path set rPath remove ID rPath table:put toForwardMessage "returnBackPath" rPath show (word "reverse path" rPath ", neighbors:" n) if not empty? rPath [ ;obtain next from path let next first rPath let nextN n with [ ID = next ] ifelse any? nextN ;; if previous node is still neihgbor, forward to it [ ask nextN [ ;;decrease ttl let stillValid? not decrease_ttl_of_message toForwardMessage ifelse stillValid? [ ;;send set recieved_messagesBufferList lput clone_table toForwardMessage recieved_messagesBufferList ;increase counters set total_messages_counter total_messages_counter + 1 set ack_messages_counter ack_messages_counter + 1 ] [ show "lost reply" set total_messages_counter total_messages_counter + 1 set lost_messages_counter lost_messages_counter + 1 ] ];;ask ] [;;else ;;TODO: HANDLE return NEIBoIRs has dispeared and need to broadcast table:put toForwardMessage "is_broken_return_path?" true ;; ;; ;; ;; show "need new routing for callback response,possible mobile node(s) location change, broadcast to neighbors" ;;TOdo: simplified broadcast to neighbors ask n [ ;;decrease ttl let stillValid? not decrease_ttl_of_message toForwardMessage ifelse stillValid? [ ;;send set recieved_messagesBufferList lput clone_table toForwardMessage recieved_messagesBufferList ;increase counters set total_messages_counter total_messages_counter + 1 set ack_messages_counter ack_messages_counter + 1 ] [ show "lost reply" set total_messages_counter total_messages_counter + 1 set lost_messages_counter lost_messages_counter + 1 ] ];;ask ] ];;if not empty rPath ] ];if not broken [;else broken return path ;; get neighbors let n ObtainMyNeighbors show "need new routing for callback response,possible mobile node(s) location change, broadcast to neighbors" ;;TOdo: simplified broadcast to neighbors let toForwardMessage ? ask n [ ;;decrease ttl let stillValid? not decrease_ttl_of_message toForwardMessage ifelse stillValid? [ ;;send set recieved_messagesBufferList lput clone_table toForwardMessage recieved_messagesBufferList ;increase counters set total_messages_counter total_messages_counter + 1 set ack_messages_counter ack_messages_counter + 1 ] [ show "lost reply" set total_messages_counter total_messages_counter + 1 set lost_messages_counter lost_messages_counter + 1 ] ];;ask ] ];if type == ACK ];;foreach ];;ask about ACK ;************************************************************ ;;______________________________________________ ;;********************************* Searching SECTION ;; send requests for the first time ask walkers with [ not empty? requests] [ ;; get neighborsdone let n ObtainMyNeighbors let messageToTransfer first requests ;;don't remove from list ;;decrease ttl let expires? decrease_ttl_of_message messageToTransfer set max_tick_to_wait ticks + 2 * requests_ttl_value; set timeout ;add current node to path ; addNodeToPath messageToTransfer ID current_groupRow current_groupCol ifelse not expires? and table:get messageToTransfer "type" = "searching" [ ask n [ ;commented: adding next future node to path c ;;addNodeToPath [ message_table nodeID regionRow regionCol ] ;addNodeToPath messageToTransfer ID current_groupRow current_groupCol ;;send message (clone to next hop) set recieved_messagesBufferList lput clone_table messageToTransfer recieved_messagesBufferList show "clone to next hop" ;increase counters set total_messages_counter total_messages_counter + 1 set searching_messages_counter searching_messages_counter + 1 ] ] [ ;;else show "dropping expired message" ] ;; remove from queue set requests remove messageToTransfer requests ];ask for first time request sending ;;_________________________________________________ ;; TODO : forward or process recieved messages ;; ;; ;; ;;try ask walkers with [ not empty? recieved_messagesBufferList] [ ;; get neighbors let n ObtainMyNeighbors ;; nieghbors in paths let copuOfRecivedMessages recieved_messagesBufferList ;; clone to avoid deletion in loop-list foreach copuOfRecivedMessages [ let messageToTransfer clone_table ? show (word "message type:________" table:get messageToTransfer "type") if table:get messageToTransfer "type" = "searching" [ ;;remove message from future processing in same pc set recieved_messagesBufferList remove messageToTransfer recieved_messagesBufferList ;;TODO ; process requirements for skills let currentNeeds table:get messageToTransfer "requirements_vector" let filteredNeeds match_skills_to_requirementsList currentNeeds skills_list ;;MATCHING table:put messageToTransfer "requirements_vector" filteredNeeds ;;test if at least 1 requirement is filled if length currentNeeds != length filteredNeeds [ AddNodeToProvidersList messageToTransfer ID ];; add me as provider addNodeToPath messageToTransfer ID current_groupRow current_groupCol let completePath table:get messageToTransfer "path_nodes" ;;to go back move from first to last in reverse list table:put messageToTransfer "returnBackPath" reverse completePath ifelse length filteredNeeds = 0 ;; no more unsatified needs [ ;;if show ( word ID ":full stistfaction, returning to source" table:get messageToTransfer "requesterID") ;;to do reply table:put messageToTransfer "type" "ack" ;;back to recived message if table:get messageToTransfer "ttl" > 0 [ set recieved_messagesBufferList lput clone_table messageToTransfer recieved_messagesBufferList] ;table:put messageToTransfer "ttl" requests_ttl_value ;;re-new ttl ] [ ;; else not full satisfaction ;;get path nodes let pathList getMessagePathList messageToTransfer show (word ID "sending to " pathList ", neighbors are:" n) ;;exclude previous nodes in each message path to avoid loops let newNeighbors n with [ not member? ID pathList] ifelse not any? newNeighbors ;; dead end [ ;;if show "dead end,returning back" ;;to do reply table:put messageToTransfer "type" "ack" table:put messageToTransfer "ttl" requests_ttl_value ;;re-new ttl ;add back to messages list to send later set recieved_messagesBufferList lput clone_table messageToTransfer recieved_messagesBufferList ] [ ;else (not dead end) let current_ttl table:get messageToTransfer "ttl" ifelse current_ttl <= 0 [ show "dropping expired request" ] [ ;else ;not expired request ;;else ;;addNodeToPath [ message_table nodeID regionRow regionCol ] addNodeToPath messageToTransfer ID current_groupRow current_groupCol ;;decrease ttl let expires? decrease_ttl_of_message messageToTransfer if not expires? [ ask newNeighbors [ ;;send message set recieved_messagesBufferList lput clone_table messageToTransfer recieved_messagesBufferList show "forwarding message" ;increase counters set total_messages_counter total_messages_counter + 1 set searching_messages_counter searching_messages_counter + 1 ] ] ];else note expired request ] ;;TODO: handle replies "ack" ;; ;; ;; ;; ] ; else not satisfaction ];;not ack ] ] ;********************************************************* ;; TODO process request of requirements vs skills *provide needs* ask walkers with [ max_tick_to_wait > 1 and max_tick_to_wait < ticks ] [ if table:length myHandledRequests = 0 [ ;;drop request (timeout) show "timeout of waiting" ] set max_tick_to_wait 0 ;;exclude first in queue (actually not needed in the current scope of simulation) if not empty? requests [ set requests but-first requests] if not has_recieved_at_least_one_response? ;due to a problem in simulation, this extra condition is tested [ ;increase failures set failed_requests_count failed_requests_count + 1 ] set is_waiting_reply? false ] ;update countes update-eval-counters end ;;============================================ to generate_requests [ use_region_skills_hashTable? ] ;;clear old requets ask walkers with [ not empty? requests and max_tick_to_wait > 0 and ticks >= max_tick_to_wait] [ set failed_requests_count failed_requests_count + 1 set requests (list) ;; empty list ;;if zrp is applied, then use the inner hash table to know the current region needs if use_region_skills_hashTable? [ ;;search in zone first let regionSkills table:keys zoneSkillsHashTable ;filter needs set needs_list match_skills_to_requirementsList regionSkills needs_list; can save broadcasting searching\ if length needs_list = 0 ;zone satisfaction [set has_recieved_at_least_one_response? true] ] ] ;; generate requests ask walkers with [ not empty? needs_list and empty? requests ] [ let maxTTL requests_ttl_value ;;generate-new-row-message [ source source_id ttl request_time_stamp requirementsList] let new_message generate-new-row-message_zrp who ID maxTTL ticks needs_list "searching" current_groupRow current_groupCol set max_tick_to_wait ticks + 2 * maxTTL ;;add as a request set requests lput new_message requests ;;set flags set is_waiting_reply? true set has_send_last_request? false ] end ;;---------------------------------------------------------- to go_alarm set algorithm "ALARM" if MovementUpdatePeriod > 0 and ticks mod MovementUpdatePeriod = 0 [ set regions_hash_table table:make ask walkers [ set-location one-of [link-neighbors] of location set color blue ;;get holder nodes set current_groupCol floor (xcor / GridWidth) set current_groupRow floor (ycor / GridWidth) register_walker_to_region current_groupCol current_groupRow ID ] ] ask walkers ;; get nieghbors [ ;;update caption set caption (list skills_list needs_list founds_list) set shape "default" ;;get neighbors colorize_Neighbors ;;score of connection let inContact ObtainMyNeighbors let scores myNeighborsConnectionLife ask inContact [ ;;-----/////------------ ifelse table:has-key? scores ID [ let v table:get scores ID set v v + 1 table:put scores ID v ] [ table:put scores ID 1 ] ] set myNeighborsConnectionLife scores ] ;;update sent messages update_messages_alarm age_threshold set average_messageBufferSize getMeanBufferSize if update_clock? [set seconds timer] if all? walkers [not is_waiting_reply? and max_tick_to_wait < 1] [ ; update_messages print "******************DONE *********************************" set update_clock? false ;stop further update to clock output ; stop ] tick end ;;---------------------------------------------------- to go set algorithm "flooding" if MovementUpdatePeriod > 0 and ticks mod MovementUpdatePeriod = 0 [ set regions_hash_table table:make ask walkers [ set-location one-of [link-neighbors] of location set color blue ;;get holder nodes set current_groupCol floor (xcor / GridWidth) set current_groupRow floor (ycor / GridWidth) register_walker_to_region current_groupCol current_groupRow ID ] ] ask walkers ;; get nieghbors [ ;;update caption set caption (list skills_list needs_list founds_list) set shape "default" ;;get neighbors colorize_Neighbors ] ;;update sent messages update_messages set average_messageBufferSize getMeanBufferSize if update_clock? [set seconds timer] if all? walkers [not is_waiting_reply? and max_tick_to_wait < 1] [ ; update_messages print "******************DONE *********************************" set update_clock? false ;stop further update to clock output ; stop ] tick end ;;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& to go_zrp set algorithm "zrp" if MovementUpdatePeriod > 0 and ticks mod MovementUpdatePeriod = 0 [ set regions_hash_table table:make ask walkers [ set-location one-of [link-neighbors] of location set color blue ;;get holder nodes set current_groupCol floor (xcor / GridWidth) set current_groupRow floor (ycor / GridWidth) register_walker_to_region current_groupCol current_groupRow ID ] ] ask walkers ;; get nieghbors [ ;;update caption set caption (list skills_list needs_list founds_list) set shape "default" ;;get neighbors colorize_Neighbors ] ;;update sent messages update_messages_Zrp set average_messageBufferSize getMeanBufferSize if update_clock? [set seconds timer] if not any? walkers with [is_waiting_reply? or (max_tick_to_wait <= ticks and max_tick_to_wait > 1)] [ ; update_messages print "******************DONE *********************************" set update_clock? false ;stop further update to clock output ; stop ] tick end ;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& to update_messages_Zrp ;;********************************* ACK SECTION ;;handle ack messages ask walkers with [ not empty? recieved_messagesBufferList ] [ ;;extract forward or self messages let copyRecievedMessage recieved_messagesBufferList;; clone of list to avoid loop-and-delete problems foreach copyRecievedMessage [ let tType table:get ? "type" show ( word "message type:---------------------------------" tType) ;;_______________________________________________ if tType = "ack" ;;acknowlege [ ifelse table:get ? "is_broken_return_path?" = false ; return path still valid [ let currentMessage ? set recieved_messagesBufferList remove ? recieved_messagesBufferList ;;remove from list ;;test if message to this node let destID table:get currentMessage "requesterID" ;;get request source ifelse destID = ID ;; this.id [ show "reply to me" if is_waiting_reply?;if waiting then process response, else drop out dated message [ ;;mark this message as returned handled request set is_waiting_reply? false let eval addToHandledHashTable currentMessage myHandledRequests if eval = "success" [;no more waiting set max_tick_to_wait 0 set is_waiting_reply? false ] ];;if waiting ] [ ;;else (request to forward) (message not to me) ;;----------------------------forwarding ;;note: Difference from normal routing is trial to go in reverse path if still available let toForwardMessage clone_table ? ;; get neighbors let n ObtainMyNeighbors ;; get next to go back node id let rPath table:get toForwardMessage "returnBackPath" ;remove me from reverse path set rPath remove ID rPath table:put toForwardMessage "returnBackPath" rPath show (word "reverse path" rPath ", neighbors:" n) if not empty? rPath [ ;obtain next from path let next first rPath let nextN n with [ ID = next ] ifelse any? nextN ;; if previous node is still neihgbor, forward to it [ ask nextN [ ;;decrease ttl let stillValid? not decrease_ttl_of_message toForwardMessage ifelse stillValid? [ ;;send set recieved_messagesBufferList lput clone_table toForwardMessage recieved_messagesBufferList ;increase counters set total_messages_counter total_messages_counter + 1 set ack_messages_counter ack_messages_counter + 1 ] [ show "lost reply" set total_messages_counter total_messages_counter + 1 set lost_messages_counter lost_messages_counter + 1 ] ];;ask ] [;;else ;;TODO: HANDLE return NEIBoIRs has dispeared and need to broadcast table:put toForwardMessage "is_broken_return_path?" true ;; ;; ;; ;; show "need new routing for callback response,possible mobile node(s) location change, broadcast to neighbors" ;;TOdo: simplified broadcast to neighbors ask n [ ;;decrease ttl let stillValid? not decrease_ttl_of_message toForwardMessage ifelse stillValid? [ ;;send set recieved_messagesBufferList lput clone_table toForwardMessage recieved_messagesBufferList ;increase counters set total_messages_counter total_messages_counter + 1 set ack_messages_counter ack_messages_counter + 1 ] [ show "lost reply" set total_messages_counter total_messages_counter + 1 set lost_messages_counter lost_messages_counter + 1 ] ];;ask ] ];;if not empty rPath ] ];if not broken [;else broken return path ;; get neighbors let n ObtainMyNeighbors show "need new routing for callback response,possible mobile node(s) location change, broadcast to neighbors" ;;TOdo: simplified broadcast to neighbors let toForwardMessage ? ask n [ ;;decrease ttl let stillValid? not decrease_ttl_of_message toForwardMessage ifelse stillValid? [ ;;send set recieved_messagesBufferList lput clone_table toForwardMessage recieved_messagesBufferList ;increase counters set total_messages_counter total_messages_counter + 1 set ack_messages_counter ack_messages_counter + 1 ] [ show "lost reply" set total_messages_counter total_messages_counter + 1 set lost_messages_counter lost_messages_counter + 1 ] ];;ask ] ];if type == ACK ];;foreach ];;ask about ACK ;************************************************************ ;;___________________________________________________________________________________________________________________________ ;;********************************* Searching SECTION ;; send requests for the first time ask walkers with [ not empty? requests] [ ;; get neighborsdone let n ObtainMyNeighbors let messageToTransfer first requests ;;don't remove from list ;;decrease ttl let expires? decrease_ttl_of_message messageToTransfer ;add current node to path ; addNodeToPath messageToTransfer ID current_groupRow current_groupCol ifelse not expires? and table:get messageToTransfer "type" = "searching" [ ; selectNeighborsOutOfRegionOrFarthest [ neighborsList region_row region_col node_XCor nodeYCor] let suggestedNeighbirs selectNeighborsOutOfRegionOrFarthest n current_groupRow current_groupCol xcor ycor ask suggestedNeighbirs [ ;commented: adding next future node to path c ;;addNodeToPath [ message_table nodeID regionRow regionCol ] ;addNodeToPath messageToTransfer ID current_groupRow current_groupCol ;;send message (clone to next hop) set recieved_messagesBufferList lput clone_table messageToTransfer recieved_messagesBufferList show "clone to next hop" ;increase counters set total_messages_counter total_messages_counter + 1 set searching_messages_counter searching_messages_counter + 1 ] ] [ ;;else show "dropping expired message" ] ;; remove from queue set requests remove messageToTransfer requests ];ask for first time request sending ;;_________________________________________________ ;; TODO : forward or process recieved messages ;; ;; ;; ;;try ask walkers with [ not empty? recieved_messagesBufferList] [ ;; get neighbors let n ObtainMyNeighbors ;; nieghbors in paths let copuOfRecivedMessages recieved_messagesBufferList ;; clone to avoid deletion in loop-list foreach copuOfRecivedMessages [ let messageToTransfer clone_table ? show (word "message type:________" table:get messageToTransfer "type") if table:get messageToTransfer "type" = "searching" [ ;;remove message from future processing in same pc set recieved_messagesBufferList remove messageToTransfer recieved_messagesBufferList ;;TODO ; process requirements for skills let currentNeeds table:get messageToTransfer "requirements_vector" let filteredNeeds match_skills_to_requirementsList currentNeeds skills_list ;;MATCHING table:put messageToTransfer "requirements_vector" filteredNeeds ;;test if at least 1 requirement is filled if length currentNeeds != length filteredNeeds [ AddNodeToProvidersList messageToTransfer ID ];; add me as provider addNodeToPath messageToTransfer ID current_groupRow current_groupCol let completePath table:get messageToTransfer "path_nodes" ;;to go back move from first to last in reverse list table:put messageToTransfer "returnBackPath" reverse completePath if length filteredNeeds != 0 ;localskills not enough, try zone skills [ let keys table:keys zoneSkillsHashTable set filteredNeeds match_skills_to_requirementsList currentNeeds keys if length filteredNeeds = 0 ;zone satisfaction [set has_recieved_at_least_one_response? true] ] ifelse length filteredNeeds = 0 ;; no more unsatified needs IN ENTIRE ZONE [ ;;if show ( word ID ":full stistfaction, returning to source" table:get messageToTransfer "requesterID") ;;to do reply table:put messageToTransfer "type" "ack" ;;back to recived message if table:get messageToTransfer "ttl" > 0 [ set recieved_messagesBufferList lput clone_table messageToTransfer recieved_messagesBufferList] ;table:put messageToTransfer "ttl" requests_ttl_value ;;re-new ttl ] [ ;; else not full satisfaction ;;get path nodes let pathList getMessagePathList messageToTransfer show (word ID "sending to " pathList ", neighbors are:" n) ;;exclude previous nodes in each message path to avoid loops let newNeighbors n with [ not member? ID pathList] ifelse not any? newNeighbors ;; dead end [ ;;if show "dead end,returning back" ;;to do reply table:put messageToTransfer "type" "ack" table:put messageToTransfer "ttl" requests_ttl_value ;;re-new ttl ;add back to messages list to send later set recieved_messagesBufferList lput clone_table messageToTransfer recieved_messagesBufferList ] [ ;else (not dead end) let current_ttl table:get messageToTransfer "ttl" ifelse current_ttl <= 0 [ show "dropping expired request" ] [ ;else ;not expired request ;;else ;;addNodeToPath [ message_table nodeID regionRow regionCol ] addNodeToPath messageToTransfer ID current_groupRow current_groupCol ;;decrease ttl let expires? decrease_ttl_of_message messageToTransfer if not expires? [ let suggestedNeighbirs selectNeighborsOutOfRegionOrFarthest newNeighbors current_groupRow current_groupCol xcor ycor ask suggestedNeighbirs [ ;;send message set recieved_messagesBufferList lput clone_table messageToTransfer recieved_messagesBufferList show "forwarding message" ;increase counters set total_messages_counter total_messages_counter + 1 set searching_messages_counter searching_messages_counter + 1 ] ] ];else note expired request ] ;;TODO: handle replies "ack" ;; ;; ;; ;; ] ; else not satisfaction ];;not ack ] ] ;********************************************************* ;; TODO process request of requirements vs skills *provide needs* ask walkers with [ max_tick_to_wait > 1 and max_tick_to_wait < ticks ] [ if table:length myHandledRequests = 0 [ ;;drop request (timeout) show "timeout of waiting" ] set max_tick_to_wait 0 ;;exclude first in queue (actually not needed in the current scope of simulation) if not empty? requests [ set requests but-first requests] ;increase failures set failed_requests_count failed_requests_count + 1 set is_waiting_reply? false ] ;update countes update-eval-counters end ;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& ;;------------------------------------------------------- ;;colorize neighbors to colorize_Neighbors;;walker proc let inContact ObtainMyNeighbors ask inContact [ ;;if pxcor != [pxcor] of myself and pycor != [pycor] of myself set color red set shape "star" ] end ;;--------------------------------------- ;;get the neighbors of a walker to-report ObtainMyNeighbors let p walkers in-radius range let inContact p with [range >= abs distance myself and abs distance myself > 0] report inContact end ;;--------------------------------------- ;;get the neighbors of a walker to-report ObtainMyNeighbors_alarm [lifeThreshold] let p walkers in-radius range let lifes myNeighborsConnectionLife;;~~~~~ let inContact p with [range >= abs distance myself and abs distance myself > 0 ] ifelse ticks < lifeThreshold [report inContact] ;;//no life thresholding in start [ let filtered inContact with [table:has-key? myNeighborsConnectionLife ID and table:get myNeighborsConnectionLife ID > lifeThreshold] report filtered ] end ;;---------------------------------------------------- to set-location [new-location] ;; walker procedure set location new-location face new-location ;; not strictly necessary, but improves the visuals a bit move-to new-location end ;============================================================= ;register nodes to regions to register_walker_to_region [ regionCol regionRow node_id] ;regions_hash_table let key (list regionCol regionRow) ifelse table:has-key? regions_hash_table key [ let list_of_pcs table:get regions_hash_table key if not member? node_id list_of_pcs [set list_of_pcs lput node_id list_of_pcs ] ] [;else (first number in region) table:put regions_hash_table key (list node_id) ] end ;;===================================================== ;; adds last node so far in routing path to addNodeToPath [ message_table nodeID regionRow regionCol ] ;;path (nodeID, row, col) let path table:get message_table "path_nodes" if not member? nodeID path [ ;;set path lput (list nodeID regionRow regionCol) path set path lput nodeID path table:put message_table "path_nodes" path ] end ;;============================================= ;; add node to provides list to AddNodeToProvidersList[ message_table nodeID] let providers table:get message_table "provider_nodes" if not member? nodeID providers [ ;;set path lput (list nodeID regionRow regionCol) path set providers lput nodeID providers table:put message_table "provider_nodes" providers ] end ;;--------------------------------------------- ;;searches skills for requirements, and return unfound requirements to-report match_skills_to_requirementsList [ skillsList requirementsList] let Unfound (list);; empty list (foreach requirementsList [ if member? ? skillsList;;match [ set Unfound lput ? Unfound ] ]) report Unfound end ;;---------------------------------------------------- to make-halo [radius] ;; runner procedure ;; when you use HATCH, the new turtle inherits the ;; characteristics of the parent. so the halo will ;; be the same color as the turtle it encircles (unless ;; you add code to change it hatch-halos 1 [ set size radius ;; Use an RGB color to make halo three fourths transparent set color lput 100 extract-rgb black ;; set thickness of halo to half a patch __set-line-thickness 0.1 ;; We create an invisible directed link from the runner ;; to the halo. Using tie means that whenever the ;; runner moves, the halo moves with it. create-link-with myself [ tie hide-link ] ] end ;;======================================================= to show_hide_labels ifelse (Labels_ON ) [ask walkers [ set label-color gray set label ID ; caption ] ] [ set label-color gray set label "" ] end ;;======================================= ;; updates ttl with -1 on each messages transfer ;;and returns if it expires or not to-report decrease_ttl_of_message [ message_table] let t table:get message_table "ttl" set t t - 1 if t < 0 [ set t 0] show (word "ttl:" t) table:put message_table "ttl" t report t <= 0 end ;;==================================== ;;gets path nodes followed by the message routing so far to-report getMessagePathList [ message_table ] let t table:get message_table "path_nodes" report t end ;;---------------------------------------------------------- ;since table is mutable (by reference), this method copies the table ;into list and then creates a new copy table to-report clone_table [ tabel_to_clone] let tList table:to-list tabel_to_clone let clone table:from-list tList report clone end ;=================================================== to save_to_file let file user-new-file ;; We check to make sure we actually got a string just in case ;; the user hits the cancel button. if is-string? file [ ;; If the file already exists, we begin by deleting it, otherwise ;; new data would be appended to the old contents. if file-exists? file [ file-delete file ] file-open file ;; record the initial turtle data ; ; ID ; location ; range ; skills_list ;;own the skills ; needs_list ;; need another walker with skill ; founds_list ;;matched items ; caption ; current_groupRow ;;indexer for containing region (column and row) ; current_groupCol ; old_groupRow ;; old position in previous tick ; old_groupCol ; recieved_messagesBufferList ;; messages recived to reply or broadcast ; requests ;; requests not replied yet ; has_send_last_request? ; is_waiting_reply? ;;is waiting for reply to a broadcasted request ; max_tick_to_wait ;; max timestamp to wait for ; myHandledRequests ;; hashtable of returned responses (timestamp, filled (yes,no, partial)) ; failed_requests_count ;; requests failed ; partial_success_count ;; partial success ; succeeded_requests_count ;; requests achieved ; original_requirements_to_restore; the original requirements list to restore from (reset in place) ; has_recieved_at_least_one_response? ;; needed to distinguis complete failure from partial failure (success) ; original_x ; original_y ;; use SORT so the turtles print their data in order by who number, ;; rather than in random order foreach sort walkers [ ask ? [ file-print (word xcor " " pycor " " ID " " range " " skills_list " " needs_list ) ] ] file-print "" ;; blank line ] end to-report read-file ifelse ( file-exists? user-file) ; browse for existing file [ file-open user-file ask walkers [die] let csv_list (list) ;; Read in all the data in the file while [ not file-at-end? ] [ ;file-print (word xcor " " pycor " " ID " " range " " skills_list " " needs_list ) let temp (list file-read file-read file-read file-read file-read file-read) set csv_list lput temp csv_list ] file-close report csv_list ] [ user-message "problem with file" report (list) ] end ;====================================================== ;selects nodes not belonging to current region from neigbirs, if all neighbors are in the same region select farthest neighbors to-report selectNeighborsOutOfRegionOrFarthest [ neighborsList region_row region_col node_XCor nodeYCor] if not any? neighborsList [report neighborsList] ;return empty list let n neighborsList with [ current_groupRow != region_row and current_groupCol != region_col] ifelse not any? n [ report n ] [ ;else throw farthest ;calculate distances let dists (list) ask neighborsList [ set temp_distance distancexy node_XCor nodeYCor set dists lput temp_distance dists ] ;;calculate mean let average mean dists ;TODO:may enchnace that critieria ;decrease count of neighbots let threshold 1.25 * average let farthest neighborsList with [ temp_distance >= threshold] if not any? farthest [set farthest neighborsList with [ temp_distance >= average] ] report farthest ] end ;------------------------------------------------------- ;needed for comparisons only to CopyCountersOldValues clear-output output-print (word "seconds: " seconds) output-print (word "total_messages_counter: " total_messages_counter) output-print (word "searching_messages_counter: " searching_messages_counter) output-print (word "ack_messages_counter: " ack_messages_counter) output-print (word "notifications_messages_counter: " notifications_messages_counter);; needed for zrp procative updates output-print (word "lost_messages_counter: " lost_messages_counter) output-print (word "average_messageBufferSize: " average_messageBufferSize) output-print (word "summary: " algorithm "," queryGeneratorsCount "," requests_ttl_value "," MaxRange "," Count_of_Walkers "," GridWidth "," MovementUpdatePeriod "," seconds "," total_messages_counter"," searching_messages_counter"," ack_messages_counter"," notifications_messages_counter"," lost_messages_counter "," average_messageBufferSize "," count walkers with [succeeded_requests_count > 0] "," count walkers with [partial_success_count > 0] "," count walkers with [ failed_requests_count > 0] "," best_case? "," age_threshold) end ;======================================= to-report getMeanBufferSize let x average_messageBufferSize let sizes (list) ask walkers [set sizes lput length recieved_messagesBufferList sizes] let current mean sizes if current > x [set x current] report x end ;============================================= ; Public Domain: ; To the extent possible under law, Uri Wilensky has waived all ; copyright and related or neighboring rights to this model. @#$#@#$#@ GRAPHICS-WINDOW 766 10 1325 590 -1 -1 9.0 1 10 1 1 1 0 1 1 1 0 60 0 60 1 1 1 ticks 30.0 BUTTON 11 11 124 44 setup_flooding setup false NIL 1 T OBSERVER NIL NIL NIL NIL 1 BUTTON 315 15 417 48 go (flooding) go T 1 T OBSERVER NIL NIL NIL NIL 1 SLIDER 375 167 565 200 Count_of_Walkers Count_of_Walkers 10 200 30 5 1 mobile HORIZONTAL SLIDER 385 323 557 356 GridWidth GridWidth 5 40 10 5 1 cells HORIZONTAL SLIDER 383 362 605 395 MovementUpdatePeriod MovementUpdatePeriod 0 10 2 1 1 every Ticks HORIZONTAL SLIDER 387 284 559 317 MaxRange MaxRange 10 100 20 5 1 patches HORIZONTAL SWITCH 143 84 242 117 Labels_ON Labels_ON 1 1 -1000 BUTTON 249 124 372 157 show/hide labels show_hide_labels NIL 1 T TURTLE NIL NIL NIL NIL 0 SLIDER 385 245 566 278 requests_ttl_value requests_ttl_value 1 100 25 2 1 ticks HORIZONTAL BUTTON 137 14 304 47 generate requests (Flooding) generate_requests false NIL 1 T OBSERVER NIL NIL NIL NIL 0 PLOT 592 143 757 263 full success Node ID count 0.0 10.0 0.0 10.0 true false "set-plot-x-range 0 (count walkers + 1)" "" PENS "full-success" 1.0 1 -14439633 true "" "plot-pen-reset\nask walkers [ plotxy ID succeeded_requests_count ]" PLOT 593 15 753 135 requests buffer size NIL NIL 0.0 10.0 0.0 10.0 true false "" "" PENS "default" 1.0 1 -16777216 true "" "plot-pen-reset\nask walkers [plotxy ID length recieved_messagesBufferList]" BUTTON 446 15 574 48 floodng-single step go NIL 1 T OBSERVER NIL NIL NIL NIL 1 SLIDER 377 204 578 237 queryGeneratorsCount queryGeneratorsCount 1 40 7 1 1 Nodes HORIZONTAL PLOT 591 268 760 392 partial NodeID Count 0.0 10.0 0.0 10.0 true false "set-plot-x-range 0 (count walkers + 1)" "" PENS "default" 1.0 1 -13791810 true "" "plot-pen-reset\nask walkers [ plotxy ID partial_success_count ]" PLOT 592 401 760 521 failures Node ID Count 0.0 10.0 0.0 10.0 true false "set-plot-x-range 0 (count walkers + 1)" "" PENS "default" 1.0 1 -8053223 true "" "plot-pen-reset\nask walkers [ plotxy ID failed_requests_count ]" MONITOR 16 119 74 164 NIL seconds 17 1 11 BUTTON 378 122 570 155 NIL restore_requests_to_original NIL 1 T OBSERVER NIL NIL NIL NIL 1 MONITOR 16 170 165 215 NIL total_messages_counter 17 1 11 MONITOR 15 216 192 261 NIL searching_messages_counter 17 1 11 MONITOR 16 260 158 305 NIL ack_messages_counter 17 1 11 MONITOR 187 209 353 254 NIL notifications_messages_counter 17 1 11 MONITOR 15 310 158 355 NIL lost_messages_counter 17 1 11 BUTTON 316 50 418 83 NIL go_zrp T 1 T OBSERVER NIL NIL NIL NIL 1 BUTTON 136 51 299 84 generate request (ZRP) generate_requests true NIL 1 T OBSERVER NIL NIL NIL NIL 0 BUTTON 445 51 573 84 go zrp single step go_zrp NIL 1 T OBSERVER NIL NIL NIL NIL 1 BUTTON 14 47 107 80 setup (zrp) setup true NIL 1 T OBSERVER NIL NIL NIL NIL 1 BUTTON 77 124 242 157 write counters values CopyCountersOldValues NIL 1 T OBSERVER NIL NIL NIL NIL 0 OUTPUT 13 394 575 516 11 MONITOR 191 258 362 303 NIL average_messageBufferSize 17 1 11 PLOT 58 520 258 670 average buffer size time mean size 0.0 10.0 0.0 3.0 true false "" "" PENS "default" 1.0 0 -14070903 true "" "plot average_messageBufferSize" MONITOR 165 304 375 349 NIL count walkers with [partial_success_count > 0] 17 1 11 MONITOR 160 349 383 394 NIL count walkers with [ failed_requests_count > 0] 17 1 11 SWITCH 12 83 130 116 best_case? best_case? 0 1 -1000 BUTTON 282 88 364 121 NIL go_alarm T 1 T OBSERVER NIL NIL NIL NIL 1 SLIDER 187 166 359 199 age_threshold age_threshold 1 100 6 5 1 NIL HORIZONTAL @#$#@#$#@ ## WHAT IS IT? based on latice walking tutrles and halo examples, a simplidifed model for mobile ad-hoc network MANET, with moving nodes (mobiles). Each node can have variable range of connection. this model is intended to be used later in social network group formation problem based on skills randomly provided to some nodes. currently, a basic flooding searching algorithm with ttl setting and count of nodes and query generators. @#$#@#$#@ default true 0 Polygon -7500403 true true 150 5 40 250 150 205 260 250 airplane true 0 Polygon -7500403 true true 150 0 135 15 120 60 120 105 15 165 15 195 120 180 135 240 105 270 120 285 150 270 180 285 210 270 165 240 180 180 285 195 285 165 180 105 180 60 165 15 arrow true 0 Polygon -7500403 true true 150 0 0 150 105 150 105 293 195 293 195 150 300 150 box false 0 Polygon -7500403 true true 150 285 285 225 285 75 150 135 Polygon -7500403 true true 150 135 15 75 150 15 285 75 Polygon -7500403 true true 15 75 15 225 150 285 150 135 Line -16777216 false 150 285 150 135 Line -16777216 false 150 135 15 75 Line -16777216 false 150 135 285 75 bug true 0 Circle -7500403 true true 96 182 108 Circle -7500403 true true 110 127 80 Circle -7500403 true true 110 75 80 Line -7500403 true 150 100 80 30 Line -7500403 true 150 100 220 30 butterfly true 0 Polygon -7500403 true true 150 165 209 199 225 225 225 255 195 270 165 255 150 240 Polygon -7500403 true true 150 165 89 198 75 225 75 255 105 270 135 255 150 240 Polygon -7500403 true true 139 148 100 105 55 90 25 90 10 105 10 135 25 180 40 195 85 194 139 163 Polygon -7500403 true true 162 150 200 105 245 90 275 90 290 105 290 135 275 180 260 195 215 195 162 165 Polygon -16777216 true false 150 255 135 225 120 150 135 120 150 105 165 120 180 150 165 225 Circle -16777216 true false 135 90 30 Line -16777216 false 150 105 195 60 Line -16777216 false 150 105 105 60 car false 0 Polygon -7500403 true true 300 180 279 164 261 144 240 135 226 132 213 106 203 84 185 63 159 50 135 50 75 60 0 150 0 165 0 225 300 225 300 180 Circle -16777216 true false 180 180 90 Circle -16777216 true false 30 180 90 Polygon -16777216 true false 162 80 132 78 134 135 209 135 194 105 189 96 180 89 Circle -7500403 true true 47 195 58 Circle -7500403 true true 195 195 58 circle false 0 Circle -7500403 true true 0 0 300 circle 2 false 0 Circle -7500403 true true 0 0 300 Circle -16777216 true false 30 30 240 cow false 0 Polygon -7500403 true true 200 193 197 249 179 249 177 196 166 187 140 189 93 191 78 179 72 211 49 209 48 181 37 149 25 120 25 89 45 72 103 84 179 75 198 76 252 64 272 81 293 103 285 121 255 121 242 118 224 167 Polygon -7500403 true true 73 210 86 251 62 249 48 208 Polygon -7500403 true true 25 114 16 195 9 204 23 213 25 200 39 123 cylinder false 0 Circle -7500403 true true 0 0 300 dot false 0 Circle -7500403 true true 90 90 120 face happy false 0 Circle -7500403 true true 8 8 285 Circle -16777216 true false 60 75 60 Circle -16777216 true false 180 75 60 Polygon -16777216 true false 150 255 90 239 62 213 47 191 67 179 90 203 109 218 150 225 192 218 210 203 227 181 251 194 236 217 212 240 face neutral false 0 Circle -7500403 true true 8 7 285 Circle -16777216 true false 60 75 60 Circle -16777216 true false 180 75 60 Rectangle -16777216 true false 60 195 240 225 face sad false 0 Circle -7500403 true true 8 8 285 Circle -16777216 true false 60 75 60 Circle -16777216 true false 180 75 60 Polygon -16777216 true false 150 168 90 184 62 210 47 232 67 244 90 220 109 205 150 198 192 205 210 220 227 242 251 229 236 206 212 183 fish false 0 Polygon -1 true false 44 131 21 87 15 86 0 120 15 150 0 180 13 214 20 212 45 166 Polygon -1 true false 135 195 119 235 95 218 76 210 46 204 60 165 Polygon -1 true false 75 45 83 77 71 103 86 114 166 78 135 60 Polygon -7500403 true true 30 136 151 77 226 81 280 119 292 146 292 160 287 170 270 195 195 210 151 212 30 166 Circle -16777216 true false 215 106 30 flag false 0 Rectangle -7500403 true true 60 15 75 300 Polygon -7500403 true true 90 150 270 90 90 30 Line -7500403 true 75 135 90 135 Line -7500403 true 75 45 90 45 flower false 0 Polygon -10899396 true false 135 120 165 165 180 210 180 240 150 300 165 300 195 240 195 195 165 135 Circle -7500403 true true 85 132 38 Circle -7500403 true true 130 147 38 Circle -7500403 true true 192 85 38 Circle -7500403 true true 85 40 38 Circle -7500403 true true 177 40 38 Circle -7500403 true true 177 132 38 Circle -7500403 true true 70 85 38 Circle -7500403 true true 130 25 38 Circle -7500403 true true 96 51 108 Circle -16777216 true false 113 68 74 Polygon -10899396 true false 189 233 219 188 249 173 279 188 234 218 Polygon -10899396 true false 180 255 150 210 105 210 75 240 135 240 hex false 0 Polygon -7500403 true true 0 150 75 30 225 30 300 150 225 270 75 270 hex_border false 14 Rectangle -16777216 true true 0 0 300 300 Rectangle -16777216 true true 30 150 300 150 Circle -7500403 true false 83 68 134 house false 0 Rectangle -7500403 true true 45 120 255 285 Rectangle -16777216 true false 120 210 180 285 Polygon -7500403 true true 15 120 150 15 285 120 Line -16777216 false 30 120 270 120 leaf false 0 Polygon -7500403 true true 150 210 135 195 120 210 60 210 30 195 60 180 60 165 15 135 30 120 15 105 40 104 45 90 60 90 90 105 105 120 120 120 105 60 120 60 135 30 150 15 165 30 180 60 195 60 180 120 195 120 210 105 240 90 255 90 263 104 285 105 270 120 285 135 240 165 240 180 270 195 240 210 180 210 165 195 Polygon -7500403 true true 135 195 135 240 120 255 105 255 105 285 135 285 165 240 165 195 line true 0 Line -7500403 true 150 0 150 300 line half true 0 Line -7500403 true 150 0 150 150 pentagon false 0 Polygon -7500403 true true 150 15 15 120 60 285 240 285 285 120 person false 0 Circle -7500403 true true 110 5 80 Polygon -7500403 true true 105 90 120 195 90 285 105 300 135 300 150 225 165 300 195 300 210 285 180 195 195 90 Rectangle -7500403 true true 127 79 172 94 Polygon -7500403 true true 195 90 240 150 225 180 165 105 Polygon -7500403 true true 105 90 60 150 75 180 135 105 plant false 0 Rectangle -7500403 true true 135 90 165 300 Polygon -7500403 true true 135 255 90 210 45 195 75 255 135 285 Polygon -7500403 true true 165 255 210 210 255 195 225 255 165 285 Polygon -7500403 true true 135 180 90 135 45 120 75 180 135 210 Polygon -7500403 true true 165 180 165 210 225 180 255 120 210 135 Polygon -7500403 true true 135 105 90 60 45 45 75 105 135 135 Polygon -7500403 true true 165 105 165 135 225 105 255 45 210 60 Polygon -7500403 true true 135 90 120 45 150 15 180 45 165 90 square false 0 Rectangle -7500403 true true 30 30 270 270 square 2 false 0 Rectangle -7500403 true true 30 30 270 270 Rectangle -16777216 true false 60 60 240 240 star false 0 Polygon -7500403 true true 151 1 185 108 298 108 207 175 242 282 151 216 59 282 94 175 3 108 116 108 target false 0 Circle -7500403 true true 0 0 300 Circle -16777216 true false 30 30 240 Circle -7500403 true true 60 60 180 Circle -16777216 true false 90 90 120 Circle -7500403 true true 120 120 60 thin ring true 0 Circle -7500403 false true 0 0 300 tree false 0 Circle -7500403 true true 118 3 94 Rectangle -6459832 true false 120 195 180 300 Circle -7500403 true true 65 21 108 Circle -7500403 true true 116 41 127 Circle -7500403 true true 45 90 120 Circle -7500403 true true 104 74 152 triangle false 0 Polygon -7500403 true true 150 30 15 255 285 255 triangle 2 false 0 Polygon -7500403 true true 150 30 15 255 285 255 Polygon -16777216 true false 151 99 225 223 75 224 truck false 0 Rectangle -7500403 true true 4 45 195 187 Polygon -7500403 true true 296 193 296 150 259 134 244 104 208 104 207 194 Rectangle -1 true false 195 60 195 105 Polygon -16777216 true false 238 112 252 141 219 141 218 112 Circle -16777216 true false 234 174 42 Rectangle -7500403 true true 181 185 214 194 Circle -16777216 true false 144 174 42 Circle -16777216 true false 24 174 42 Circle -7500403 false true 24 174 42 Circle -7500403 false true 144 174 42 Circle -7500403 false true 234 174 42 turtle true 0 Polygon -10899396 true false 215 204 240 233 246 254 228 266 215 252 193 210 Polygon -10899396 true false 195 90 225 75 245 75 260 89 269 108 261 124 240 105 225 105 210 105 Polygon -10899396 true false 105 90 75 75 55 75 40 89 31 108 39 124 60 105 75 105 90 105 Polygon -10899396 true false 132 85 134 64 107 51 108 17 150 2 192 18 192 52 169 65 172 87 Polygon -10899396 true false 85 204 60 233 54 254 72 266 85 252 107 210 Polygon -7500403 true true 119 75 179 75 209 101 224 135 220 225 175 261 128 261 81 224 74 135 88 99 wheel false 0 Circle -7500403 true true 3 3 294 Circle -16777216 true false 30 30 240 Line -7500403 true 150 285 150 15 Line -7500403 true 15 150 285 150 Circle -7500403 true true 120 120 60 Line -7500403 true 216 40 79 269 Line -7500403 true 40 84 269 221 Line -7500403 true 40 216 269 79 Line -7500403 true 84 40 221 269 x false 0 Polygon -7500403 true true 270 75 225 30 30 225 75 270 Polygon -7500403 true true 30 75 75 30 270 225 225 270 @#$#@#$#@ NetLogo 5.0.4 @#$#@#$#@ @#$#@#$#@ @#$#@#$#@ @#$#@#$#@ @#$#@#$#@ default 0.0 -0.2 0 0.0 1.0 0.0 1 1.0 0.0 0.2 0 0.0 1.0 link direction true 0 Line -7500403 true 150 150 90 180 Line -7500403 true 150 150 210 180 @#$#@#$#@ 0 @#$#@#$#@