;; breeds declaration breed [ nodes ] breed [ edges ] breed [ circles ] ;; global variables globals [ iteration num-of-terminals rate-cellular data-rates players num-players num-opponents num-clusters-units num-clusters-rates freq-clusters-units freq-clusters-rates freq-cluster-breaking num-broken-clusters num-of-games num-of-clusters tot-clusters-units tot-clusters-rates num-coop color-map probe ;; variable for debugging clusters-list edges-list ;;links colors color-coop color-no-coop ;;power-data for WLAN cooperation full-coop-54 full-coop-48 full-coop-36 full-coop-24 full-coop-18 full-coop-12 full-coop-9 full-coop-6 ;;number of nodes with each strategy num-kind-selfish num-selfish num-loyal num-wise num-kind-loyal ; num-unforgiving ;;number of interactions by each strategy num-kind-selfish-games num-selfish-games num-loyal-games num-wise-games num-kind-loyal-games ; num-unforgiving-games ; num-unknown-games ;;total power received by all nodes playing each strategy kind-selfish-power selfish-power loyal-power wise-power kind-loyal-power ; unforgiving-power ;; total average power power-players power-opp power-system tot-power-system tot-power-coop tot-num-coop power-coop avg-power-system avg-power-coop gain-coop avg-gain-coop avg-gain-system ] ;; the own field store the inner data of each terminal ;; follows the implementation given for the PD N-Person Iterated ;; N.B. power of each terminal is stored in the node label nodes-own [ num-in-neighborhood neighborhood neighbor-edges strategy ;; strategy for games behaviour old-strategy power-cluster is-player? ;; true if the node is a player clustered? ;; means --> cooperating in a group checked? connected-nodes answer ;; answer of terminal to current game rate cluster ;; store agentset for current cluster num-in-cluster num-neighbors partner-history out-edges ] edges-own [a b] ;;;;;;;;;;;;;;;;;;;;;; ;;;Setup Procedures;;; ;;;;;;;;;;;;;;;;;;;;;; to store-initial-node-counts set num-players initial-n-players set num-selfish n-selfish set num-wise n-wise ; set num-unforgiving n-unforgiving end ;; setup global variables to setup ca store-initial-node-counts ;; create the screen edges ask patches with [abs pxcor = max-pxcor or abs pycor = max-pycor] [ set pcolor gray ] ;; setup global variables and initialize parameters for analisy ;; set num-of-terminals n-of-wireless-terminals set-data ;; set data-rates and payoff-list set color-map [5 15 25 35 45 115 125 135] ;; colors for different rates set color-coop 45 ;; yellow set color-no-coop 3 ;; dark gray set iteration 0 set num-of-games 0 set num-coop 0 set gain-coop 0 set tot-clusters-units 0 set tot-clusters-rates 0 set freq-clusters-units [] set freq-clusters-rates [] set freq-cluster-breaking 0 set num-broken-clusters 0 set power-coop 0 set tot-power-coop 0 set tot-num-coop 0 set tot-power-system 0 set avg-gain-coop 0 set avg-gain-system 0 set avg-power-system 0 set avg-power-coop 0 ;; initialize frequency lists repeat 8 [ set freq-clusters-units fput 0 freq-clusters-units ] repeat 8 [ set freq-clusters-rates fput 0 freq-clusters-rates ] ;; setup nodes and edges set-default-shape edges "line" set-default-shape nodes "mobile phones" setup-nodes ;; setup nodes and distribute them randomly ;; set player-strategy value-from random-one-of players [ strategy ] ;; to be used with a halo to follow the specified player end to set-data set data-rates [54 48 36 24 18 12 9 6] ;; 8 data rates for WLAN set rate-cellular 6 ;; power levels for WLAN coop, max num of cooperators in a group is 10, Rc = 6 set full-coop-54 [ 0.6667 0.5030 0.4211 0.3720 0.3393 0.3159 0.2983 0.2847 0.2738 ] set full-coop-48 [ 0.6863 0.5200 0.4369 0.3870 0.3538 0.3300 0.3122 0.2983 0.2873 ] set full-coop-36 [ 0.7450 0.5711 0.4842 0.4320 0.3972 0.3724 0.3538 0.3393 0.3277 ] set full-coop-24 [ 0.8625 0.6733 0.5788 0.5220 0.4842 0.4571 0.4369 0.4211 0.4085 ] set full-coop-18 [ 0.9800 0.7756 0.6733 0.6120 0.5711 0.5419 0.5200 0.5030 0.4893 ] set full-coop-12 [ 1.2150 0.9800 0.8625 0.7920 0.7450 0.7114 0.6863 0.6667 0.6510 ] set full-coop-9 [ 1.4500 1.1844 1.0517 0.9720 0.9189 0.8810 0.8525 0.8304 0.8127 ] set full-coop-6 [ 1.9200 1.5933 1.4300 1.3320 1.2667 1.2200 1.1850 1.1578 1.1360 ] end ;; setup the nodes and distribute them randomly to setup-nodes ;; Create the appropriate number of nodes and sets the variables that all nodes share cct-nodes num-kind-selfish [ set strategy "kind-selfish" set-nodes] cct-nodes num-selfish [ set strategy "selfish" set-nodes] cct-nodes num-loyal [ set strategy "loyal" set-nodes] cct-nodes num-wise [ set strategy "wise" set-nodes] cct-nodes num-kind-loyal [ set strategy "kind-loyal" set-nodes] ; cct-nodes num-unforgiving [ set strategy "unforgiving" set-nodes] set num-of-terminals count nodes ask nodes [ set is-player? true ] ;; N.B. everybody is set to player here! ; ask random-n-of num-players nodes with [ strategy = players-strategy ] [ set is-player? true set color red ] ;; set players group and update the counters set players nodes with [ is-player? ] update-node-counts ask nodes [ set old-strategy strategy ] ;; initialize the old-strategy setup-history-lists ;;initialize PARTNER-HISTORY list in all nodes end to set-color-nodes if strategy = "kind-selfish" [ set color blue ] if strategy = "selfish" [ set color green ] if strategy = "loyal" [ set color red ] if strategy = "wise" [ set color cyan ] if strategy = "kind-loyal" [ set color magenta ] end to update-node-counts ; if players-strategy = "kind-selfish" [ set num-kind-selfish num-kind-selfish + num-players ] ; if players-strategy = "selfish" [ set num-selfish num-selfish + num-players ] ; if players-strategy = "loyal" [ set num-loyal num-loyal + num-players ] ; if players-strategy = "wise" [ set num-wise num-wise + num-players ] ; if players-strategy = "kind-loyal" [ set num-kind-loyal num-kind-loyal + num-players ] ; if players-strategy = "unforgiving" [ set num-unforgiving num-unforgiving + num-players ] set num-players count nodes with [ is-player? ] set num-opponents count nodes with [ not is-player? ] end ;; set the common properties of each terminal to set-nodes set-color-nodes set num-neighbors 0 set num-in-cluster 1 set power-cluster 1 set rate 0 set is-player? false set answer false set connected-nodes nobody set label 1 ;; the label is used to store the avg-power set clustered? false set cluster nobody set checked? false set neighbor-edges nobody set out-edges [] set connected-nodes nobody rt random-float 360 setxy max-pxcor max-pycor ;; ensure that there are no nodes on the walls while [pcolor = gray] [ setxy random-float world-width random-float world-height ] end ;; for the moment, the terminals are only capable to remember the last move ;; of the opponent to setup-history-lists let num-nodes count nodes let default-history [] ;;initialize the DEFAULT-HISTORY variable to be a list repeat num-nodes [ set default-history (fput false default-history) ] ask nodes [ set partner-history default-history ] end ;;;;;;;;;;;;;;;;;;;;;;;; ;;;Runtime Procedures;;; ;;;;;;;;;;;;;;;;;;;;;;;; ;; if possible, add a new player to add-player if ( num-players + 1 <= count nodes ) [ set num-players num-players + 1 ;; update counter let new-player one-of nodes with [ not is-player? ] ;; choose a new player ask new-player [ set old-strategy strategy set strategy players-strategy set is-player? true set color green ] set players nodes with [ is-player? ] ;; set the new players agentset update-node-counts ] end ;; remove a player from the game to remove-player if ( num-players > 0 ) [ set num-players num-players - 1 let old-player one-of players ask old-player [ set strategy old-strategy set is-player? false set color blue ] ;; if old-player had a cluster, cluster is deleted if ( clustered?-of old-player ) [ ask nodes with [ member? self cluster-of old-player ] [ reset-clusters if ( not is-player? ) [ set color blue ] ] ask edges with [ a = old-player ] [ disappear ] ] set players nodes with [ is-player? ] update-node-counts ] end to form-edge [ current-player ] ;; cluster-node procedure, connect all the neighboring nodes ;; uses procedure check-connection if ( not check-connection current-player ) [ connect-to current-player ] end to connect-to [other-node] ;; node procedure, creates the edge ;; set the edge properties hatch 1 [ set breed edges ;; it's the same to use "hatch-edges 1" set color color-no-coop set a other-node ;; that's the current player set b myself set (out-edges-of a) lput self (out-edges-of a) set (out-edges-of b) lput self (out-edges-of b) reposition ] end to-report connected-to? [other-node] ;; node procedure, reports whether the connection is established report member? other-node (map [b-of ?] out-edges) end to reposition ;; edge procedure: position the edge setxy (xcor-of a) (ycor-of a) set heading towards-nowrap b ;; set direction of link set size distance-nowrap b ;; size stores the distance jump (distance-nowrap b) / 2 set-label end to set-label ;; edge procedure ;; Set the edge-label with the appropriate data-rate and the ;; proper node color as a function of distance. ;; The maximum possible range is implicitly fixed to 8 unit distance ;; If maximum range is exceeded just re-color the nodes ;; and delete the link. let b-player? member? b players ifelse ( size > max-range ) ;; can be possible after moving! [ disappear ] [ set label nobody let dist 0 let counter 0 while [ label = nobody ] [ ifelse ( size > dist and size <= dist + 1 ) [ set label item counter data-rates ] [ set dist dist + 1 set counter counter + 1 ] ] ] end to disappear ;; edge procedure, called by set-labels-and-colors ;; Delete the edge when is too long and update node labels set label-of a 1 set label-of b 1 set (out-edges-of a) remove self (out-edges-of a) set (out-edges-of b) remove self (out-edges-of b) die end to move ;; makes the nodes move randomly, they bounce back when finding a wall rt (random-float 10 - random-float 10) while [pcolor-of patch-ahead 1 = gray ] [ rt random-float 360 ] fd random-float 0.1 end to go without-interruption [ clear-last-round ] set iteration iteration + 1 ask nodes [ move ] ;; all nodes move around randomly ask edges [ reposition ] ;; edges reposition after moving ask nodes [ find-neighborhood ] ;; all nodes set the neighborhood at the max-range ask players [ cluster-up ] ; ask players with [ not clustered? ] ;; ask the left nodes to cluster-up ; [ set neighborhood neighborhood with [ not clustered? ] ; set num-in-neighborhood count neighborhood ; cluster-up ] do-bookkeeping ;; collect data and display charts end to setup-static ;; Distribute nodes in a circle of selected radius and play static cooperation setup ask nodes [ rt random-float 360 setxy 0 0 jump random-float static-radius ] set-default-shape circles "thin-ring" cct-circles 1 [ set size 2 * static-radius set color yellow ] ask nodes [ find-neighborhood ] ask players [ cluster-up ] set iteration 1 do-bookkeeping end ;; nodes find the neighborhood at the max specified range and set the links to find-neighborhood let current-node self set neighborhood nodes in-radius-nowrap max-range ;; neighborhood of current-node is set set num-in-neighborhood count neighborhood ;; to the max-range neighborhood let neighbor-nodes neighborhood with [ self != current-node ] if ( num-in-neighborhood > 1 ) [ ;; found somebody in the neighborhood, positive match ;; creates the links to the neighboring nodes, if they are not already present ask neighbor-nodes [ form-edge current-node ] ;; (take care of the node color as well) ] end ;; players try to find the likely-partners to make the clusters for cooperation to cluster-up without-interruption [ ;; the current-player cannot be interrupt while is searching ;; if there are neighbors to cluster-up ---> play ifelse ( num-in-neighborhood > 1 ) [ search-clusters ] [] ;; otherwise: if no neighbors, don't do anything ] end ;;;;;;;;;;;;;;;;;;;;; ;;;Game Procedures;;; ;;;;;;;;;;;;;;;;;;;;; ;; Useful subroutines to handle add/remove unit from agentsets ;; ---> the caller is current player to-report add-node [ curr-nodes new-node ] ifelse ( curr-nodes != nobody ) [ report neighborhood with [ member? self curr-nodes or self = new-node ] ] [ report neighborhood with [ self = new-node ] ] end to-report remove-node [ curr-nodes node ] ifelse ( curr-nodes != nobody ) [ report curr-nodes with [ self != node ] ] [ report nobody ] end to-report add-edges [ curr-edges new-edges ] ifelse ( curr-edges != nobody ) [ report edges with [ member? self curr-edges or member? self new-edges ] ] [ report new-edges ] end ;; Find groups for cooperation and play elite. Implicit assumptions : ;; - only homogeneus cooperation is considered (rate is chosen as the min rate ;; in the cluster) ;; - the calling routine cluster-up ensure player is not an isolated terminal to search-clusters let curr-player self let curr-nodes neighborhood ;; set current set of edges let curr-edges edges with [ member? a curr-nodes and member? b curr-nodes ] ;; set lists of connections in the current neighborhood ask neighborhood [ set-connected-nodes curr-nodes set neighbor-edges curr-edges ] ;; initialize lists and agentsets for current search set clusters-list [] set edges-list [] let parent-nodes curr-nodes with [ self = curr-player ] let parent-edges nobody ;; run ricorsive subroutine find-cluster find-clusters parent-nodes ;; play cooperation with the potential clusters found in current neighborhood play-coop curr-player end to find-clusters [ parent-nodes ] ;; Ricorsive subroutine find-clusters: find all possible connected cluster ;; in the current neighborhood let parent self let my-connected connected-nodes with [ not member? self parent-nodes ] if ( my-connected != nobody ) [ ask my-connected [ let curr self set connected-nodes remove-node connected-nodes parent set connected-nodes-of parent remove-node connected-nodes-of parent curr let new-cluster add-node parent-nodes curr let new-edges edges with [ member? a new-cluster and member? b new-cluster ] set clusters-list fput new-cluster clusters-list set edges-list fput new-edges edges-list find-clusters new-cluster ] ] end ;; Set the list of connected nodes for each terminal in the current neighborhood to set-connected-nodes [ curr-nodes ] let curr self let other nobody foreach out-edges [ ifelse ( a-of ? = curr ) [ set other b-of ? ] [ set other a-of ? ] if ( member? other curr-nodes ) [ set connected-nodes add-node connected-nodes other ] ] end to play-coop [ curr-player ] ;; Try to play elite cooperation while cluster-list is not empty; ;; Decisions are taken depending on the nodes strategy. ; let cluster-formed? false while [ not empty? clusters-list ] [ ;; find the potential cluster (connected) with minimum avg-power per node (best opportunity) ; let curr-label min labels ; let pos position curr-label labels let curr-cluster first clusters-list let curr-edges first edges-list ;; new cluster rate is the minumum rate of all current links let curr-rate label-of min-one-of curr-edges [ label ] let num-cluster count curr-cluster let curr-label 0 ifelse ( num-cluster <= 10 ) [ set curr-label item ( num-cluster - 2 ) get-power-coop curr-rate ] [ set curr-label item 8 get-power-coop curr-rate ] ;; if all nodes agree on cooperation, make the cluster and set coop ---> on ;; here is the cluster negotiation ask curr-cluster [ select-action curr-label curr-cluster curr-player ] if ( agree-on-coop? curr-cluster ) [ set num-of-games num-of-games + 1 clear-old-clusters curr-cluster make-new-cluster curr-cluster curr-edges curr-rate curr-label ] ; set cluster-formed? true ] ;; otherwise update the lists and play again set clusters-list remove-item 0 clusters-list set edges-list remove-item 0 edges-list ; set labels remove-item pos labels ] end to-report agree-on-coop? [ curr-cluster ] ;; Check whether nodes in current best cluster agree on cooperation ;; depending on different player strategies let num-pos-ans count curr-cluster with [ answer = true ] let num-cluster count curr-cluster ifelse ( num-pos-ans = num-cluster ) [ report true ] [ report false ] end to clear-old-clusters [ new-cluster ] ;; clear the old clusters of the new nodes joining the group, if already existing ;; N.B. even curr-player could have already been clustered! let new-nodes new-cluster with [ clustered? ] ;; new nodes are the terminals coming from already formed clusters ask new-nodes [ set num-broken-clusters num-broken-clusters + 1 let current self ;; cluster refers to the old-cluster of current new-node let old-cluster cluster with [ self != current and not member? self new-cluster ] let conn-edges edges with [ ( a = current and member? b old-cluster ) or ( b = current and member? a old-cluster ) ] ;; clear old links to new node ask conn-edges [ set color color-no-coop ] let num-old count old-cluster ;; set properly the labels in the old-cluster and clear the clusters ;; where cooperation brings no more advantage ifelse ( num-old > 1 ) [ let old-edges edges with [ member? a old-cluster and member? b old-cluster ] let new-rate label-of min-one-of old-edges [ label ] let new-label item ( num-old - 2 ) ( get-power-coop new-rate ) ;; if old-cluster still agree on cooperation form a new group ;; (N.B. First reset the old-labels!!) ifelse ( new-label < 1 ) [ make-new-cluster old-cluster old-edges new-rate new-label ] ;; otherwise break the old-cluster and release partners [ ask old-edges [ set color color-no-coop ] ask old-cluster [ reset-clusters update-num-games ] ] ] [ ask old-cluster [ reset-clusters update-num-games ] ] ] end to make-new-cluster [ new-cluster new-edges new-rate new-label ] let num-cluster count new-cluster ;; set cluster properties ask new-cluster [ update-num-games set clustered? true set cluster new-cluster set num-in-cluster num-cluster set rate new-rate set label new-label set power-cluster ( label * num-in-cluster ) ] ask new-edges [ set color color-coop ] end to update-num-games if strategy = "kind-selfish" [ set num-kind-selfish-games num-kind-selfish-games + 1 ] if strategy = "selfish" [ set num-selfish-games num-selfish-games + 1 ] if strategy = "loyal" [ set num-loyal-games num-loyal-games + 1 ] if strategy = "wise" [ set num-wise-games num-wise-games + 1 ] if strategy = "kind-loyal" [ set num-kind-loyal-games num-kind-loyal-games + 1 ] end to-report check-connection [ current ] ;; called by: form-edge / set-connected? let other-node current ;; is there a connection? ifelse (not connected-to? other-node) and (not value-from other-node [connected-to? myself]) [ report false ] ;; not connected [ report true ] ;; connected end to-report get-power-coop [ curr-rate ] if ( curr-rate = 54 ) [ report full-coop-54 ] if ( curr-rate = 48 ) [ report full-coop-48 ] if ( curr-rate = 36 ) [ report full-coop-36 ] if ( curr-rate = 24 ) [ report full-coop-24 ] if ( curr-rate = 18 ) [ report full-coop-18 ] if ( curr-rate = 12 ) [ report full-coop-12 ] if ( curr-rate = 9 ) [ report full-coop-9 ] if ( curr-rate = 6 ) [ report full-coop-6 ] end ;; clear the last game to clear-last-round ask nodes [ set neighborhood nobody set num-in-neighborhood 1 set neighbor-edges nobody ] let clustered-nodes nodes with [ clustered? ] ask clustered-nodes [ reset-clusters ] ask edges with [ color = color-coop ] [ set color color-no-coop ] end ;;reset-clusters to reset-clusters set clustered? false set cluster nobody set num-in-cluster 1 set power-cluster 1 set label 1 set rate 0 end ;;choose an action based upon the strategy being played to select-action [ curr-label curr-cluster curr-player ] ;;node procedure if strategy = "kind-selfish" [ kind-selfish curr-label ] if strategy = "selfish" [ selfish curr-label ] if strategy = "loyal" [ loyal curr-label ] if strategy = "wise" [ wise curr-label curr-cluster curr-player ] if strategy = "kind-loyal" [ kind-loyal curr-label ] ; if strategy = "unforgiving" [ unforgiving ] end ;;update PARTNER-HISTORY based upon the strategy being played to update-history if strategy = "kind-selfish" [ kind-selfish-history-update ] if strategy = "selfish" [ selfish-history-update ] if strategy = "loyal" [ loyal-history-update ] if strategy = "wise" [ wise-history-update ] if strategy = "kind-loyal" [ kind-loyal-history-update ] ; if strategy = "unforgiving" [ unforgiving-history-update ] end ;;;;;;;;;;;;;;;; ;;;Strategies;;; ;;;;;;;;;;;;;;;; ;;All the strategies are described in the Information Tab. to kind-selfish [ curr-label ] ;; act as a sefish but has a "sacrifice threshold": the unit can join ;; the group even if not gaining whereas the loss is small ;; (here the threshold is set to 10% power loss) ifelse ( curr-label < label ) [ set answer true ] [ let power-loss ( ( curr-label - label ) / curr-label ) ifelse ( power-loss <= 0.1 ) [ set answer true ] [ set answer false ] ] end to kind-selfish-history-update ;;uses no history- this is just for similarity with the other strategies end to selfish [ curr-label ] ;; if I gain I will join you! ifelse ( curr-label < label ) [ set answer true ] [ set answer false ] end to selfish-history-update ;;uses no history - decision is based on node's own profit end to loyal [ curr-label ] ;; if not already clustered, act as a selfish one ifelse ( not clustered? ) [ selfish curr-label ] [ set answer false ] end to loyal-history-update ;; ? end to kind-loyal [ curr-label ] ifelse ( not clustered? ) [ kind-selfish curr-label ] [ set answer false ] end to kind-loyal-history-update ;; end to wise [ curr-label curr-cluster curr-player ] ;; Make new cluster only if: 1) the new total power consumption of the local evironment ;; (new cluster + old clusters where coop is still present) is better than the former one; ;; 2) all the terminals in the proposed cluster agree on coop (sure if they are wise, ;; because the current player has already found the best possibility and others trust him) ifelse ( self != curr-player ) [ set answer true ] ;; if node is the current player play-wise-coop [ play-wise-coop curr-label curr-cluster ] end to play-wise-coop [ curr-label curr-cluster ] ;; Current player calculate the overalls and take the decision on cooperation. ;; First calculate the new overall power assuming to make a new cluster ;; from the proposed one and preserving cooperation whereas possible in the ;; eventual broken clusters ( power-curr-cluster + power-ext ). ;; Calculate power from external clusters: let power-ext 0 ask curr-cluster [ set checked? true if ( clustered? ) [ let ext-nodes cluster with [ not member? self curr-cluster and not checked? ] let num-ext count ext-nodes if ( num-ext != 0 ) [ ask ext-nodes [ set checked? true ] ifelse ( num-ext > 1 ) [ let ext-edges edges with [ member? a ext-nodes and member? b ext-nodes ] let ext-rate label-of min-one-of ext-edges [ label ] let ext-label item ( num-ext - 2 ) ( get-power-coop ext-rate ) set power-ext power-ext + ( ext-label * num-ext ) ] [ set power-ext power-ext + 1 ] ] ] ] ;; N.B. considered nodes in the current computation are marked as "checked". ;; Now calculate power for curr cluster and new overall power consumption let power-new ( curr-label * count curr-cluster ) let new-overall power-new + power-ext ;; and the current overall power over the nodes that are now considered and ;; decide whether new cluster shall be made let curr-nodes nodes with [ checked? ] let curr-overall sum values-from curr-nodes [ label ] ask curr-nodes [ set checked? false ] ;; reset label 'checked' for next iteration ifelse ( new-overall < curr-overall ) [ set answer true ] [ set answer false ] end to wise-history-update ;; ?? end ;to unforgiving ; set num-unforgiving-games num-unforgiving-games + 1 ; set partner-defected? item (who-of partner) partner-history ; ifelse (partner-defected?) ; [set defect-now? true] ; [set defect-now? false] ;end ; ;to unforgiving-history-update ; if partner-defected? [ ; set partner-history ; (replace-item (who-of partner) partner-history partner-defected?) ; ] ;end ;;;;;;;;;;;;;;;;;;;;;;;;; ;;;Plotting Procedures;;; ;;;;;;;;;;;;;;;;;;;;;;;;; ;;procedure called by go that calculates power and plots to do-bookkeeping collect-info do-scoring do-plotting end ;;calculate the total power of each strategy to do-scoring set kind-selfish-power kind-selfish-power + (calc-power "kind-selfish" num-kind-selfish) set selfish-power selfish-power + (calc-power "selfish" num-selfish) set loyal-power loyal-power + (calc-power "loyal" num-loyal) set wise-power wise-power + (calc-power "wise" num-wise) set kind-loyal-power kind-loyal-power + (calc-power "kind-loyal" num-kind-loyal) ; set unforgiving-power (calc-power "unforgiving" num-unforgiving) ;; calculate the overall power consumption for category (players and opponents) set power-players (calc-power-players true num-players) set power-opp (calc-power-players false num-opponents) end ;; returns the total power for a strategy if any nodes exist that are playing it to-report calc-power [strategy-type num-with-strategy] ifelse num-with-strategy > 0 [ report (sum values-from (nodes with [ strategy = strategy-type ]) [ label ]) ] [ report 0 ] end ;; returns the total power consumption for a strategy if any nodes exist that are playing it to-report calc-power-players [player-type num-of-players] ifelse count players > 0 [ report (sum values-from (nodes with [ is-player? = player-type ]) [ label ]) ] [ report 0 ] end ;;if a strategy has had any interactions, plot the avereage power per interaction to do-plotting ;; plot the strategies power set-current-plot "Average Power" if ( num-kind-selfish > 0 ) [ set-current-plot-pen "kind-selfish" plot kind-selfish-power / num-kind-selfish / iteration ] if ( num-wise > 0 ) [ set-current-plot-pen "wise" plot wise-power / num-wise / iteration ] if ( num-selfish > 0 ) [ set-current-plot-pen "selfish" plot selfish-power / num-selfish / iteration ] if ( num-loyal > 0 ) [ set-current-plot-pen "loyal" ; plot loyal-power / (num-loyal-games) plot loyal-power / num-loyal / iteration ] if ( num-kind-loyal > 0 ) [ set-current-plot-pen "kind-loyal" plot kind-loyal-power / num-kind-loyal / iteration ] ; if num-unforgiving-games > 0 [ ; set-current-plot-pen "unforgiving" ; plot unforgiving-power / (num-unforgiving-games) ; ] ;; plot the power consumption of players and opponents set-current-plot "Power Players vs. Power Opponents" if num-players > 0 [ set-current-plot-pen "power-players" plot power-players / (num-players) ] if num-opponents > 0 [ set-current-plot-pen "power-opp" plot power-opp / (num-opponents) ] ;; plot the average power consumption of the network set-current-plot "Average System Power" if ( num-of-terminals > 0 ) [ ;; and iteration > 0 ) [ set-current-plot-pen "power-system" plot avg-power-system ] set-current-plot-pen "power-no-coop" plot 1 set-current-plot-pen "power-coop" if ( num-coop > 0 ) [ plot avg-power-coop ] ;; make the histograms of the cluster-occurency ;; and plot the average values vs. number of iterations display-charts end to display-charts ;; plot the first histogram set-current-plot "Cluster histogram 1" plot-pen-reset set-plot-pen-mode 1 set-plot-x-range 0 9 foreach num-clusters-units [ plot ? ] ;; plot the second histogram set-current-plot "Cluster histogram 2" plot-pen-reset set-plot-pen-mode 1 set-plot-x-range 0 9 let def-list [ 0 1 2 3 4 5 6 7 ] ( foreach def-list num-clusters-rates [ plotxy ?1 ?2 ] ) ;; plot the first average frequency values set-current-plot "Frequency Clusters 1" plot-pen-reset set-plot-pen-mode 1 set-plot-x-range 0 9 foreach freq-clusters-units [ plot ( ? / iteration ) ] ;; plot the second average frequency values set-current-plot "Frequency Clusters 2" plot-pen-reset set-plot-pen-mode 1 set-plot-x-range 0 9 ( foreach def-list freq-clusters-rates [ plotxy ?1 ( ?2 / iteration ) ] ) ;; plot the first pdf set-current-plot "pdf 1" plot-pen-reset set-plot-pen-mode 0 set-plot-x-range 0 9 if ( tot-clusters-units > 0 ) [ foreach freq-clusters-units [ plot ( ? / tot-clusters-units ) ] ] ;; plot the second pdf set-current-plot "pdf 2" plot-pen-reset set-plot-pen-mode 0 set-plot-x-range 0 9 if ( tot-clusters-rates > 0 ) [ ( foreach def-list freq-clusters-rates [ plotxy ?1 ( ?2 / tot-clusters-rates ) ] ) ] end to collect-info ;; collect information from the current iteration of the model ;; for the sake of analyses ask nodes with [ label = 1 ] [ set num-in-cluster 1 ] set num-coop count nodes with [ label != 1 ] ;; first two lines just set some parameters ( num-coop = current number of coop ), ;; then save old data in old-lists and reset current lists let counter 1 let old-list-units num-clusters-units let old-list-rates num-clusters-rates set num-clusters-units [] set num-clusters-rates [] ;; set num-clusters-units [ N ] ---> number of clusters of N-units repeat 8 [ let n1 ( ( count nodes with [ num-in-cluster = counter ] ) / counter ) set num-clusters-units ( lput n1 num-clusters-units ) set counter counter + 1 ] ;; set num-clusters-rates [ R ] ---> number of clusters of rate R foreach data-rates [ let def-list-rate [] set counter 1 repeat 8 [ let n2 ( ( count nodes with [ ( rate = ? ) and ( num-in-cluster = counter) ] ) / counter ) set def-list-rate ( lput n2 def-list-rate ) set counter counter + 1 ] set num-clusters-rates ( lput ( sum def-list-rate ) num-clusters-rates ) ] set num-of-clusters sum ( but-first num-clusters-units ) ;; only the cluster with J > 1 set tot-clusters-units tot-clusters-units + num-of-clusters let num-cl-rates sum num-clusters-rates set tot-clusters-rates tot-clusters-rates + num-cl-rates set freq-clusters-units add-list freq-clusters-units num-clusters-units set freq-clusters-rates add-list freq-clusters-rates num-clusters-rates ;; calculate avg-gain for cooperation ( only relative to the units that are coop each round ) ;; and for the system: current values set power-coop sum ( values-from nodes with [ label < 1 ] [ label ] ) if ( num-coop > 0 ) [ set gain-coop ( ( 1 - power-coop / num-coop ) * 100 ) ] set power-system sum ( values-from nodes [ label ] ) ;; totals update set tot-power-coop tot-power-coop + power-coop set tot-num-coop tot-num-coop + num-coop set tot-power-system tot-power-system + power-system ;; average values if ( num-coop > 0 ) [ set avg-power-coop ( tot-power-coop / tot-num-coop ) ] set avg-gain-coop ( 1 - avg-power-coop ) * 100 set avg-power-system ( tot-power-system / num-of-terminals / iteration ) set avg-gain-system ( 1 - avg-power-system ) * 100 set freq-cluster-breaking ( num-broken-clusters / iteration ) end to-report add-list [ old-list curr-list ] ;; add the values of the current list to the old list ;; and report the new list let new-list [] ( foreach old-list curr-list [ set new-list lput ( ?1 + ?2 ) new-list ] ) report new-list end ;;;;;;;;;;;;;;;;;;;;; ;;;Movie Procedure;;; ;;;;;;;;;;;;;;;;;;;;; ;; makes a movie of the model; stops when 300 iterations are done ;; and exports movie to a file to make-movie ;; prompt user for movie location user-message "Save your new movie file (choose a name ending with .mov)" let path user-new-file if not is-string? path [ stop ] ;; stop if user canceled ;; run the model setup movie-start path movie-grab-view while [ iteration <= 300 ] [ go movie-grab-view ] ;; export the movie movie-close user-message (word "Exported movie to " path) end @#$#@#$#@ GRAPHICS-WINDOW 369 10 879 541 12 12 20.0 1 10 1 1 1 0 1 1 1 -12 12 -12 12 CC-WINDOW 5 592 1255 687 Command Center 0 BUTTON 3 10 66 43 NIL setup NIL 1 T OBSERVER T NIL BUTTON 69 10 132 43 NIL go T 1 T OBSERVER T NIL BUTTON 135 10 238 43 step-by-step go NIL 1 T OBSERVER T NIL SLIDER 3 45 175 78 initial-n-players initial-n-players 0 100 0 1 1 NIL MONITOR 4 148 63 197 NIL iteration 3 1 PLOT 4 321 356 528 Average Power Iterations Ave Power / strategy 0.0 10.0 0.4 0.7 true true PENS "kind-selfish" 1.0 0 -13345367 true "wise" 1.0 0 -11221820 true "loyal" 1.0 0 -2674135 true "selfish" 1.0 0 -10899396 true "kind-loyal" 1.0 0 -5825686 true MONITOR 210 148 292 197 NIL num-opponents 3 1 MONITOR 64 148 141 197 NIL num-of-games 3 1 SLIDER 3 80 175 113 max-range max-range 1 8 5 1 1 NIL BUTTON 4 536 101 569 NIL make-movie NIL 1 T OBSERVER T NIL TEXTBOX 7 116 232 142 NOTE: the maximum reachable range of each terminal is set to 8 units distance. SLIDER 68 224 191 257 n-selfish n-selfish 0 100 10 1 1 NIL SLIDER 68 259 191 292 n-wise n-wise 0 100 10 1 1 NIL MONITOR 142 148 209 197 NIL num-players 3 1 BUTTON 265 250 357 283 NIL add-player NIL 1 T OBSERVER T NIL BUTTON 265 285 358 318 NIL remove-player NIL 1 T OBSERVER T NIL TEXTBOX 88 201 238 219 Nodes strategies CHOOSER 256 203 363 248 players-strategy players-strategy "selfish" "loyal" "wise-coop" "kind-selfish" "kind-loyal" "unforgiving" 2 PLOT 881 457 1041 577 Power Players vs. Power Opponents Iterations Ave Power / unit 0.0 10.0 0.0 2.0 true true PENS "power-players" 1.0 0 -2674135 true "power-opp" 1.0 0 -13345367 true PLOT 885 424 1163 573 Average System Power Iteration Ave Power / unit 0.0 10.0 0.0 1.0 true true PENS "power-system" 1.0 0 -13791810 true "power-no-coop" 1.0 0 -5825686 true "power-coop" 1.0 0 -2674135 true MONITOR 293 148 367 197 num-terminals num-of-terminals 3 1 PLOT 880 10 1065 147 Cluster histogram 1 Cluster size Num clusters 0.0 9.0 0.0 10.0 true false PENS "default" 1.0 1 -13345367 true PLOT 1066 10 1246 147 Cluster histogram 2 Data rate Num clusters 0.0 10.0 0.0 10.0 true false PENS "default" 1.0 1 -2674135 true MONITOR 1164 474 1236 523 NIL num-coop 3 1 MONITOR 193 529 273 578 NIL avg-gain-coop 3 1 PLOT 880 148 1065 285 Frequency Clusters 1 Cluster size Avg clusters 0.0 10.0 0.0 10.0 true false PENS "default" 1.0 0 -13345367 true PLOT 1066 148 1246 285 Frequency Clusters 2 Data rate Avg clusters 0.0 10.0 0.0 10.0 true false PENS "default" 1.0 0 -2674135 true MONITOR 1164 424 1236 473 num-clusters num-of-clusters 3 1 PLOT 880 286 1065 423 pdf 1 Cluster size Probability 0.0 10.0 0.0 1.0 true false PENS "default" 1.0 0 -13345367 true PLOT 1066 286 1246 423 pdf 2 Data rate Probability 0.0 10.0 0.0 1.0 true false PENS "default" 1.0 0 -2674135 true MONITOR 102 529 192 578 NIL avg-gain-system 3 1 MONITOR 274 529 345 578 freq-cl-brk freq-cluster-breaking 3 1 BUTTON 241 10 338 43 NIL setup-static NIL 1 T OBSERVER T NIL SLIDER 176 80 339 113 static-radius static-radius 0 10 10 1 1 NIL @#$#@#$#@ WHAT IS IT? ----------- The initial setting consist of a specified number of wireless terminal moving randomly in a square field. Several different strategies can be chosen by the user. HOW IT WORKS ------------ The program shows the quest for clusters at a user specified range (slider "radius"). Depending on distance, each unit of the cluster is assigned a color and each link a data-rate according to the WLAN specifications of IEEE802.11a/g A random set of terminals (players = green units) is chosen to look for opponents to play with, they are looking for cooperation (but the user can choose the players strategy). After finding the neighborhood, each player play his round depending on his own strategy and tries cluster-up when all the nodes in the current potential cluster agree on cooperation (also depending on strategies). Here 2 strategies are taken in consideration: selfish and wise. The actions of each unit are taken depending on the instantaneous profit (no history). Scores for each player are determined by the payoff matrix resulting from the calculations of the average power per unit in a cooperative secenario (see formulas on power consumption). HOW TO USE IT ------------- This section could explain how to use the model, including a description of each of the items in the interface tab. THINGS TO NOTICE ---------------- THINGS TO TRY ------------- This section could give some ideas of things for the user to try to do (move sliders, switches, etc.) with the model. EXTENDING THE MODEL ------------------- This section could give some ideas of things to add or change in the procedures tab to make the model more complicated, detailed, accurate, etc. NETLOGO FEATURES ---------------- This section could point out any especially interesting or unusual features of NetLogo that the model makes use of, particularly in the Procedures tab. It might also point out places where workarounds were needed because of missing features. RELATED MODELS -------------- This section could give the names of models in the NetLogo Models Library or elsewhere which are of related interest. CREDITS AND REFERENCES ---------------------- This section could contain a reference to the model's URL on the web if it has one, as well as any other necessary credits or references. @#$#@#$#@ default true 0 Polygon -7500403 true true 150 5 40 250 150 205 260 250 link true 0 Line -7500403 true 150 0 150 300 link direction true 0 Line -7500403 true 150 150 30 225 Line -7500403 true 150 150 270 225 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 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 mobile phones true 0 Rectangle -7500403 true true 90 60 210 270 Rectangle -7500403 true true 180 15 195 60 Rectangle -16777216 false false 105 75 120 90 Rectangle -16777216 false false 105 105 120 120 Rectangle -16777216 false false 180 105 195 120 Rectangle -16777216 false false 180 75 195 90 Rectangle -16777216 false false 105 135 120 150 Rectangle -16777216 false false 180 135 195 150 Circle -16777216 false false 135 225 30 Rectangle -16777216 false false 105 195 120 210 Rectangle -16777216 false false 180 195 195 210 Rectangle -16777216 false false 105 165 120 180 Rectangle -16777216 false false 180 165 195 180 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 4 Circle -1184463 false true -1 -1 301 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 3.1.3 @#$#@#$#@ @#$#@#$#@ @#$#@#$#@ @#$#@#$#@