Huff Turtle-Based

No preview image

This model is seeking new collaborators — would you please help?

1 collaborator

Default-person Steven Kimbrough (Author)

Tags

greedy hill climbing 

Tagged by Steven Kimbrough about 8 years ago

market area analysis 

Tagged by Steven Kimbrough about 8 years ago

Visible to everyone | Changeable by the author
Model was written in NetLogo 5.1.0 • Viewed 260 times • Downloaded 21 times • Run 0 times
Download the 'Huff Turtle-Based' modelDownload this modelEmbed this model

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


WHAT IS IT?

A number of establishments that compete for regional customer exist or are contemplated in a particular geographic area. Given the several locations and attractivenesses of these establishments, we would like to predict the market share each will achieve. We are interested in deciding whether to build a number of new establishments as well as where to put any we do decide to build.

This problem falls under the category of market area analysis, addressing one of the category's main concerns: the location of prospective retail stores. The Huff model is used extensively for this purpose. The Huff NetLogo model constitutes a simple implementation of the Huff model.

The basic formula for the Huff model is

P(i,j) = (S(j)alpha / T(i,j)beta) / sum(i=1,n)[(S(j)alpha / T(i,j)beta)]

where

  • P(i,j) is the probability of a consumer at a given origin i traveling to a particular shopping center j.
  • S(i) is the size of a shopping center j (typically measured in terms of the square footage of selling area devoted to the sale of a particular class of goods). More generally, a measure of attractiveness of the shopping center (with higher values more attractive than lower values).
  • T(ij) is the travel time or cost for customer i to go to shopping center j.

  • alpha is a parameter, to be estimated empirically but often simply set to 1, for scaling the importance of the attractiveness measure for the establishment, S(j).

  • beta is a parameter, to be estimated empirically but often simply set to 2 (hence the literature often speaks of the "Huff gravity model" for this class of models), reflecting the effect of travel time and other costs on various kinds of shopping trips.
  • n is the number of establishments or shopping centers under consideration.

Further, it is presumed in using this model that there are m customers, that each customer has a known location, and that each of the establishments under consideration has a known location, real or hypothetical.

The expected traffic for a store j is

expected_traffic(j) = sum(i=1,m)[P(i,j)]

HOW IT WORKS

Customers are represented by turtles of breed customers and displayed as small gray circles. The setup procedure arrays them randomly. There is nothing in the implementation that makes them move. Stores are represented by turtles of breed stores. The calculate-store-traffic procedure calculates P(i,j) for all customers i and stores j. The display-results procedure reports to the output widget the expected traffic for each store in the model. These two procedures are combined, with some error checking, in the Calculate Traffic & Display Results button.

You make pick an individual store and direct it to explore for an improved position. At each tick the chosen store will pick a random patch in its neighborhood of radius exp-radius, travel to the patch and cause the system to re-evaluate everyone's expected traffic. If the store finds its new expected traffic is better, it remains where it is and the tick is over. If not, the store returns to its original position and causes the original expected traffic values to be restored. You can direct this with the Store ID Explore button, which is a forever button.

Alternatively, you may ask all of the stores to explore in parallel. This is accomplished essentially with an ask stores directive, instead of an ask store X directive, where X is a store ID. You direct this with the Explore button, which is also a forever button.

HOW TO USE IT

Use the sliders to set the number of customers, n in the Huff formula, and alpha and beta in the Huff formula. Click the setup button to initialize the world. To add stores, click the add-drop-stores button and then click in the world on any patch that does not already have a store. If your click on a patch that already has a store over it, the store gets removed. Click the add-drop-stores button again when you are done adding or removing stores. Click on the Calculate Traffic & Display Results button to run the Huff formula on each of the customer-store combinations, and to report in the output widget the expected traffic for each store. Stores have a default size of 1 when they are added.

Once you have clicked on the Calculate Traffic & Display Results button you may direct individual or collective search for improved positions. To direct individual search by store with ID X,

  1. Edit the input widget exploring-store-id so that it contains X.
  2. Click the reset-ticks button.
  3. Adjust the exp-radius slider to have the value you want.
  4. Click the Store ID Explore button.
  5. Watch while the store moves around and the tick counter increases.
  6. Click the Store ID Explore button to halt search when you wish.
  7. Click the Display results button.

To direct collect search for improved positions,

  1. Click the reset-ticks button. This starts our clock anew.
  2. Adjust the exp-radius slider to have the value you want.
  3. Click the Explore button.
  4. Watch the stores move as the ticks counter increases.
  5. Click the Explore button again to halt search when you wish.
  6. Click the Display results button.

THINGS TO NOTICE

Changing the size of a store can have a substantial affect on the level of its expected traffic, especially if alpha is much greater than 1. You can easily change the size of a store by inspecting it and editing the size attribute.

The payoffs resulting from changes in position are often surprising, usually interesting.

THINGS TO TRY

You can use NetLogo commands to move the turtles/customers to non-random distributions. For example:

observer> ask turtles [set heading 180]
observer> ask turtles [fd 5]

Again, the payoffs resulting from changes in position are often surprising, usually interesting.

NETLOGO FEATURES

The code uses the NetLogo table extension multiple times in its calculation of P(i,j) and expected traffic.

RELATED MODELS

The Huff Turtles-Based NetLogo model is an extension of the Huff NetLogo model.

The coding methods here draw upon the Life NetLogo model, found in the Models Library.

The Huff model has an interesting relationship with Hotelling's spatial location models, which are implemented in the Hotelling's Law NetLogo model in the Models Library.

HOW TO CITE

If you mention this model in a publication, we ask that you include these citations for the model itself and for the NetLogo software:

  • Kimbrough, Steven O. (2014). Huff model. University of Pennsylvania, Philadelphia, PA. Huff.nlogo

