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.
powered by NetLogo
view/download model file: water_pollution_in_river_basin_model.nlogo
(a general understanding of what the model is trying to show or explain)
(what rules the agents use to create the overall behavior of the model)
(how to use the model, including a description of each of the items in the Interface tab)
(suggested things for the user to notice while running the model)
(suggested things for the user to try to do (move sliders, switches, etc.) with the model)
(suggested things to add or change in the Code tab to make the model more complicated, detailed, accurate, etc.)
(interesting or unusual features of NetLogo that the model uses, particularly in the Code tab; or where workarounds were needed for missing features)
(models in the NetLogo Models Library and elsewhere which are of related interest)
(a reference to the model’s URL on the web if it has one, as well as any other necessary credits, citations, and links)
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