Enrico Minardi

Simulation models for economics

Project work on

"Water pollution in river basin model."

 

The applet requires Java 5 or higher. Java must be enabled in your browser settings. Mac users must have Mac OS X 10.4 or higher. Windows and Linux users may obtain the latest Java from Oracle's Java site.


Here you can find an introduction to the Water pollution in river basin model application.


powered by NetLogo

view/download model file: water_pollution_in_river_basin_model.nlogo

WHAT IS IT?

(a general understanding of what the model is trying to show or explain)

HOW IT WORKS

(what rules the agents use to create the overall behavior of the model)

HOW TO USE IT

(how to use the model, including a description of each of the items in the Interface tab)

THINGS TO NOTICE

(suggested things for the user to notice while running the model)

THINGS TO TRY

(suggested things for the user to try to do (move sliders, switches, etc.) with the model)

EXTENDING THE MODEL

(suggested things to add or change in the Code tab to make the model more complicated, detailed, accurate, etc.)

NETLOGO FEATURES

(interesting or unusual features of NetLogo that the model uses, particularly in the Code tab; or where workarounds were needed for missing features)

RELATED MODELS

(models in the NetLogo Models Library and elsewhere which are of related interest)

CREDITS AND REFERENCES

(a reference to the model’s URL on the web if it has one, as well as any other necessary credits, citations, and links)

CODE

breed [households household]
breed [firms firm]
breed [authorities authority]
breed[basin-authorities basin-authority]

turtles-own [jurisdictionTurtle]
firms-own [ pollutionClass ordersToFirm productionLevel currentPollution pollutionProduced billed totalCost relocationCost fixedCost VarCost profit assets-t0 assets-t1 meditation 
            K K-needed L L-needed needtohire needtofire countdown alpha dummygrowth varCost0 r w tax disposalCost]; 
households-own [ concern complaintForPollution pollutionNearMe dummy1 employed complaintForUnemployment]
patches-own [jurisdiction pollutionLevel polluted taxationPatch ] 
authorities-own [ meanPollutionInArea taxation reclamationCostPerFirm g p unemploymentRate-t1 unemploymentRate-t0 growthexpectation-t0 dummy-unemployment dummy-negativegrowthexp taxesCollected
  growthexpectation-t1 p-t1 p-t0 pollutionDisposalCost plantCapability currentAggregatePollution numberOfMyPatches numberOfMyHouseholds difference]

globals [ n all-patches authorityColorList pollutionClassList totalPollution year a b c d f numberOfFirms numberOfHouseholds q authority-failure n_over n_under m compensate pollutiontoDischarge z]

;;;;;;;;;;;;;;;;;;;;;;;;;;;;SETUP;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

to setup
  
  clear-all
  set pollutionClassList [0.1 0.2 0.3] ;list of values for the marginal damage produced 
  create-institution
  define-authorityJurisdiction
  set numberOfFirms howManyFirms
  create-productionsystem
  set numberOfHouseholds howManyHouseholds
  create-cities
  setup-plots
  reset-ticks
  
end

to create-institution

  set authorityColorList [5 15 25 35 45 55 65 75 85 95 105 115 125 135]
  create-authorities howManyAuthorities
  [set shape "authority"
   setxy random-xcor random-ycor
   set color one-of authorityColorList
   set authorityColorList remove color authorityColorList
   set jurisdictionTurtle who
   set taxation random-float 0.7
   set pollutionDisposalCost (1 + random-float 1)
   
   ]
  
end

to define-authorityJurisdiction
       
    set all-patches ((max-pxcor + 1)*(max-pycor + 1))
    ask authorities [ask patch-here
                       [set pcolor [color + 2] of myself
                        set jurisdiction [who] of myself
                        set taxationPatch [taxation] of myself
                       ]
                     ask neighbors 
                       [if (pcolor = 0)
                         [set pcolor [color + 2] of myself
                          set jurisdiction [who] of myself
                          set taxationPatch [taxation] of myself
                         ]
                       ]
                     ]
    while [ count patches with [pcolor != 0] != all-patches ]
          [ask patches with [pcolor = [color + 2] of authority n ]                                     ;Just already coulored patches are asked.
              [ask neighbors with [pcolor = 0]                                                         ;The number of coulored patches is fixed at t0, and just them are asked.
                  [set pcolor [color + 2] of authority n
                   set jurisdiction [jurisdiction] of myself
                   set taxationPatch [taxationPatch] of myself 
                   ]          
               ]   
           set n ( n + 1 )
           if n = howManyAuthorities [set n 0] 
           ]
    ask authorities
    [set numberOfMyPatches count patches with [jurisdiction = [who] of myself]
     set numberOfMyHouseholds count households with [jurisdictionTurtle = [who] of myself]
     set plantCapability (100 + count patches with [jurisdiction = [who] of myself])
     ]
end

to create-productionsystem

  create-firms numberOfFirms
  [set shape "firm"
   setxy random-xcor random-ycor
   set color [ color + 3] of authority [jurisdiction] of patch-here
   set pollutionClass one-of pollutionClassList
   set jurisdictionTurtle [jurisdiction] of patch-here
   
   set L 1
   set K (100000 + random 500 - random 500)     
   set alpha random-float 1
   ]
  
end


to create-cities

  create-households numberOfHouseholds
  [set shape "house"
   setxy random-xcor random-ycor
   set color [color + 3] of authority [jurisdiction] of patch-here
   set jurisdictionTurtle [jurisdiction] of patch-here
   set concern random 2   
   ]
  
end
    
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;TO GO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

to go
  
  if count patches with [pollutionLevel >= pollutionLimit] = all-patches or count firms = 0 [ stop ]
  if stopAfterFailure?
  [if authority-failure != 0
    [stop]
    ]
  set year floor ( ticks / 12)                                                                          ; As assumption, 12 ticks can be considered as a year
 ; add-or-subtract-agents                                                                               ; check before use! can be used to simulate a life-cicle.
  
  organize-production
  fire
  hire
  produce              
  diffuse-pollution_report_set-pollutionDisposalCost
  evaluateRelocation
  complainForPollution/Unemployment
  govern
  cooperate                                            ;in use only if switcher cooperate? is  set on
  tick

end


to organize-production
  
  ask firms
   [set ordersToFirm (ordersToFirm + random 10 - random 10)                                              ; random walk
    if ordersToFirm < 0
      [set ordersToFirm 0]
      
    set r abs(0.10 + random-float 0.005 - random-float 0.005)                                       
    
    ifelse count households with [jurisdictionTurtle = [jurisdictionTurtle] of myself] = 0
    [set w 1.1] 
    [set w ( 1.1 - (count households with [jurisdictionTurtle = [jurisdictionTurtle] of myself and employed = 0] / count households with [jurisdictionTurtle = [jurisdictionTurtle] of myself]))
      ]
    set K-needed floor(((((1 - alpha)/ alpha) * (r / w)) ^ (alpha - 1)) * ordersToFirm)                    ; level of K needed to produce ordersToFirm with given alpha, w and r
     
    set L-needed ceiling(((((1 - alpha)/ alpha) * (r / w)) ^ (alpha)) * ordersToFirm)                     ; level of L needed to produce ordersToFirm with given alpha, w and r
                                                                                                         ; PROD.FUNCTION: output = f(K,L) = (K ^ alpha) * (L ^ (1 - alpha)))    
    if K-needed > K
      [set VarCost (VarCost + ((K-needed - K) * r ))
       set K K-needed
       ]
    if K-needed < K
      [set VarCost (VarCost - ((K - K-needed) * r ))
       set K K-needed
       ]                                                                                                    
    
    if L < L-needed
      [set needtohire 1]
    if L != 1 and L > L-needed 
      [set needtofire 1]
    ]

 end

to fire
  
   while [count firms with [needtofire = 1] != 0]
   [ask firms with [needtofire = 1]
     [ifelse count households with [ employed = [who] of myself] != 0
       [ask one-of households with [ employed = [who] of myself]
         [set employed 0
          ask link who [who] of myself 
           [die]
          ]
        set L (L - 1)
        if L = L-needed
          [set needtofire 0]
        ]
       [set needtofire 0]
     ]
   ]

end          
          
to hire
  
  set d 0
  while [ d != howManyAuthorities]
   [if count firms with [ jurisdictionTurtle = d and needtohire = 1 ] != 0
     [if count households with [jurisdictionTurtle = d and employed = 0 ] != 0
        [while [count households with [jurisdictionTurtle = d and employed = 0 ] != 0 and count firms with [jurisdictionTurtle = d and needtohire = 1] != 0]
          [ask firms with [jurisdictionTurtle = d and needtohire = 1]
            [if count households with [jurisdictionTurtle = d and employed = 0] != 0
              [ask one-of households with [jurisdictionTurtle = d and employed = 0]
                [set employed [who] of myself
                 create-link-to firm [who] of myself 
                 ask link who [who] of myself [set color [color] of authority d]
                 ]
               set L (L + 1)
               if L = L-needed
                 [set needtohire 0]
               ]
             ]
           ]
         ]
      ]   
    set d (d + 1)
    ]
           
end

to produce
   ask firms
   [set productionLevel ((K ^ alpha ) * (L ^ (1 - alpha)))                                               ;now K and L are equal to K-needed and L-needed if enough workers were at disposal
     
    ifelse (ticks / 12) = 0 or (ticks / 12) != year 
      [set billed ( billed + (random 10 * productionLevel))                                              ; price is randomly determined
       set currentPollution (pollutionClass * productionLevel)                                           ; a tecnology swift should affect the pollution class
       set pollutionProduced (pollutionProduced + currentPollution)
       set disposalCost (disposalCost + ([pollutionDisposalCost] of authority jurisdictionTurtle * currentPollution))
       set VarCost ( VarCost + (L * w) + (K * r))                                       ; adding variable cost per month, now all the pollutant produced is declared.
       ]                                           
      [set billed ( billed + (random 10 * productionLevel))                                              ; adding last-month's data for production
       set currentPollution (pollutionClass * productionLevel)  
       set pollutionProduced (pollutionProduced + currentPollution)
       set disposalCost (disposalCost + ([pollutionDisposalCost] of authority jurisdictionTurtle * currentPollution))     ; now all the pollutant produced is declared.
       set VarCost ( VarCost + (L * w) + (K * r))                                       ;      "         "      "  for variable cost
       set tax (billed * [taxationPatch] of patch-here)
       ask authority jurisdictionTurtle
        [set taxesCollected (taxesCollected + [tax] of myself + [disposalCost] of myself)] 
       set totalCost (tax + RelocationCost + FixedCost + VarCost + disposalCost)                                        ; no fixed cost at the moment
       if totalCost > (999999999999999 * (E ^ 709))
        [set totalCost (999999999999999 * (E ^ 709))]
       set profit (billed - totalCost)
       set assets-t1 (assets-t0 + profit)
       if assets-t0 > 0                                                                                  ; to be developed
         [if ((assets-t1 / assets-t0) > 1)                                                               ;
           [ set dummygrowth 1]                                                                          ;
          if ((assets-t1 / assets-t0) < 1)                                                               ;
           [ set dummygrowth 0]                                                                          ;
          ]                                                                                              ;
          
       set assets-t0 assets-t1
       
       set billed 0
       set relocationCost 0
       set VarCost 0
       set totalCost 0
       set disposalCost 0
       
       ifelse assets-t0 < 0
         [set countdown (countdown + 1)]
         [set countdown 0]
       if countdown = yearsWithDeficit
         [goBankrupt]
       ]
      
    ask patch-here 
     [   set pollutionLevel (pollutionLevel + [currentPollution] of myself)
      ]  
    ]

end

to goBankrupt
  
  ask households with [employed = [who] of myself]
   [ set employed 0]
  ask links with [end2 = [who] of myself]
   [die]
  die

end


to diffuse-pollution_report_set-pollutionDisposalCost

  ask authorities
    [ask patches with [(jurisdiction = [who] of myself) and (pollutionLevel > 0)]
       [set n count neighbors
        set n_over count neighbors with [pycor > [pycor] of myself]
        set n_under count neighbors with [pycor <= [pycor] of myself]
        ifelse pollutionLevel > pollutionLimit
          [ask neighbors with [pycor <= [pycor] of myself]
             [set pollutionLevel (pollutionLevel + (( 0.8 / n_under)* pollutantDiffusion *([pollutionLevel] of myself - pollutionLimit ))) ;no / ininfluent climb up of pollutant
              ] 
           ifelse n_over != 0
             [ask neighbors with [pycor > [pycor] of myself]
               [set pollutionLevel (pollutionLevel + ((0.2 / n_over) * pollutantDiffusion * ([pollutionLevel] of myself - pollutionLimit ))) ; if neighbors are n=8, then each neighbor 
                ]                                                                                                                     ; inherits 1/8th of value pollutantDiffusion * pollutionLevel
              set pollutionLevel (pollutionLevel - (pollutantDiffusion * (pollutionLevel - pollutionLimit)))
              ]
             [set pollutionLevel (pollutionLevel - (0.8 * pollutantDiffusion * (pollutionLevel - pollutionLimit)))
              ]
           ] 
          [ask neighbors with [pycor <= [pycor] of myself]
             [set pollutionLevel (pollutionLevel + (( 0.8 / n_under)* pollutantDiffusion *[pollutionLevel] of myself )) ;no / ininfluent climb up of pollutant
              ] 
           ifelse n_over != 0
             [ask neighbors with [pycor > [pycor] of myself]
               [set pollutionLevel (pollutionLevel + ((0.2 / n_over) * pollutantDiffusion * [pollutionLevel] of myself )) ; if neighbors are n=8, then each neighbor 
                ]                                                                                                                     ; inherits 1/8th of value pollutantDiffusion * pollutionLevel
              set pollutionLevel (pollutionLevel - (pollutantDiffusion * pollutionLevel))
              ]
             [set pollutionLevel (pollutionLevel - (0.8 * pollutantDiffusion * pollutionLevel))
              ] 
          ]
       ]         
      
     set currentAggregatePollution (sum [currentPollution] of firms with [jurisdictionTurtle = [who] of myself])
     set pollutionDisposalCost ( currentAggregatePollution /  plantCapability)
      if currentAggregatePollution > 0
        [while [ q < currentAggregatePollution and count patches with [jurisdiction = [who] of myself and pollutionLevel > 0] != 0]
            [ask one-of patches with [jurisdiction = [who] of myself and pollutionLevel > 0]
              [set q (q + pollutionLevel)
               set pollutionLevel 0
               ]
             ]
         set difference (currentAggregatePollution - q)                    ; see to cooperate
         set currentAggregatePollution 0                                     
         set q 0                                                             
         ]
         
      
      ask patches with [(jurisdiction = [who] of myself) and (pollutionLevel > 0)]
       [ifelse pollutionLevel >= pollutionLimit                                      
          [set pcolor [color] of authority jurisdiction
           set polluted 1
           ]
          [set pcolor [color + 2] of authority jurisdiction
           set polluted 0
           ] 
        ]
       
      ifelse cooperate?
      [stop]
      [set meanPollutionInArea ((sum [pollutionLevel] of patches with [ jurisdiction = [who] of myself]) / numberOfMyPatches) 
       set totalPollution ( sum [pollutionLevel] of patches)
       ]
    ]
end

to complainForPollution/Unemployment
  
  ask households
   [set pollutionNearMe ((sum [pollutionLevel] of neighbors + [pollutionLevel] of patch-here) / (count neighbors + 1) )   ;complain for pollution
    ifelse pollutionNearMe >= pollutionLimit                                                                              ;
     [set dummy1 1 ]                                                                                                      ;
     [set dummy1 0 ]                                                                                                      ;    set complaintForPollution (concern * dummy1)                                                                          ;
    ifelse employed = 0                                                                                                   ;complain for unemployment
     [set complaintForUnemployment 1
      ifelse complaintForPollution != 0
       [ifelse color != 104
         [set color 104]
         [set color 14]
        ] 
       [set color 104]
      ]
     [set complaintForUnemployment 0
      ifelse complaintForPollution != 0
       [set color 14]
       [set color [color + 3] of authority [jurisdiction] of patch-here]
      ]
    ]
    
end

to evaluateRelocation   ; taxation PollutionDisposalCost unemployment

  ask firms
   [if [taxationPatch] of patch-here != min [taxationPatch] of patches 
       or [unemploymentRate-t0] of authority jurisdictionTurtle != max [unemploymentRate-t0] of authorities 
       or [pollutionDisposalCost] of authority jurisdictionTurtle != min [pollutionDisposalCost] of authorities
     [set meditation (meditation + 1)                                                                   ; the underlying assumption is that if the conditions (now just taxationLevel)  
      if meditation >= 36 and dummygrowth = 1 and assets-t1 > random 1000000                            ; don't change within 3 years, a firm should undertake relocation by paying a 
       [relocate                                                                                        ; relocation cost (here it is expected, but will be assigned during the relocate-procedure)
        set meditation 0
        set pollutionProduced 0                                                                         ; pollutionProduced counts the pollution produced in the actual jurisdiction,
        ]                                                                                               ; so that, when a firm relocates, the counter restarts form 0.
      ]
    ]
       
end

to relocate
  
  ifelse any? patches with [ taxationPatch = min [taxationPatch] of patches and jurisdiction != [jurisdictionTurtle] of myself] 
    [move-to one-of patches with [ taxationPatch = min [taxationPatch] of patches and jurisdiction != [jurisdictionTurtle] of myself]
     ]
    [ifelse jurisdictionTurtle != [who] of authorities with [unemploymentRate-t0 = max [unemploymentRate-t0] of authorities]
      [move-to one-of patches with [jurisdiction = [who] of one-of authorities with [unemploymentRate-t0 = max [unemploymentRate-t0] of authorities]]
      ]
      [move-to one-of patches with [jurisdiction = [who] of one-of authorities with [pollutionDisposalCost = min [pollutionDisposalCost] of authorities] and jurisdiction != [jurisdictionTurtle] of myself]
      ]
    ] 
  set L (L - count households with [employed = [who] of myself])
  ask households with [ employed = [who] of myself]
      [set employed 0
       ask link who [who] of myself 
          [die]  
       ]
   set jurisdictionTurtle [jurisdiction] of patch-here
   
