Rubin and Schneider (2021)

No preview image

1 collaborator

Default-person Sean Huang (Author)

Tags

(This model has yet to be categorized with any tags)
Visible to everyone | Changeable by the author
Model was written in NetLogo 6.4.0 • Viewed 76 times • Downloaded 2 times • Run 0 times
Download the 'Rubin and Schneider (2021)' modelDownload this modelEmbed this model

Do you have questions or comments about this model? Ask them here! (You'll first need to log in.)


Info tab cannot be displayed because of an encoding error

Comments and Questions

Please start the discussion about this model! (You'll first need to log in.)

Click to Run Model

;;;;;;;;;;;;;;;;;;;;;;;;
;;; Setup Procedures ;;;
;;;;;;;;;;;;;;;;;;;;;;;;
globals [
         remover ;; tracks the number of ticks so we can "retire" scientists once the number of scientists reaches num-scientists
         ticks-on-contest ;; tracks the number of ticks used on display-contest to calibrate aspects of model which depend on time-steps
       ]
turtles-own [group] ;; if a turtle has group = 0, it is a part of a HEG. If a turtle has group = 1, it is part of a HUG.

to setup
  clear-all
  set-default-shape turtles "circle"
  ;; make the initial network of two turtles and an edge
  create-turtles num-links [
    set color red
    create-links-with other turtles
    fd 8
  ]
  set remover 3 - num-scientists
  set ticks-on-contest 0
  reset-ticks
end 

;;;;;;;;;;;;;;;;;;;;;;;
;;; Main Procedures ;;;
;;;;;;;;;;;;;;;;;;;;;;;


;; go procedure for building and maintaining network

to go
  ask turtles [set color red] ;; reset color if the model has just finished running display-contest
  ask links [ set color gray ]
  make-node
  set remover remover + 1
  if remover >= 0 [
    ask turtle remover [
      die
    ]
  ]
  layout
  tick
end 

;; reports the difference between the proportion of contests won by a HEG member and the proportion of contests won by a HUG member

to-report heg-advantage
  let hug-wins 0
  let heg-wins 0
  repeat num-contests [
    ifelse run-contest = 0 [
      set heg-wins heg-wins + 1
    ]
    [ if run-contest = 1 [
      set hug-wins hug-wins + 1
      ]
    ]
  ]
  report (heg-wins - hug-wins ) / num-contests
end 

;; reports the winner of a contest

to-report run-contest
  ;code for assigning contestants
  random-seed new-seed
  let winner nobody
  let hug-player one-of turtles with [group = 1]
  let heg-player one-of turtles with [group = 0]
  ask hug-player [set color blue]
  ask heg-player [set color green]
  while [count turtles with [color = red] != 0] [
    let scientist one-of turtles with [color = red]
    let blues turtles with [color = blue]
    let greens turtles with [color = green]
    let blues-list sort blues
    let greens-list sort greens
    set blues-list map [i -> path-length scientist i ] blues-list
    set greens-list map [i -> path-length scientist i] greens-list
    let distance1 min blues-list
    let distance2 min greens-list
    ifelse distance1 < distance2 [
      ask scientist [set color blue]
    ] [
      ifelse distance2 < distance1 [
        ask scientist [set color green]
      ] [
        ask scientist [set color one-of [blue green]]
      ]
    ]
  ]
  ifelse (count turtles with [color = blue] > 66) [
    set winner hug-player
    print ("Player from HUG wins!")
  ] [
    ifelse (count turtles with [color = green] > 66) [
      set winner heg-player
      print ("Player from HEG wins!")
    ] [
      print ("Tie!")
    ]
  ]
  reset-contest
  ifelse winner != nobody [
    report [group] of winner
  ]
  [ report 2]
end 

;; a procedure that displays each step of a attribution contest.

to display-contest
  random-seed new-seed
  let winner nobody
  let hug-player one-of turtles with [group = 1]
  let heg-player one-of turtles with [group = 0]
  ask hug-player [set color blue]
  ask heg-player [set color green]
  while [count turtles with [color = red] != 0] [
    let scientist one-of turtles with [color = red]
    let blues turtles with [color = blue]
    let greens turtles with [color = green]
    let blues-list sort blues
    let greens-list sort greens
    set blues-list map [i -> path-length scientist i ] blues-list
    set greens-list map [i -> path-length scientist i] greens-list
    let distance1 min blues-list
    let distance2 min greens-list
    print (word "The scientist is " distance1 " steps away from the closest blue scientist. "
               "The scientist is " distance2 " steps away from the closest green scientist.")
    ifelse distance1 < distance2 [
      ask scientist [set color blue]
    ] [
      ifelse distance2 < distance1 [
        ask scientist [set color green]
      ] [
        ask scientist [set color one-of [blue green]]
      ]
    ]
    tick
    set ticks-on-contest ticks-on-contest + 1
  ]
  ifelse (count turtles with [color = blue] > 66) [
    set winner hug-player
    print ("Player from HUG wins!")
  ] [
    ifelse (count turtles with [color = green] > 66) [
      set winner heg-player
      print ("Player from HEG wins!")
    ] [
      print ("Tie!")
    ]
  ]
end 

;; procedure to reset a contest

to reset-contest
  ask turtles [set color red]
end 

;; procedure to make a node and connect it with other nodes.

to make-node
  create-turtles 1
  [
    set color red
    let community-proportion population_proportion / (1 + 10 * e ^ (-0.5 * (ticks - ticks-on-contest))) ;; here we use ticks-on-contest so that the ticks used in displaying a contest do not count towards the actual time-steps.
    ifelse random-float 1 <= community-proportion [
      set group 1
      set shape "box"
      set size 3
    ]
    [
      set group 0
    ]
    let partners find-partners self
    let old-nodes map [i -> item 0 i] partners
    foreach old-nodes [
      i ->
      create-link-with i [ set color green ]
      move-to i
      fd 8
    ]
    ;; code for adding advisors
    if count turtles >= 50 [
      let partner-list first partners
      let partner-turtle first partner-list
      let partner-link-neighbors sort [link-neighbors] of partner-turtle
      foreach partner-link-neighbors [
        i ->
        if self != i [ ; Ensure we're not linking to ourselves
          let ran random-float 1
          if ran < .5 [
            create-link-with i [ set color blue ]
          ]
        ]
      ]
    ]
  ]
end 

;; procedure to find partners that a new node will connect to

to-report find-partners [new-node] ;; issue with turtle 178
  let old-nodes sort turtles with [self != new-node]
  let degrees sum map [i -> count [link-neighbors] of i] old-nodes
  let similarities sum map [i -> similarity new-node i] old-nodes
  let turtle-weights map [i -> list (i) (homophily * (similarity new-node i / (1 + similarities)) +
    (1 - homophily) * (count [link-neighbors] of i / degrees))] old-nodes
  ;; We weigh each turtle's chances of connecting based on their similarity and degree. See Rubin and Schneider (2021).
  report lottery-winners turtle-weights
end 

;; reports 1 if two nodes are in the same group and 0 otherwise.

to-report similarity [new-node old-node]
  ifelse [group] of new-node = [group] of old-node [
    report 1
  ]
  [
    report 0
  ]
end 

;; procedure that determines the group of nodes a new node will connect to.

to-report lottery-winners [turtle-weights]
  set turtle-weights shuffle turtle-weights
  let results []

  repeat num-links [
    let weights map [i -> item 1 i] turtle-weights
    let pick random-float sum weights
    let result nobody

    foreach turtle-weights [
      i ->
      if result = nobody [
        ifelse pick <= item 1 i [
          set result i
        ] [
          set pick pick - item 1 i
        ]
      ]
    ]

    if result != nobody [ ;;issue here
      set turtle-weights remove result turtle-weights
      set results lput result results
    ]
  ]
  report results
end 

;; a procedure that reports the shortest path-length between two turtles using depth-first search

to-report path-length [start-turtle end-turtle]
  if start-turtle = end-turtle [ report 0 ] ; Path length is 0 if both turtles are the same

  let visited-nodes []
  let queue (list (list start-turtle 0)) ; Queue contains pairs of turtle and path length

  while [not empty? queue] [
    let current-item first queue
    let current-turtle item 0 current-item
    let current-length item 1 current-item
    set queue butfirst queue

    if not member? current-turtle visited-nodes [
      set visited-nodes lput current-turtle visited-nodes

      if current-turtle = end-turtle [
        report current-length ; Found the end turtle, report the path length
      ]

      ask current-turtle [
        let next-neighbors link-neighbors with [not member? self visited-nodes]
        let next-neighbors-list sort next-neighbors
        foreach next-neighbors-list [
          x ->
          set queue lput (list x (current-length + 1)) queue
        ]
      ]
    ]
  ]
  report -1 ; Return -1 or some indicator if no path is found
end 

;;;;;;;;;;;;;;
;;; Layout ;;;
;;;;;;;;;;;;;;

;; resize-nodes, change back and forth from size based on degree to a size of 1

to resize-nodes
  ifelse all? turtles [size <= 1]
  [
    ;; a node is a circle with diameter determined by
    ;; the SIZE variable; using SQRT makes the circle's
    ;; area proportional to its degree
    ask turtles [ set size sqrt count link-neighbors ]
  ]
  [
    ask turtles [ set size 1 ]
  ]
end 

to layout
  ;; the number 3 here is arbitrary; more repetitions slows down the
  ;; model, but too few gives poor layouts
  repeat 3 [
    ;; the more turtles we have to fit into the same amount of space,
    ;; the smaller the inputs to layout-spring we'll need to use
    let factor sqrt count turtles
    ;; numbers here are arbitrarily chosen for pleasing appearance
    layout-spring turtles links (1 / factor) (350 / factor) (20 / factor)
    display  ;; for smooth animation
  ]
  ;; don't bump the edges of the world
  let x-offset max [xcor] of turtles + min [xcor] of turtles
  let y-offset max [ycor] of turtles + min [ycor] of turtles
  ;; big jumps look funny, so only adjust a little each time
  set x-offset limit-magnitude x-offset 0.1
  set y-offset limit-magnitude y-offset 0.1
  ask turtles [ setxy (xcor - x-offset / 2) (ycor - y-offset / 2) ]
end 

to-report limit-magnitude [number limit]
  if number > limit [ report limit ]
  if number < (- limit) [ report (- limit) ]
  report number
end 

There is only one version of this model, created 8 months ago by Sean Huang.

Attached files

No files

This model does not have any ancestors.

This model does not have any descendants.