Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ;;;;; Units Used
- ;; Land - km2
- ;; Water - m3
- ;; Weight - kg
- globals
- [
- population
- available-area-increase
- available-area-encourage
- actual-rice-consumption
- last-rice-production
- price-per-kg-dup
- tempPrice
- used-land-increase-production
- used-land-encourage-production
- current-water-available
- riceInStorage
- used-area
- MAX-VALUE
- maintain-counter
- increase-counter
- encourage-counter
- import-counter
- base-transportation-price
- base-importation-preparation-price
- maximum-storage-ever
- production-to-waste
- ]
- to setup
- clear-all
- if initial-population <= 0
- [
- show "Population must be equal or greater than zero."
- stop
- ]
- if initial-available-land-increase < 0
- [
- show "Available area to encourage increase of production must be equal or greater than zero."
- stop
- ]
- if initial-available-land-encourage < 0
- [
- show "Available area to encourage the production must be equal or greater than zero."
- stop
- ]
- if initial-used-land <= 0
- [
- show "Used area must be equal or greater than zero."
- stop
- ]
- if land-preparation-cost <= 0
- [
- show "The average cost of buying and adapting the land must be greater than zero."
- stop
- ]
- if water-needed-per-kg < 0
- [
- show "The water needed per kg can not be negative."
- stop
- ]
- if seed-price-per-kg < 0
- [
- show "The seed price can not be negative."
- stop
- ]
- if labour-price-per-kg < 0
- [
- show "The average labour price per kilogram can not be negative."
- stop
- ]
- if fertilizers-price-per-kg < 0
- [
- show "The average fertilizers price per kilogram can not be negative."
- stop
- ]
- if price-per-kg < 0
- [
- show "The rice price per kilogram must be equal or greater than zero."
- stop
- ]
- if dry-probability < 0
- [
- show "The probability of being a dry year can not be negative."
- stop
- ]
- if initial-rice-in-storage < 0
- [
- show "The initial rice stored can not be negative."
- stop
- ]
- set price-per-kg-dup price-per-kg
- set population initial-population
- set available-area-increase initial-available-land-increase
- set available-area-encourage initial-available-land-encourage
- set used-area initial-used-land
- set used-land-increase-production []
- set used-land-encourage-production []
- set actual-rice-consumption precision (actual-rice-consumption * population * 1000) 2
- set tempPrice 0
- set riceInStorage 0
- set current-water-available 0
- set last-rice-production 0
- set MAX-VALUE 8999999999999999
- set riceInStorage initial-rice-in-storage
- set maximum-storage-ever riceInStorage
- set base-transportation-price 0.2
- set base-importation-preparation-price 0.15
- set production-to-waste 0.8
- resetcounters
- reset-ticks
- draw
- end
- to draw
- ask patches [
- set pcolor 78
- ]
- ;; Paint the population aspect
- ask patches with [pxcor >= -10 and pxcor <= 10 and pycor >= -3 and pycor <= 2] [
- ifelse getRiceConsumption > riceInStorage
- [
- set pcolor 15 ;; red
- ]
- [
- let safetyRatio 1.3
- ifelse (getRiceConsumption * safetyRatio) > riceInStorage
- [
- set pcolor 45 ;; yellow
- ]
- [
- set pcolor 94 ;; blue
- ]
- ]
- ]
- ;; Set label for population aspect
- ask patches with [pxcor = 2 and pycor = 2] [
- set plabel "Population/Demand"
- set plabel-color 0
- ]
- ;; Paint the storage aspect
- ask patches with [pxcor >= -19 and pxcor <= -12 and pycor >= -9 and pycor <= 9] [
- ifelse riceInStorage = 0
- [
- set pcolor 15 ;; red
- ]
- [
- ifelse riceInStorage < 0.2 * maximum-storage-ever
- [
- set pcolor 45
- ]
- [
- set pcolor 35
- ]
- ]
- ]
- ;; Set label for storage aspect
- ask patches with [pxcor = -15 and pycor = 9] [
- set plabel "Storage"
- set plabel-color 0
- ]
- ;; Paint the bought area aspect
- ask patches with [pxcor >= 12 and pxcor <= 19 and pycor >= -9 and pycor <= 9] [
- set pcolor 35
- ]
- ;; Set label for bought area aspect
- ask patches with [pxcor = 16 and pycor = 9] [
- set plabel "Prodution"
- set plabel-color 0
- ]
- end
- to resetCounters
- set maintain-counter 0
- set increase-counter 0
- set encourage-counter 0
- set import-counter 0
- end
- to go
- if population <= 0
- [
- set population 0
- stop
- ]
- update
- if ticks mod 4 = 0
- [
- crop
- ]
- if ticks mod 12 = 0
- [
- decide
- ]
- draw ;; draw the UI components again so that the colors can change accordingly to the system state
- consume
- tick
- end
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Update Handlers ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;; Procedure called every tick (month) that updates the variables of the system
- ;;
- to update
- updateRemoveLands
- updateUsedLand
- updatePopulation
- updateWater
- updateRicePricePerKG
- end
- ;; Updates used land
- to updateUsedLand
- ;; Set used-area for the output information
- set used-area initial-used-land + sumLands used-land-increase-production + sumLands used-land-encourage-production
- end
- ;; Remove the lands once the loan (5 years) has finished
- to updateRemoveLands
- set used-land-increase-production removeOnLimitFirstElement used-land-increase-production
- set used-land-encourage-production removeOnLimitFirstElement used-land-encourage-production
- set available-area-increase (initial-available-land-increase - sumLands used-land-increase-production)
- set available-area-encourage (initial-available-land-encourage - sumLands used-land-encourage-production)
- end
- ;; Procedure that updates the population number
- to updatePopulation
- set population population + int (population * random-normal ((avg-population-growth / 100) / 12) ((deviation-population-growth / 100 )) / 12)
- end
- ;; Updates the rice price based on the month
- to updateRicePricePerKG
- let amplitude (price-per-kg-dup / 3)
- let randomFactor 1 / 6
- set price-per-kg-dup precision (price-per-kg + (amplitude * (cos((180 / pi) * ((ticks mod 12) / 2)))) + random-normal 0 (amplitude * randomFactor)) 2
- end
- ;; Updates the water value according to the month
- to updateWater
- let water-needed used-area * rice-production-per-km2 * water-needed-per-kg
- let amplitude (water-needed / 2)
- let randomFactor 1 / 2
- set current-water-available (water-needed + (amplitude * (cos((180 / pi) * ((ticks mod 12) / 2)))) + random-normal 0 (amplitude * randomFactor))
- end
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Action Handlers ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;; Import procedure
- ;; The quantity imported is stored in the respective "warehouses"
- to import [quantity]
- set riceInStorage riceInStorage + quantity
- if riceInStorage > maximum-storage-ever
- [
- set maximum-storage-ever riceInStorage
- ]
- set import-counter import-counter + 1
- end
- ;; Encourage-Production procedure
- to encourage-production [quantity]
- let neededArea precision ((quantity / rice-production-per-km2)) 2
- ifelse available-area-encourage > neededArea
- [
- set available-area-encourage available-area-encourage - neededArea
- ]
- [
- set neededArea available-area-encourage
- set available-area-encourage 0
- ]
- set used-land-encourage-production addElementToTheList (list neededArea (ticks + 5 * 12)) used-land-encourage-production
- set encourage-counter encourage-counter + 1
- end
- ;; Increase-Production procedure
- to increase-production [quantity]
- let neededArea precision ((quantity / rice-production-per-km2)) 2
- ifelse available-area-increase > neededArea
- [
- set available-area-increase available-area-increase - neededArea
- ]
- [
- set neededArea available-area-increase
- set available-area-increase 0
- ]
- set used-land-increase-production addElementToTheList (list neededArea (ticks + 5 * 12)) used-land-increase-production
- set increase-counter increase-counter + 1
- end
- ;; Procedure that increases the number of rice, representing a crop
- ;; A season is estimated with a duration of four months
- to crop
- let currentCrop precision ((min list (current-water-available / water-needed-per-kg) (used-area * rice-production-per-km2)) * production-to-waste) 2
- set last-rice-production currentCrop
- set riceInStorage riceInStorage + currentCrop
- if riceInStorage > maximum-storage-ever
- [
- set maximum-storage-ever riceInStorage
- ]
- end
- ;; Procedure that simulates the consumption of the population for a month
- to consume
- set actual-rice-consumption min list (precision (rice-consumption * population * 1000) 2) (riceInStorage)
- set riceInStorage precision (riceInStorage - actual-rice-consumption) 2
- end
- ;; Procedure that returns the rice demand
- to-report getRiceConsumption
- report precision (rice-consumption * population * 1000) 2
- end
- ;; Procedure representing the decision maker
- ;; It is used a MVE approach used in Operational Research
- to decide
- let normal-probability (1 - dry-probability)
- let dry-factor 0.7
- let normal-factor 1
- let water-state-normal current-water-available * normal-factor
- let water-state-dry current-water-available * dry-factor
- let average-water (water-state-normal * normal-probability + water-state-dry * dry-probability)
- let average-production getAvgProductionNextYear average-water
- let safetyRatio 1.2
- let quantity ((getAvgConsumptionNextYear * safetyRatio) - riceInStorage - average-production)
- if quantity < 0
- [
- set quantity 0
- ]
- let neededArea precision (quantity / rice-production-per-km2) 2
- let real-water-value (estimateWaterValue (neededArea + used-area))
- let utility-import-normal (utilityImport quantity)
- let utility-import-dry (utilityImport quantity)
- let utility-doNothing-normal (utilityDoNothing average-production)
- let utility-doNothing-dry (utilityDoNothing average-production)
- let utility-encourageProdution-normal (utilityEncourageProdution neededArea (real-water-value * normal-factor))
- let utility-encourageProdution-dry (utilityEncourageProdution neededArea (real-water-value * dry-factor))
- let utility-increaseProduction-normal (utilityEncourageIncreaseProdution neededArea (real-water-value * normal-factor))
- let utility-increaseProduction-dry (utilityEncourageIncreaseProdution neededArea (real-water-value * dry-factor))
- let mveValueImport precision (dry-probability * utility-import-dry + normal-probability * utility-import-normal) 2
- let mveValueDoNothing precision (dry-probability * utility-doNothing-dry + normal-probability * utility-doNothing-normal) 2
- let mveValueEncourage precision (dry-probability * utility-encourageProdution-dry + normal-probability * utility-encourageProdution-normal) 2
- let mveValueIncrease precision (dry-probability * utility-increaseProduction-dry + normal-probability * utility-increaseProduction-normal) 2
- let minValue min (list mveValueImport mveValueDoNothing mveValueEncourage mveValueIncrease)
- ifelse minValue = mveValueImport [
- import quantity
- ]
- [
- ifelse minValue = mveValueEncourage [
- encourage-production quantity
- ]
- [
- ifelse minValue = mveValueIncrease [
- increase-production quantity
- ]
- [
- set maintain-counter maintain-counter + 1
- ]
- ]
- ]
- end
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Utility Procedures ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;; Utility function representing the decision of doing nothing
- to-report utilityDoNothing [avgProduction]
- let safetyRatio 1.2
- let ratio (riceInStorage + avgProduction) / (getAvgConsumptionNextYear * safetyRatio)
- let utility 0
- ifelse ratio < 1
- [
- set utility MAX-VALUE
- ]
- [
- set utility -1
- ]
- show word (utility) (" DoNothing")
- report utility
- end
- ;; Utility function representing the decision of importing a specific rice quantity
- to-report utilityImport [quantity]
- if quantity = 0
- [
- report MAX-VALUE
- ]
- let transportation-price base-transportation-price
- ifelse quantity > 5000
- [
- set transportation-price base-transportation-price * 0.75
- ]
- [
- if quantity > 2000
- [
- set transportation-price base-transportation-price * 0.8
- ]
- ]
- let utility precision (quantity * (price-per-kg-dup + transportation-price + base-importation-preparation-price)) 2
- show word (utility) (" Import")
- report utility
- end
- ;; Utility function representing the decision of encourage the production of the farmers that don't farm
- to-report utilityEncourageProdution [neededArea real-water-value]
- if neededArea = 0
- [
- report MAX-VALUE
- ]
- let water-needed (neededArea + used-area) * rice-production-per-km2 * water-needed-per-kg
- let utility 0
- let landFactor 0
- let waterFactor (water-needed / real-water-value)
- if waterFactor > 1
- [
- set waterFactor waterFactor ^ e
- ]
- show waterFactor
- ifelse available-area-encourage = 0
- [
- set utility MAX-VALUE
- ]
- [
- let difference available-area-increase - neededArea
- ifelse difference > 0
- [
- set landFactor 1
- ]
- [
- set landFactor (neededArea / available-area-encourage)
- ]
- let happinessFactor 0.1
- set utility precision ((land-preparation-cost * neededArea) + (seed-price-per-kg + labour-price-per-kg + fertilizers-price-per-kg) * (averageProductionIn5years neededArea water-needed) * happinessFactor * waterFactor * landFactor) 2
- ]
- show word (utility) (" Encourage")
- report utility
- end
- ;; Utility function representing the decision of encouraging the increase of production by the farmers that already have lands ready for producing
- to-report utilityEncourageIncreaseProdution [neededArea real-water-value]
- if neededArea = 0
- [
- report MAX-VALUE
- ]
- let water-needed (neededArea + used-area) * rice-production-per-km2 * water-needed-per-kg
- let utility 0
- let landFactor 0
- let waterFactor (water-needed / real-water-value)
- if waterFactor > 1
- [
- set waterFactor waterFactor ^ e
- ]
- ifelse available-area-increase = 0
- [
- set utility MAX-VALUE
- ]
- [
- let difference available-area-increase - neededArea
- ifelse difference > 0
- [
- set landFactor 1
- ]
- [
- set landFactor (neededArea / available-area-increase)
- ]
- let happinessFactor 0.15
- set utility precision (((seed-price-per-kg + labour-price-per-kg + fertilizers-price-per-kg) * (averageProductionIn5years neededArea water-needed)) * waterFactor * happinessFactor * landFactor) 2
- ]
- show word (utility) (" Increase")
- report utility
- end
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Bought Land Handler ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;; Sum all the lands
- to-report sumLands [listToSum]
- let sumLand 0
- foreach listToSum[
- n -> set sumLand (sumLand + first n)
- ]
- report sumLand
- end
- ;; Removes the first element if the tick is equal to the actual tick
- to-report removeOnLimitFirstElement [usedLand]
- if length usedLand != 0 [
- let element first usedLand
- let newList []
- if last element = ticks
- [
- set newList but-first usedLand
- report newList
- ]
- ]
- report usedLand
- end
- ;; Adds a element [km2 endTick] to the list of lands of the parameter "usedLand"
- to-report addElementToTheList [element usedLand]
- let newList lput element usedLand
- report newList
- end
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Estimate procedures ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;; Gets the average consumption of the population for the next year (12 months)
- to-report getAvgConsumptionNextYear
- let estimatedPopulation population + int (population * random-normal ((avg-population-growth / 100)) ((deviation-population-growth / 100 )))
- let avgPopulation (population + estimatedPopulation) / 2
- let consumption precision (12 * rice-consumption * avgPopulation * 1000) 2
- report consumption
- end
- ;; gets the average production for the next year (12 months)
- to-report getAvgProductionNextYear [water]
- report precision (3 * (min list (water / water-needed-per-kg) (used-area * rice-production-per-km2)) * production-to-waste) 2
- end
- ;; Estimated Average Production for 5 years of a terrain of defined dimension
- to-report averageProductionIn5years [dimension water]
- report precision (3 * 5 * (min list (water / water-needed-per-kg) (dimension * rice-production-per-km2)) * production-to-waste) 2
- end
- ;; Estimates the water needed for the land
- to-report estimateWaterValue [land-area]
- let water-needed land-area * rice-production-per-km2 * water-needed-per-kg
- let amplitude (water-needed / 2)
- let randomFactor 1 / 2
- let value precision ((water-needed + (amplitude * (cos((180 / pi) * ((ticks mod 12) / 2))))) + random-normal 0 (amplitude * randomFactor)) 2
- report value
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement