Public Choice Tiebout Sorting

Public Choice Tiebout Sorting preview image

1 collaborator

Default-person Patrick Schwabl (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.0.3 • Viewed 164 times • Downloaded 16 times • Run 0 times
Download the 'Public Choice Tiebout Sorting' 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

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;  BREEDS AND GLOBAL VARIABLES ;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
globals [ relocations interjuris] ; global variable to count relocations and interjuris-distance

breed [ parties party ]
breed [ citizens citizen ]

patches-own [
  current-platform ; a list positions (0 = no; 1 = yes) on every issue currently in force in every jusristicion
  majorparty ; the current biggest party in this community
  sharevotes; the share of votes every party in the juristicion currently holds
  mean-wealth ; mean wealth (money) of citizens on this patch
  max-wealth ; wealth of richest agent on patch
]
parties-own [
  platform ; a list of positions on every issue the party currently propagates
  prop-platform ; a helper list to store a hypothetical platform a party could progapagate, to see how well it would do in elections
  newsharevotes ; a helper variable to store the votes a party would get with prop-platform
  lastexpsharevotes ; a helper variable to store the parties votes with their last proposed platform
  party-id ; a id that numerates all parties within their community
]

citizens-own [
  preferences ; a list of utility gained, if a issue were implemented
  utility ; the actual utility gained in the community the agent is currently living in
  exp-utility ; utility the agent would expect to recieve in another community
  party-distance ; a list to calculate the distance from the agents positions to every parties position on every issue in the community
  destination ; the x-coordinate of the patch where an agent can expect higher utility
  money ; money to move
  rank-list ; ranking of parties for borda count
]

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;; SETUP PROCEDURES ;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

to setup
  clear-all
  reset-ticks
  setup-patches ; sets up all patches, also sets up the party-agents within all the patches
  setup-citizens ; creates all citizens with their initial variables
  calculate-utility
end 

to setup-citizens
  create-citizens num-agents
  ask citizens [
    set shape "circle"
    set size 0.04
    set color green
    if wealth-dist = "beta" [set money (random-beta 2 5) * 1000] ; a society with a skewed distribution of wealth
    if wealth-dist = "normal" [set money random-normal 500 125] ; a society with a quite egalitarian distribution of wealth
    set utility 0 ; initialize utility for every agent at -10
    set preferences [] ; empty list for storing preferences
    let i 0
    while [i < num-issues] ; loop over all issues;
    [
      let pref random-float ( 800 / num-issues) - (400 / num-issues) ; use condition applied by Kollman et al. (1997)
      set preferences lput pref preferences ; append preference on issue i to preference lists of agents
      set i i + 1 ; preferences are drawn from a random distribution, the more issues there are the more split
    ]             ; up the preferance space gets (e.g. with 2 issues the maximum value of utility of each
                  ; issue is 200; with 10 issues this value shrinks to 40
      go-to patch-at random-pxcor random-pycor ; moves agents around inside their patch, so they dont stack on one another in the middle
  ]
end 

to-report random-beta [ p q ]
  let gamma1 random-gamma p 1
  let gamma2 random-gamma q 1
  let result gamma1 / ( gamma1 + gamma2 )
  report result
end 

to setup-patches
  resize-world 0 (num-jurisdictions - 1) 0 0 ; create patches given by the slider, all alonge the x-axis
  ask patches [
     if any? citizens-here[
      set mean-wealth mean [money] of citizens-here
      set max-wealth max [money] of citizens-here]
     set pcolor random 10
     set current-platform [] ; empty list for platform on num-issues
     let i 0
     while [ i < num-issues ]
      [
        set current-platform lput random 2 current-platform ; let the patches platforms be randomly chosen form 0 (con) and 1 (pro)
        set i i + 1
      ]
    ; create parties in each justisticion
    if voting-system = "two-party-majority" [ set num-parties 2 sprout-parties num-parties set sharevotes n-values num-parties [0]]
    ; two parties on every patch with initial sharevotes 0
    if voting-system = "multi-party-proporional" [ sprout-parties num-parties set sharevotes n-values num-parties [0]]
    ; num-parties parties on every patch with initial sharevotes 0
    if voting-system = "multi-party-relative-majority" [ sprout-parties num-parties set sharevotes n-values num-parties [0]]
    ; num-parties parties on every patch with initial sharevotes 0
    if voting-system = "borda-count" [ sprout-parties num-parties set sharevotes n-values num-parties [0]]
  ]
    ; num-parties parties on every patch with initial sharevotes 0
  ask parties[
    set size 0.1
    set shape "person"
    set color yellow
    set party-id who mod num-parties ; enumerates all parties from 0 to num-parties within every community
    go-to patch-here
    set platform []
    let i 0
    while [i < num-issues]
      [
        set platform lput random 2 platform ; let the parties platforms be randomly chosen form 0 (con) and 1 (pro)
        set i i + 1
      ]
  ]
end 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;; GO PROCEDURES ;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

to go
  calculate-utility ; calculates the utility agents get in their current community
  move-citizens ; exit, citizens move to another community, where they expect the recieve more utility
  let r 0
  while [r < 5]
  [
    parties-change ; gives the parties a chance to adapt their platforms, according to voters tastes
    set r r + 1
  ]
  alter-platform
  calculate-interjuris-distance
  change-preferences
  tick
end 

to go-to [ some-patch ]
   setxy ([ pxcor ] of some-patch + (random-float 0.9) - 0.45)
     ([ pycor ] of some-patch + (random-float 0.9) - 0.45)
end 

to calculate-utility
  ask patches[
    ask citizens-here[
      set utility 0
      let i 0
      while [ i < num-issues ]
      [
        set utility utility + item i preferences * item i current-platform
        set i i + 1
      ]
    ]
  ]
end 

to move-citizens ; citizens may move to other jurisdictions if they expect a higher utility
  ask citizens[ ; asks all citizens to do something
   let agent self ; sets the current citizen doing something
   let j 0
    while [ j < num-jurisdictions ] ; loop over all jurisdictions
    [
      let exp-utility_help [utility] of agent ; a helper variable to store the citizens utility for patch j-1
      set exp-utility 0 ; set the expected utility of the agent (self) 0
      ask patch j 0 [ ; ask patch j to do something
      let i 0
      while [ i < num-issues ] ; loop over all issues
      [
        ask agent [ set exp-utility exp-utility + item i preferences * item i [current-platform] of patch j 0 ]
        ; calculate the expected utility
        set i i + 1
      ]
      ]
      ask agent [ if exp-utility > exp-utility_help
      [
        set destination j ; set the x-coordinate of the patch the agent will move to
        set utility exp-utility ; set the new utility
      ]
      ]
      set j j + 1
    ]
  ]
  ask citizens [
    if [pxcor] of patch-here != destination and
    ( money > ( affluence-needed-to-move * [mean-wealth] of patch destination 0 ) ) ; or random 101 < 10 )
    ; affluence-needed-to-move is the percentage of wealth (his money) an agent needs to have in relation to his destination patch
    ; if this condition is fulfilled, the agent wants to move. if he has to money to do so, he will do it, otherwise its a game of chance
        [move-to patch destination 0
         go-to patch-at random-pxcor random-pycor
         set relocations relocations + 1 ]] ; whenever an agent finds a patch with higher utility, the relocation counter
  ; is increased, agents reloate all at once

  ask patches [
    if any? citizens-here [set mean-wealth mean [money] of citizens-here]]
end 

to change-preferences
  if random 101 < probability-of-change-mind [ ; chance thank an "event" takes place in whichs consequence some citizens change their mind
    ;ask n-of (int (0.10 * count citizens)) citizens [ ; only every 10th citizen is influenced
    ask citizens [
    ;ask citizens with [who mod 10 = 0][ ; only every 10th citizens is influenced
      let i 0
      while [i < num-issues]
      [
        if random 101 < probability-of-change-mind ; in addition to an event taking place, that event has to actually
        ; influence the opinion of an agent
        [
          let pref random-float ( 800 / num-issues ) - ( 400 / num-issues )
          set preferences replace-item i preferences pref
        ]
        set i i + 1
      ]
    ]

  ]
end 

to alter-platform
  if voting-system = "direct-democracy"[
  ask patches [
     ; in direct democracy the median vote is the platform that wins
      let i 0
      if count citizens-here > 0[
      while [ i < num-issues ]
      [
        let medianvote median [item i preferences] of citizens-here;loop over issues and calculate median of citizens
        ifelse medianvote < 0 ;if preferences of citizens are negative towards issue i...
        [set current-platform replace-item i current-platform 0];...the platform of the patch is 0 (agianst issue)
        [set current-platform replace-item i current-platform 1];...else...the platform of the patch is 1 (pro issue)
        ;print medianvote
        set i i + 1
      ]
     ]
    ]
  ]
  if voting-system = "two-party-majority" [
    vote
    ask patches [
      let maxsharevotes max sharevotes
      let j 0
      while [j < num-parties]
        [
          if maxsharevotes = item j sharevotes [set majorparty j]
          set j j + 1
        ]
    set current-platform [platform] of one-of parties-here with [party-id = majorparty] ; KANN DAS NICHT VERKĂśRZT WERDEN???
    ]
  ]
  if voting-system = "multi-party-proporional" [
    vote
    ask patches [
      let i 0
      while [ i < num-issues ]
      [
        let j 0
        let voteissue 0 ; local variable to store proporional representation for each issue, considering all party proporional to their voteshare
        while [ j < num-parties ]
        [
          set voteissue voteissue + item j sharevotes * [item i platform] of one-of parties-here with [party-id = j]
          ; if for example a party has 0.3 of the votes and is in favour of an issue the result for this party is the following:
          ; 0.3*1, so the pro vote of that party on the issue is taken into account proporional to its electoral success
          ; if it is against an issue: 0.3*0, therefore the whole vote is weight down in direction of 0, which makes it harder
          ; for other parties that are in favour of that issue to still reach the threshold of 0.5 to pass a 'yes' vote on the issue
          set j j + 1
        ]
        ifelse voteissue = 0.5 [][ ; in case of an exact parity of votes, nothing happens, otherwise...
          ifelse voteissue < 0.5 ;...if the the proportional votes are below 0.5...
          [set current-platform replace-item i current-platform 0];...the patches platform is set to zero
          [set current-platform replace-item i current-platform 1]];...otherwise the patches platform is set to one
          set i i + 1
      ]
    ]
  ]
   if voting-system = "multi-party-relative-majority" [ ; in a system with many parties and relative majority ...
    vote ; ... again, people vote
    ask patches [
      let maxsharevotes max sharevotes
      let j 0
      while [j < num-parties]
        [
          if maxsharevotes = item j sharevotes [set majorparty j] ; just as with absolute majority, the party that has the most votes ...
          set j j + 1 ; ... will win. The only difference is, that now a party can win with e.g. 30% of the votes, if no other as more
        ]
    set current-platform [platform] of one-of parties-here with [party-id = majorparty] ; patches platform is set to winning parties platform
  ]
  ]
  if voting-system = "borda-count"[ ; in a borda count system with many parties
    vote
    ask patches [
    let maxsharevotes max sharevotes
    let j 0
    while [j < num-parties]
      [
        if maxsharevotes = item j sharevotes [set majorparty j] ; just as with absolute majority, the party that has the most votes ...
        set j j + 1 ; ... will win. The only difference is, that now a party can win with e.g. 30% of the votes, if no other as more
      ]
     set current-platform [platform] of one-of parties-here with [party-id = majorparty] ; patches platform is set to winning parties platform
  ]




  ]
end 

to vote
  ask patches [
    let cumvotes n-values num-parties [0] ; list with zeros to store cumulated votes of all parties
    ask citizens-here [
      set party-distance n-values num-parties [0] ; fill list of citizens to measure distance to parties with zeros
        let j 0
        while [j < num-parties] ; loop over parties...
        [
          let i 0
          while [ i < num-issues]; ... and over issues
          [
            ;if one-of parties-here with party-id = j
            set party-distance replace-item j party-distance (item j party-distance + (item i preferences)
              * ([item i platform] of one-of parties-here with [party-id = j]))
            ; the line above gives every citizen a utility according to a parties platform (wether the party
            ; show party-distance
            set i i + 1
          ]
          set j j + 1
        ]
      ifelse voting-system = "borda-count" [
      ;;;;;;;;;;;;;;;;;;;;;;;;;; voting for borda ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
        let party-dist-sorted sort-by < party-distance ; sort parties in increasing order
        set rank-list []
        foreach party-distance
        [
          x ->
          set rank-list lput ( position x party-dist-sorted ) rank-list
          ; show party-distance
          ; show rank-list
        ]
        let kk 0
        while [kk < num-parties]
        [
          set cumvotes replace-item kk cumvotes (item kk cumvotes + item kk rank-list)
          set kk kk + 1
      ]]
      [
        ;;;;;;;;;;;;;;;;;;;;;;;;;; voting in all other systems with parties ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
        let kk 0
        while [kk < num-parties]
        [
          if max party-distance = item kk party-distance [set cumvotes replace-item kk cumvotes (item kk cumvotes + 1)]
          set kk kk + 1
        ]
      ]
      ;;;;;;;;;;;;;;;;;;;;;;;;;;; calculating vote share, same for borda and others ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
      let k 0
      while [k < num-parties]
      [
        set sharevotes replace-item k sharevotes ( item k cumvotes / ( sum cumvotes + 0.0000000000000000000000001 ) )
        set k k + 1
      ]
     ]
  ]
end 

to poll-voters
  set newsharevotes n-values num-parties [0] ; list of zeros to store every parties new voteshare
  let cumvotes n-values num-parties [0] ; list of zeros to store every parties new cumulated votes
  ask n-of (int (0.10 * count citizens-here)) citizens-here [ ; poll only 10 percent of citizens
    let exputility-party n-values num-parties [0] ; list of zeros to store citizens expected utility from parties
    let j 0
    while [j < num-parties]
    [
      let exputil_help 0
      let party_j one-of parties-here with [party-id = j]
      let i 0
      while [ i < num-issues]
      [
        set exputil_help exputil_help + (item i preferences) * ([item i prop-platform] of party_j)
        set i i + 1
      ]
      set exputility-party replace-item j exputility-party exputil_help
      set j j + 1
    ]
    let kk 0
    while [kk < num-parties]
    [
      if max exputility-party = item kk exputility-party [set cumvotes replace-item kk cumvotes (item kk cumvotes + 1)]
      set kk kk + 1
    ]
  ]
  let i 0
  while [i < num-parties]
  [
    set newsharevotes replace-item i newsharevotes (item i cumvotes / (sum cumvotes + 0.0000000000000000000000001))
    set i i + 1
  ]
end 

to parties-change
  ask parties [set prop-platform platform]
  ask parties [
    poll-voters
    set lastexpsharevotes item party-id newsharevotes
    let k 0
    while [k < 8]
    [
      set prop-platform platform
      let i 0
      while [i < 3] ; every party has 3 chances to change its platform to get a higher voter turnout
      [
        set prop-platform replace-item ( random num-issues ) prop-platform ( random 2 )
        set i i + 1
      ]
      poll-voters
      if item party-id newsharevotes > lastexpsharevotes [set platform prop-platform set lastexpsharevotes item party-id newsharevotes]
      set k k + 1
    ]
  ]
end 

to calculate-interjuris-distance
  let j 0
  let k 1 ; start k one ahead of j
  let cumsum 0
  while [j < num-jurisdictions] ; to achieve all possible pairwise comparisons we have to go over all patches ...
  [
    while [k < num-jurisdictions] ; ... and every patch that is one index higher
    [
      let list1 [current-platform] of patch j 0 ; get platform of patch j
      let list2 [current-platform] of patch k 0 ; get platform of patch k
      let diff (map - list1 list2) ; calculate the difference of every item in the plaforms
      let diff2 (map * diff diff) ; square it, so that there are no negative values (its all zeros and ones anyway, so nothing bad will happen)
      let sumdiff sum diff2 ; get the sum of that list
      set cumsum cumsum + sumdiff ; cumulate that sum
      set k k + 1
    ]
    set j j + 1 ; set j to the next patch ...
    set k j + 1 ; ... and set k to one index higher then j
  ]
  set interjuris cumsum
  set interjuris ( cumsum / num-issues) ; interjuris distance is calculated by dividing the cumulated error sum by the number of issues ...
  set interjuris ( interjuris / ( ( num-jurisdictions * ( num-jurisdictions - 1 ) ) / 2 ) ) ; ... and also take the mean of all possible pairwise comparisons
end 

There is only one version of this model, created about 5 years ago by Patrick Schwabl.

Attached files

File Type Description Last updated
Public Choice Tiebout Sorting.png preview Preview for 'Public Choice Tiebout Sorting' about 5 years ago, by Patrick Schwabl Download

This model does not have any ancestors.

This model does not have any descendants.