!!!---reciprocity3.nlogo
来自「NETLOGO」· NLOGO 代码 · 共 766 行 · 第 1/2 页
NLOGO
766 行
; package delivery problem; by; Jose M. Vidalbreeds [deliverators] ;"The Deliverator stands tall, your [pizza] pie in thirty minutes or you can have it free, ; shoot the driver, take his car, file a class-action suit."--Snow Crash.deliverators-own [dist deliveries steps balance average-cost accepted-package packages helping behavior spoke rating];dist is the total distance the agent has travelled;deliveries are the set of deliveries left. They are given in [spoke distance] pairs.;steps is used to keep track of the steps left towards the goal;balance is a list of the balances (B in the paper). The i'th element refers to who-of agent = i.;behavior is; 0 - philanthropic; 1 - selfish; 2 - reciprocative; 3 - individual;;I used a variable instead breeds so that I could "ask deliverators". (wish netlogo had breed inheritance);The only important name is "depot"patches-own [name];max-distance is the variable D in the paper. The maximum length of a spoke.;delivery-distances is a random list of delivery distances. All agents use these distances. That way; we can be certain that all agents will travel the same distance.;spoke-mult is the angle of the spoke;distance-mult is how much we multiply the distance in order to plot it;num-asks-multiplier is how many times deliverators try to trade packages.;num-deliverators;total-dist travelled by all deliveratorsglobals [max-distance delivery-distances spoke-mult distance-mult num-asks-multiplier num-deliverators total-dist time average-rating profits average-profit];num-deliveries- deliveries are referred to as "tasks" in the paper.;num-spokes- is the variable "R" in the paperto setup ca initializeendto initialize set profits [] set average-rating 1 set time 1 set max-distance 3 ;This is variable "D" in the paper set spoke-mult 360 / num-spokes set distance-mult 5 set num-asks-multiplier 10 set num-deliverators num-philanthropic + num-selfish + num-reciprocative + num-individual create-custom-deliverators num-philanthropic + num-selfish + num-reciprocative + num-individual [ set-current-plot "Movement" create-temporary-plot-pen "q" + who set-current-plot-pen "q" + who set-plot-pen-color color set rating 0 ifelse (who < num-philanthropic) [ set behavior 0 ] [ ifelse (who < num-philanthropic + num-selfish) [ set behavior 1 ] [ ifelse (who < num-philanthropic + num-selfish + num-reciprocative)[ set behavior 2] [ set behavior 3]]]] set delivery-distances make-list num-deliveries ask deliverators [ set-deliveries set heading 0] ask (patch 0 0) [set name "depot"] print "Setup done."endto update ;turn of the infinity button if set if (count deliverators with [empty? deliveries] = num-deliverators and count deliverators with [name-of patch-here = "depot"] = num-deliverators) [stop] ;agents in the depot exchange-tasks ;Ask all deliverators to move one step, in parallel ask deliverators [ deliver] ;Plot the total distance travelled set-current-plot "Total Distance" set total-dist sum values-from deliverators [dist] plot total-dist ;Plot individual agent distances set-current-plot "Movement" ask deliverators [ set-plot-pen "q" + who plot dist / time] set time time + 1end;returns a copy of lst with all the elements randomized.to-report randomize-list [lst] locals [i len num-reps a a-val b] set len length lst set num-reps len * 2 while [i < num-reps] [ set a random len set a-val item a lst set b random len set lst replace-item a lst (item b lst) set lst replace-item b lst a-val set i i + 1 ] report lstend;Makes a list of len items by cycling over the possible distances of delivery.;We assume only integer distances are allowed.to-report make-list [len] locals [i lst c] set lst [] set i 0 set c round (max-distance / 2) while [i < len] [ set lst fput c lst set i i + 1 set c (c + 1) mod max-distance + 1] report lstend;returns a list of (spoke-number, distance) pairs.;This is the list of deliveries the deliverator will need to make.to-report make-deliveries locals [i res] set res [] while [i < length delivery-distances][ set res fput list (random num-spokes) (item i delivery-distances) res set i i + 1] report randomize-list resend;agents in the depot exchange tasks;I had to do this using a double loop because the parallelism introduced synchronization problems.;without-interruption is not good enough to solve the problems.;Sandip's papers do not go into the details of how this exchange happens so I had to make some assumptions.to exchange-tasks locals [i j owners traders tradersToHelp tradersToAskForHelp gain1 gain2 tradersToHelpGain tradersToAskForHelpGain] ask deliverators with [name-of patch-here = "depot" and not empty? deliveries][ set accepted-package false ;true if agent has accepted a package from someone. If so, he will not try to trade his package away set packages fput (item 1 first deliveries) [] ;A list of distances for the packages Im delivering, the first is my original one set helping [] ;A list of who-of for the agents for whom agent has agreed to take a package set spoke first first deliveries ] set owners values-from deliverators with [name-of patch-here = "depot" and (not empty? deliveries) ] [who] set owners randomize-list owners while [not empty? owners][ set i (turtle first owners) if (not accepted-package-of i and ;If i has not accepted a package then it can still try to give his away. behavior-of i != 3)[ ;individual agents don't ask for help set traders values-from deliverators with [name-of patch-here = "depot" and not empty? packages and who != who-of i and spoke = spoke-of i and behavior != 1 and behavior != 3] [who] set tradersToHelp [] set tradersToAskForHelp [] set tradersToHelpGain [] set tradersToAskForHelpGain [] while [not empty? traders][ set gain1 (first packages-of (turtle first traders)) - ( max list 0 ( ((first packages-of (turtle first traders)) - (first packages-of i)) * 2) ) set gain2 (first packages-of i) - ( max list 0 ( ((first packages-of i) - (first packages-of (turtle first traders))) * 2) ) ifelse (gain2 > gain1) [set tradersToHelp lput (turtle first traders) tradersToHelp set tradersToHelpGain lput gain2 tradersToHelpGain] [set tradersToAskForHelp lput (turtle first traders) tradersToAskForHelp set tradersToAskForHelpGain lput gain1 tradersToAskForHelpGain] set traders butfirst traders ] ifelse (behavior-of i != 1 and behavior-of i != 3 and (max tradersToHelpGain) >= average-profit) [ ask (item (position (max tradersToHelpGain) tradersToHelpGain) tradersToHelp) [give-my-next-task-to-agent i (max tradersToHelpGain)] set owners remove (who-of (item (position (max tradersToHelpGain) tradersToHelpGain) tradersToHelp)) owners set tradersToHelp remove (item (position (max tradersToHelpGain) tradersToHelpGain) tradersToHelp) tradersToHelp set tradersToHelpGain replace-item (position (max tradersToHelpGain) tradersToHelpGain) tradersToHelpGain 10000 set tradersToHelpGain remove 10000 tradersToHelpGain ] [ while [not empty? tradersToAskForHelp][ set j item (position (max tradersToAskForHelpGain) tradersToAskForHelpGain) tradersToAskForHelp ask i [ try-to-give-next-task-to-agent j (max tradersToAskForHelpGain)] ifelse (empty? packages-of i)[ ;if I gave it then Im done set tradersToAskForHelp [] set tradersToAskForHelpGain [] ] [ set tradersToAskForHelp remove (item (position (max tradersToAskForHelpGain) tradersToAskForHelpGain) tradersToAskForHelp) tradersToAskForHelp set tradersToAskForHelpGain replace-item (position (max tradersToAskForHelpGain) tradersToAskForHelpGain) tradersToAskForHelpGain 10000 set tradersToAskForHelpGain remove 10000 tradersToAskForHelpGain ] ] ] ] if (not empty? packages-of i)[ while [not empty? tradersToHelp][ if ((max tradersToHelpGain) > average-profit / 4) [set j item (position (max tradersToHelpGain) tradersToHelpGain) tradersToHelp ask j [give-my-next-task-to-agent i (max tradersToHelpGain)] set owners remove (who-of (item (position (max tradersToHelpGain) tradersToHelpGain) tradersToHelp)) owners ] set tradersToHelp remove (item (position (max tradersToHelpGain) tradersToHelpGain) tradersToHelp) tradersToHelp set tradersToHelpGain replace-item (position (max tradersToHelpGain) tradersToHelpGain) tradersToHelpGain 10000 set tradersToHelpGain remove 10000 tradersToHelpGain ]] ask i [ if (not empty? packages) [ set heading (first first deliveries) * spoke-mult set deliveries but-first deliveries ] ] set owners butfirst owners ask deliverators with [not empty? packages] [set steps max packages] ] end;reports the agent's cost for doing all delivrsto-report get-costs-from [delivrs] locals [res] set res [] while [not empty? delivrs][ set res lput (item 1 first delivrs * 2) res set delivrs butfirst delivrs] report resend;Report the extra cost that agnt will incurr if it accepts task, given its current task (first deliverables);This method is explained in the 1996 paper.to-report extra-cost [agnt task-dist task-spoke] if (spoke-of agnt != task-spoke)[ ;laura first first deliveries-of report 0] ;only report cost if they are both on the same fin ifelse (task-dist <= first packages-of agnt)[ ;item 1 first deliveries-of laura report task-dist] ;if task is closer than mine then cost is just cost to get there [ report 2 * task-dist - first packages-of agnt] ;if task is farther than mineend;;;;;;; Member functions for the Deliverators.;;;;;;;Initialize the agent's deliveries.to set-deliveries locals [i] set deliveries make-deliveries set average-cost mean get-costs-from deliveries set steps 0 set balance [] while [i < num-deliverators][ set i i + 1 set balance lput 0 balance]endto-report reciprocating-agent-accepts-my-next-task? [ag] ifelse (rating-of ag <= average-rating + (average-rating / 2) and rating >= average-rating / 4) [report true][report false]end to give-my-next-task-to-agent [to-agent profit] locals [his-extra-cost task] set his-extra-cost extra-cost to-agent first packages spoke set (packages-of to-agent) lput (first packages) (packages-of to-agent) set (accepted-package-of to-agent) true set (helping-of to-agent) lput who (helping-of to-agent) set (balance-of to-agent) replace-item who (balance-of to-agent) ((item who balance-of to-agent) - his-extra-cost) set balance replace-item (who-of to-agent) balance ((item (who-of to-agent) balance) + (2 * first packages)) ;update my balance of him..nice guy. set rating-of to-agent (rating-of to-agent + 1) set average-rating (mean values-from deliverators [rating]) set deliveries butfirst deliveries set packages [] set profits lput profit profits ;print "PROFIT:" ;print profit set average-profit (mean profits)end;Assumes that the next task for me and ag is on the same spoke.to try-to-give-next-task-to-agent [ag profit] locals [my-cost his-cost] ifelse (profit > average-profit) [give-my-next-task-to-agent ag profit] [ if (reciprocating-agent-accepts-my-next-task? ag) [ give-my-next-task-to-agent ag profit] ]end;Assumes that the next task for me and ag is on the same spoke.to try-to-give-next-task-to-agent2 [ag profit]give-my-next-task-to-agent ag profitendto deliver locals [willing-to-help] if (empty? packages and name-of patch-here = "depot") [ ;nothing to deliver stop] if (steps = 0)[ ;at delivery site, turn around set heading heading + 180 set packages [] ] fd distance-mult set dist dist + 1 set steps steps - 1end@#$#@#$#@GRAPHICS-WINDOW2461056132517179.011000CC-WINDOW245326560446Command CenterBUTTON2178350NILsetupNIL1TOBSERVERBUTTON841716550NILupdateNIL1TOBSERVERBUTTON1651724650NILupdateT1TOBSERVERSLIDER2
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?