COPYRIGHT AND LICENSE

Copyright 2014 Steven O. Kimbrough.

CC BY-NC-SA 3.0

This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.

Commercial licenses are also available. To inquire about commercial licenses, please contact Steven O. Kimbrough at kimbrough@wharton.upenn.edu.

Version: $Id: Huff Turtle-Based.nlogo 4336 2014-09-08 21:12:50Z sok $.

Comments and Questions

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

Click to Run Model

extensions [table]
globals[stores-traffic calculated?]
breed [customers customer]
breed [stores store] ;; Declare store breed after customer
;; breed so that stores will be viewed on top of customers.

stores-own [store-size]
customers-own [store-distances store-probabilities 
  total-distance
  total-attractiveness
  store-attractivenesses]

to setup
  clear-all
  set calculated? false
  ask patches [set pcolor white]
  create-customers num-customers
  ask customers [setxy random-xcor random-ycor
    set color gray
    set shape "circle" 
    set size 1 / 2
    ]
end 

to add-drop-stores
  let erasing? any? stores-on patch mouse-xcor mouse-ycor
  while [mouse-down?]
    [ask patch mouse-xcor mouse-ycor
      [ifelse erasing?
        [remove-store]
        [add-store]]
      display]
end 

to remove-store
  ask stores-here [die]
end 

to add-store
  if not any? stores-here
  [ask stores-here [die] ;; any existing stores are removed
    sprout-stores 1 [set color black
      set shape "house"
      set size 2
      set store-size 1]]
end 

to calculate-attractivness-statistics
  let n count stores
  ask customers [set store-distances []
    set store-probabilities []
    set store-attractivenesses []]  
  ; Record the store distances for each turtle.
  ask customers [
    let the-turtle self
    ask stores [
      let the-distance distance the-turtle
      let the-store self
      ask the-turtle [set store-distances fput (list the-distance the-store) store-distances]
    ]
  ]
  ; Not really needed:
  ask customers [set store-distances sort-by [first ?1 < first ?2] store-distances]
  ; Record the store-attractivenesses for each turtle.
  ; The attractiveness of a store is the
  ; product of the size of the store powered
  ; to the value of alpha, times the
  ; reciprocal of 
  ; distance to that store, powered to beta.
  ask customers [set store-attractivenesses table:make
    set total-distance  total-distances
    let td total-distance    
    foreach store-distances [
     let dist first ?
     let store last ?
     table:put store-attractivenesses [who] of store ;(list [pxcor] of store [pycor] of store) 
        ([store-size] of store) ^ alpha * (1 / dist) ^ beta
    ]
  ]
  ; Record the store-probabilities for each turtle.
  ask customers [set store-probabilities table:make
    set total-attractiveness total-attractivenesses
    foreach table:keys store-attractivenesses [
     table:put store-probabilities ? 
     (table:get store-attractivenesses ? / total-attractivenesses)
     ]
    ]
end 

to-report total-distances
  let answer 0
  foreach store-distances
  [set answer (answer + first ?)]
  report answer
end 

to-report total-attractivenesses
  let answer 0
  foreach table:keys store-attractivenesses
  [set answer (answer + table:get store-attractivenesses ?)]
  report answer  
end 

to calculate-store-traffic
  calculate-attractivness-statistics
  set stores-traffic table:make
  ask stores [  ; let x [xcor] of self
   ;let y [ycor] of self
   let key [who] of self ;(list x y)
   table:put stores-traffic key 0
  ]
;  set traffic-accumulator 0
  let keys table:keys stores-traffic
  foreach keys [
   ask customers [table:put stores-traffic ? 
     (table:get stores-traffic ? + table:get store-probabilities ?)
  ]
  ]
  ; ask stores [set expected-traffic table:get stores-traffic who]
end 

to display-results
  ; Now display it
  
  output-print (word "Store           Expected")
  output-print (word "  x   y    ID   Traffic")
  let listtable table:to-list stores-traffic
  set listtable sort-by [first ?1 < first ?2] listtable
  
  let sep ""
  repeat 24 [set sep (word sep "-")]
  let sepstar ""
  repeat 24 [set sepstar (word sepstar "*")]
  output-print sep
  foreach listtable [
    let x (word [xcor] of store first ?)
    let y (word [ycor] of store first ?)
    let id (word first ?)
    let paddingx ""
    repeat (3 - length x) [set paddingx (word paddingx  " ")]
    let paddingy ""
    repeat (4 - length y) [set paddingy (word paddingy  " ")]
    let paddingid ""
    repeat (6 - length id) [set paddingid (word paddingid " ")]
    let the-traffic (round (100 * last ?) / 100)
    let paddingtraffic ""
    repeat (9 - length (word the-traffic)) [set paddingtraffic (word paddingtraffic " ")]
    output-print (word  paddingx x paddingy y   paddingid id
      paddingtraffic the-traffic)]
  output-print sepstar
end 

to explore
  no-display
  let x xcor
  let y ycor
  let stores-traffic-temp stores-traffic
  move-to one-of patches in-radius exp-radius
  calculate-store-traffic
  if table:get stores-traffic who < 
       table:get stores-traffic-temp who
  ;; The move is not an improvement, so reverse it.
  [;print "No improvement"
    set xcor x
   set ycor y
   set stores-traffic stores-traffic-temp]
  display
end 

to-report get-store-ids
  let ids []
  ask stores [set ids fput who ids]
  report ids
end 

There is only one version of this model, created about 8 years ago by Steven Kimbrough.

Attached files

No files

This model does not have any ancestors.

This model does not have any descendants.