end
  
to add-or-subtract-agents                     ; possible extention, not in use
  
  set numberOfFirms random 1 
  create-productionsystem
  set numberOfHouseholds random 1
  create-cities
  
  ask n-of random 1 firms
  [goBankrupt]
  ask n-of random 1 households
  [ask firm who
    [set L (L - 1)]
   if employed != 0
    [ask links with [end1 = self]
      [die]
     ]
   die
   ]

end


;;;;;;;;;;;;;;;;AUTHORITY'S DECIOSION-BOARD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


to govern
  ask authorities
  [check-unemploymentRate_and_growthExpectiation
   update-taxation
  ]
  
end



to check-unemploymentRate_and_growthExpectiation
  set unemploymentRate-t1 ((1 + count households with [jurisdictionTurtle = [who] of myself and employed = 0])/ (1 + numberOfMyHouseholds))
    ifelse unemploymentRate-t1 > unemploymentRate-t0
    [set dummy-unemployment 1]
    [set dummy-unemployment 0]
  set unemploymentRate-t0 unemploymentRate-t1
  set growthexpectation-t1 ((1 + count firms with [jurisdictionTurtle = [who] of myself and dummygrowth != 0])/ (1 + count firms with [jurisdictionTurtle = [who] of myself]))
  ifelse growthexpectation-t1 < growthexpectation-t0
    [set dummy-negativegrowthexp 1]
    [set dummy-negativegrowthexp 0]
  set growthexpectation-t0 growthexpectation-t1

end

to update-taxation
  
  ifelse dummy-negativegrowthexp != 0 and dummy-unemployment != 0
  [set g (- 1)]
  [set g 0]
  ifelse meanPollutionInArea < pollutionLimit
   [if meanPollutionInArea < 0 
      [set meanPollutionInArea 0]  
    set taxation (((meanPollutionInArea / pollutionLimit)^(5 ^ (unemploymentRate-t0))) + (g * 0.01))
    if taxation < 0
       [set taxation 0]
    ask patches with [jurisdiction = [who] of myself]
      [set taxationPatch [taxation] of myself]
    ]
    [reclaimLand
    ]
   
end

to reclaimLand

 let reclamationCost ((999999999999 ^ 25 ) * meanPollutionInArea * count patches with [jurisdiction = [who] of myself])  
  set taxesCollected (taxesCollected - reclamationCost)
  ifelse taxesCollected > 0
    [ ask patches with [jurisdiction = [who] of myself and polluted = 1]
     [set pollutionLevel 0
      set pcolor [color + 2] of myself
      set polluted 0
      ]
     ]
    [let firmsHere count firms with [jurisdictionTurtle = [who] of myself]
     ifelse firmsHere != 0
       [ask firms with [jurisdictionTurtle = [who] of myself]
         [set totalCost (totalCost + ([taxesCollected] of myself / firmshere))
          ]
        ask patches with [jurisdiction = [who] of myself and polluted = 1]
         [set pollutionLevel 0
          set pcolor [color + 2] of myself
          set polluted 0
          ]
        ]
       [set color 14
        set authority-failure (authority-failure + 1)
        ]
     ]
     
end


to cooperate
  
  if cooperate?
   [if m = 0 
     [create-basin-authorities 1
      [set shape "flag"
       setxy random-xcor random-ycor
       ]
      set m 1
     ]
    ask authorities with [difference > 0]
     [set compensate ( compensate + difference)
      ]
    set z count authorities with [difference <= 0]
    if z != 0
    [
     set pollutiontoDischarge (compensate / z) 
     ask authorities with [difference <= 0]
           [while [ pollutiontoDischarge != 0 and count patches with [jurisdiction = [who] of myself and pollutionLevel > 0] != 0]
             [ask one-of patches with [jurisdiction = [who] of myself and pollutionLevel > 0]
              [set pollutiontoDischarge (pollutiontoDischarge - pollutionLevel)
               set pollutionLevel 0
               ]
              ]
             if z != 1
             [set pollutiontoDischarge ( pollutiontoDischarge  + (compensate / (z - 1)))
              ]
            
            ]
     ]
    ]
    ifelse cooperate?
     [ask authorities
      [set meanPollutionInArea ((sum [pollutionLevel] of patches with [ jurisdiction = [who] of myself]) / numberOfMyPatches) 
       set totalPollution ( sum [pollutionLevel] of patches)
       ]
      ]
     [stop]
  
end