Hotelling's Law

Hotelling's Law preview image

2 collaborators

Uri_dolphin3 Uri Wilensky (Author)

Tags

ccl 

Tagged by Uri Wilensky almost 12 years ago

social science 

Tagged by Reuven M. Lerner over 10 years ago

Model group CCL | Visible to everyone | Changeable by group members (CCL)
Model was written in NetLogo 5.0.4 • Viewed 886 times • Downloaded 54 times • Run 0 times
Download the 'Hotelling's Law' 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

turtles-own [
  price               ; How much each store charges for its product
  area-count          ; The area (market share) that a store held at the end of the last tick
]

patches-own [
  preferred-store     ; The store currently preferred by the consumer
]

globals [
  consumers           ; The patches that will act as consumers, either a vertical line or all patches
]
  
;;;;;;;;;;;;;;;;;;;;;;;;
;;; setup procedures ;;;
;;;;;;;;;;;;;;;;;;;;;;;;

to setup        
  clear-all
  setup-consumers
  setup-stores
  recalculate-area
  reset-ticks
end 

to setup-consumers
  ; Store the agentset of patches that are going to be our
  ; consumers in a global variable for easy reference.
  set consumers ifelse-value (layout = "line")
    [ patches with [ pxcor = 0 ] ]
    [ patches ]
end 

to setup-stores 
  ; We choose as many random colors as the number of stores we want to create
  foreach n-of number-of-stores base-colors [ 
    ; ...and we create a store of each of these colors on random consumer patches
    ask one-of consumers [
      sprout 1 [
        set color ? ; use the color from the list that we are looping through
        set shape "Circle (2)" 
        set size 2 
        set price 10
        set pen-size 5
      ]
    ]
  ]
end 

to go
  ; We accumulate location and price changes as list of tasks to be run later
  ; in order to simulate simultaneous decision making on the part of the stores
     
  let location-changes ifelse-value (rules = "pricing-only")
    [ (list) ] ; if we are doing "pricing-only", the list of moves is empty
    [ [ new-location-task ] of turtles ]
  
  let price-changes ifelse-value (rules = "moving-only")
    [ (list) ] ; if we are doing "moving-only", the list of price changes is empty
    [ [ new-price-task ] of turtles ]

  foreach location-changes run
  foreach price-changes run
  recalculate-area
  tick  
end 

to recalculate-area
  ; Have each consumer (patch) indicate its preference by 
  ; taking on the color of the store it chooses
  ask consumers [ 
    set preferred-store choose-store
    set pcolor ([ color ] of preferred-store + 2)
  ]
  ask turtles [
    set area-count count consumers with [ preferred-store = myself ]
  ]
end 

;;;;;;;;;;;;;;;;;;;;;;;;;
;;; turtle procedures ;;;
;;;;;;;;;;;;;;;;;;;;;;;;;

; Have the store consider the benefits of taking a unit step in each of the four cardinal directions
; and report a task that will allow the chosen location change to be enacted later

to-report new-location-task

  ; we want the neighbors4 in random order, but we want to turn them from an agentset to a list
  ; and `sort` is the way to do that, hence the weird `shuffle sort` expression
  let possible-moves shuffle sort (neighbors4 with [ member? self consumers ])
  
  if area-count > 0 [
    ; Only consider the status quo if we already have a market share, but if we consider it,
    ; put it at the front of the list so it is favored in case of ties in sort-by
    set possible-moves fput patch-here possible-moves
  ]

  ; pair the potiental moves with their revenues, and sort these pairs by revenues
  let moves-with-market-shares
    sort-by [ last ?1 > last ?2 ]
    map [ list ? (market-share-if-move-to ?) ] possible-moves

  ; report the first item of the first pair, i.e., the move with the best revenues
  let chosen-location first first moves-with-market-shares

  let store self ; put self in a local variable so that it can be "captured" by the task
  report task [
    ask store [
      pen-down 
      move-to chosen-location
      pen-up
    ]
  ]
end 

; report the market share area the store would have if it moved to destination

to-report market-share-if-move-to [ destination ] ; turtle procedure
  let current-position patch-here
  move-to destination
  let market-share-at-destination potential-market-share
  move-to current-position
  report market-share-at-destination
end 

to-report potential-market-share
  report count consumers with [ choose-store = myself ]
end 

; Have the store consider the revenue from hypothetically increasing or decreasing its price by one unit
; and report a task that will allow the chosen price change to be enacted later

to-report new-price-task

  ; We build a list of candidate prices, keeping the status quo in first, but having -1 and +1 in random 
  ; order after that. This order is going to be preserved by the `sort-by` primitive in case of ties,
  ; and we always want the status quo to win in this case, but -1 and +1 to have equal chances
  let possible-prices fput price shuffle list (price - 1) (price + 1)

  ; pair each potential price change with its potential revenue
  ; and sort them in decreasing order of revenue
  let prices-with-revenues
    sort-by [ last ?1 > last ?2 ]
    map [ list ? (potential-revenue ?) ] possible-prices

  let all-zeros? (not member? false map [ last ? = 0 ] prices-with-revenues)
  let chosen-price ifelse-value (all-zeros? and price > 1)
    [ price - 1 ] ; if all potential revenues are zero, the store lowers its price as an emergency procedure if it can
    [ first first prices-with-revenues ] ; in any other case, we pick the price with the best potential revenues

  let store self ; put self in a local variable so that it can be "captured" by the task
  report task [
    ask store [
      set price chosen-price
    ]
  ]
end 

to-report potential-revenue [ target-price ]
  let current-price price
  set price target-price
  let new-revenue (potential-market-share * target-price)
  set price current-price
  report new-revenue
end 

;;;;;;;;;;;;;;;;;;;;;;;
;;; patch procedure ;;;
;;;;;;;;;;;;;;;;;;;;;;;

; report the store with the best deal, defined as the smallest sum of price and distance

to-report choose-store
  report min-one-of turtles [ (price) + (distance myself) ]
end 


; Copyright 2009 Uri Wilensky.
; See Info tab for full copyright and license.

There are 4 versions of this model.

Uploaded by When Description Download
Uri Wilensky almost 11 years ago Updated to NetLogo 5.0.4 Download this version
Uri Wilensky over 11 years ago Updated version tag Download this version
Uri Wilensky over 11 years ago Updated to version from NetLogo 5.0.3 distribution Download this version
Uri Wilensky almost 12 years ago Updated from NetLogo 5.0 Download this version

Attached files

File Type Description Last updated
Hotelling's Law.png preview Preview for 'Hotelling's Law' almost 11 years ago, by Uri Wilensky Download
Hotelling's Law.png preview Preview for 'Hotelling's Law' almost 11 years ago, by Uri Wilensky Download

This model does not have any ancestors.

This model does not have any descendants.