Simple_Demographic_and_Fiscal_Dynamics
Do you have questions or comments about this model? Ask them here! (You'll first need to log in.)
WHAT IS IT?
Demographic and Fiscal Dynamics
An agent-based model built in NetLogo for exploring population structure, fiscal policy, and environmental hazards.
Demographic and Fiscal Dynamics is an agent-based simulation that models the evolution of a human population over time, incorporating key demographic processes, economic behaviors, and external risks. The model represents individual people as agents with properties such as age, generation, income, tax contribution, and family relationships. These agents live in a spatial environment and interact based on rules inspired by real-world demographic and fiscal systems.
HOW IT WORKS
This simulation represents a synthetic society’s demographic and fiscal behavior, including:
Births, deaths, aging, marriages, and income generation
Government revenue from taxes
Spending on pensions and child allowances
Effects of periodic hazard zones (e.g., disasters)
HOW TO USE IT
The interface allows users to control demographic and fiscal parameters, toggle specific mechanisms, and monitor key population and financial indicators.
SETUP AND RUNNING
To begin, click the Setup button to initialize the simulation environment with the specified starting population. Individuals are placed randomly on the grid and color-coded by age group:
blue for children (0–12 years),
green for adults (13–59), and
orange for seniors (60+).
Then, click Go to run the simulation. Each tick represents 1 month. As time advances:
People age naturally and may change category (e.g., child to adult, adult to senior).
Adults can form marriages within their generation.
Fertile married adults can produce children based on a birth probability.
People may die due to age-based death probabilities or environmental hazards.
Government finances are updated monthly based on tax collected and allowances paid.
INTERFACE ELEMENTS
INITIAL POPULATION
Child0to12Years: Number of children (age < 13) at setup. Adult13to59Years: Number of adults (13–59) at setup. Senior60plus_Years: Number of seniors (60+) at setup.
BIRTH PROBABILITY (MONTHLY)
birth-probability: Monthly probability (0–1) that a married, fertile pair produces a child.
DEATH PROBABILITY (MONTHLY)
child-death-probability: Monthly probability a child dies naturally. adult-death-probability: Monthly probability an adult dies naturally. senior-death-probability: Monthly probability a senior dies naturally.
FERTILITY AGE RANGE
fertility-minimum-age / fertility-maximum-age: Adults between these ages are eligible to have children if married.
MARRIAGE AGE RANGE
marriage-minimum-age / marriage-maximum-age: Adults within this range can get married to others from the same generation.
PUBLIC FISCAL POLICY
child-allowance: Monthly government payment per child. tax-percentage-income-less-than-4000: Tax percentage for adults earning up to 4000 units/month. tax-percentage-income-higher-than-4000: Tax percentage for high-income adults (8000+ units/month). pension-percentage: Monthly pension as a % of adult salary after becoming a senior.
SWITCHES
show-id:
Toggles display of a person’s ID.
When the show-id switch is turned on, each individual is labeled with their unique ID and generation in the format: ID | Generation — for example, 2 | 3 refers to the person with ID 2 in the 3rd generation, and 12 | 1 refers to ID 12 in the 1st generation.
If two individuals from the same generation get married, their labels update to show their partnership: For example, if 21 | 2 marries 24 | 2, their labels will become:
21 → 24 | 2
24 → 21 | 2
This visually indicates a mutual partnership within the same generation.
If one partner dies, the surviving individual's label automatically reverts to the original format, e.g., 21 | 2, and their partner-id is reset.
hazard-death:
When ON, introduces periodic environmental hazards that can kill people within randomly placed circular zones with specified random radius.
The hazard-death switch controls whether people are affected by periodic environmental hazard zones.
Every 10 years (i.e., every 120 ticks), a hazard zone is randomly created on the map with:
A center at a random location
A radius between 5 and 10 units
A 12-month delay before it becomes lethal
If hazard-death is ON, then at the end of the 12 months, all individuals within the hazard radius will die, simulating the impact of natural or environmental disasters.
The map visually shows this zone as a smooth gradient:
Red at the center
White at the edge
The zone fades and resets after its impact.
A variable hazard-deaths-this-tick keeps track of how many individuals were lost in each hazard event, and is plotted separately for analysis.
If hazard-death is OFF, the hazard zone appears visually but has no impact on the population.
PLOTS AND MONITORS
Population Over Time: Line graph showing the number of children, adults, and seniors over time.
Births and Deaths per Month: Shows monthly birth and death counts.
Government Fiscal Flow: Visualizes monthly government spending on children and pensions versus tax income.
Fiscal Surplus: Displays net government balance (tax revenue – allowances – pensions).
Hazard Deaths: Tracks the number of deaths caused by hazard zones.
Income Statistics: Categorizes adults by salary group: No income, Mid income (up to 4000), High income (8000+)
OTHER BEHAVIORS
Individuals earn a salary and begin paying tax when they become adults. Salaries are randomly assigned based on probabilities to represent a low-, mid-, and high-income distribution.
Upon becoming seniors, adults stop earning salaries and start receiving pensions.
Every 10 years (120 ticks), a hazard zone appears and kills individuals inside a circular area after 12 months (if hazard-death is ON).
Individuals who die are removed from the world and from economic calculations.
The model recalculates all fiscal values and demographic statistics each tick.
This model allows experimentation with various policy scenarios (e.g., increasing pensions or changing tax rates), population dynamics, and external shocks (hazards).
This is perfectly designed to study how age structure and fiscal policies co-evolve over time.
THINGS TO NOTICE
Population Shifts Over Time
Watch how the proportions of children, adults, and seniors change as the simulation progresses. Do you notice population aging? When do certain age groups dominate?
Birth and Death Fluctuations
Observe how birth and death counts rise or fall depending on population composition, fertility age ranges, death probabilities, and hazard effects. Are births keeping up with deaths?
Government Fiscal Health
Track the net balance in the Fiscal Surplus plot. When does the government run a surplus vs. deficit? How do child allowance, pensions, and taxes affect this balance?
Income Stratification
Pay attention to how adult income groups (no income, mid-income, high-income) evolve over time. Are there persistent inequalities? Does one group dominate?
Pension Load and Retirement
As adults transition into seniors, pension obligations increase. Is the tax revenue enough to support this growing cost?
Impact of Hazard Events
If hazard-death is enabled, watch how periodic disasters cause sudden mortality spikes. What age groups are most affected? Do they destabilize the population structure or finances?
Marriage Patterns
Only adults of the same generation can marry. How does this influence the number of births? Do large generations produce more offspring?
Lagged Effects
Many effects (e.g., policy changes, birth rate shifts) don’t manifest immediately. Observe how policy or demographic changes cause ripple effects months or years later.
Population Collapse or Growth
Under certain settings, the population may shrink to extinction or explode exponentially. What combinations of fertility, death, and fiscal policy lead to sustainability?
Emergent Behavior
Watch for long-term trends or tipping points (e.g., sudden fiscal collapse, aging crisis, or baby booms) that emerge from simple rules and parameters.
THINGS TO TRY
Change Hazard Radius
Increase or decrease the hazard radius to observe its impact on population stability and density.
Reduce Fertility and Marriage Range
Narrow the age ranges and lower birth probabilities to see how reproduction slows down over time.
Zero-Population Scenarios
Use extreme settings (e.g., high senior death, zero birth rate) to observe total population collapse with high net fiscal surplus.
High Birth Probability
Increase birth probability and widen marriage range to see overcrowding and fiscal stress due to rising child allowance.
Balance Demography and Economy
Tune all parameters to achieve a sustainable balance between population size and government surplus.
ASSUMPTIONS
No Married Couples at Initialization
At the start of the simulation, no agents are married. All partnerships form dynamically during the simulation based on age eligibility and generation constraints.
No Divorce or Re-Marriage
Once two agents are married, the partnership remains for life unless one dies. Divorce, separation, or re-marriage dynamics are not modeled.
No Gender Consideration
All agents are treated as gender-neutral. The model does not account for gender roles, imbalances, or reproduction based on sex.
No Choice to Remain Single
If an individual is within the marriageable age and unpartnered, they will attempt to pair. Voluntary celibacy or rejection of marriage is not represented.
No Inheritance
Children do not inherit assets, income, or pension from their parents. Wealth is not passed between generations.
Fixed Child Allowance
All children receive the same amount of allowance monthly, regardless of household status or total number of children.
Static Salary Assignment
Adults receive a one-time assigned salary when they transition to adulthood. Their income does not change with age, performance, or inflation.
Pension Based on Last Adult Salary
When agents transition to seniors, their pension is calculated as a percentage of their final salary and remains fixed thereafter.
Simplified Tax System
Tax is based only on monthly income brackets with no deductions, rebates, or progressive scales. It only applies to salaried adults.
Government Fiscal Scope is Limited
Government income is solely from income tax; expenditures are limited to child allowances and pensions. No costs for healthcare, education, infrastructure, or public employment are considered.
No Price or Market Dynamics
The model does not simulate consumption, inflation, or supply-demand interactions. Goods and services are assumed to exist and be uniformly accessible.
Balanced Public Accounts Beyond Modeled Scope
Other government revenues (like goods & services taxes, import duties) and expenditures (e.g., employee wages, development spending) are assumed to balance out and are not explicitly modeled.
EXTENDING THE MODEL
This model provides a flexible foundation for exploring both demographic and fiscal policies. Several extensions can reduce simplifying assumptions and broaden its applicability:
--> Incorporate Gender and Reproductive Roles --> Model Divorce and Re-Marriage --> Add Inheritance and Wealth Transfer --> Introduce Employment Transitions --> Include Living Costs and Spending --> Expand Taxation Schemes --> Environmental and Energy Linkage --> Urbanization and Land Use --> Education and Skill Development --> Policy Experiments
This model can serve as a backbone for multi-sectoral policy simulation, linking population with economics, environment, infrastructure, and energy.
USE OF AI
ChatGPT was used to support writing, some logic development, and error correction during model design. However, due to limitations, it does not always provide syntax specific to NetLogo e.g., exact ifelse structure).
NETLOGO FEATURES
One feature I found particularly helpful during development was the Globals Monitor (accessible via Tools > Globals Monitor). It allowed me to track key global variables like numbers, tax revenue, pension, child allowance, and net balance in real-time. This made debugging and understanding the dynamics of fiscal flow much easier during the coding process.
RELATED MODELS
Simple Birth Rates, Urban Suite - Pollution, Simple Economy, Wealth Distribution
HOW TO CITE
If you mention this model or the NetLogo software in a publication, I ask that you include the citations below.
Please cite the NetLogo software as: Wilensky, U. (1999). NetLogo. http://ccl.northwestern.edu/netlogo/. Center for Connected Learning and Computer-Based Modeling, Northwestern University, Evanston, IL.
COPYRIGHT AND LICENSE
Developed by Dharti DODIYA as part of the ABM course project at DSTI using NetLogo.
Professor Name: Dr Georgiy Bobashev
This model is free to use and share for educational and academic purposes.
Comments and Questions
breed [people person] people-own [ age partner-id generation gen-id salary tax pension child-allowance ] globals [ num-children num-adults num-seniors num-births-this-month num-deaths-this-month-based-on-probability generation-id-map total-child-allowance total-tax-revenue total-pension net-balance hazard-center-x hazard-center-y hazard-radius hazard-start-tick hazard-deaths-this-month num-deaths-this-month num-no-income-adults num-mid-income-adults num-high-income-adults ] to setup clear-all set-default-shape people "person" set generation-id-map [[1 1]] ; start generation 1 at ID 1 ; Children create-people Child_0_to_12_Years [ set age random-float 13 set color blue setxy random-xcor random-ycor set partner-id nobody set generation 1 set gen-id update-generation-id generation set child-allowance child-allowance-per-child set salary 0 set tax 0 set pension 0 set num-children Child_0_to_12_Years ] ; Adults create-people Adult_13_to_59_Years [ set age 13 + random-float 45 ; age gap is provided for age conversion set color green setxy random-xcor random-ycor set partner-id nobody set generation 1 set gen-id update-generation-id generation ; No child allowance for adults set child-allowance 0 ; Assign salary & tax let income-type random-float 1 if income-type < 0.01 [ set salary 0 ] if income-type >= 0.01 and income-type < 0.96 [ set salary random 2501 + 1500 ] if income-type >= 0.96 [ set salary random 7001 + 8000 ] if salary = 0 [ set tax 0 ] if salary > 0 and salary <= 4000 [ set tax salary * tax-percentage-income-less-than-4000 / 100 ] if salary > 4000 [ set tax salary * tax-percentage-income-higher-than-4000 / 100 ] set pension 0 set num-adults Adult_13_to_59_Years ] ; Seniors create-people Senior_60_plus_Years [ set age 60 + random-float 39 ; age gap is provided for age conversion set color orange setxy random-xcor random-ycor set partner-id nobody set generation 1 set gen-id update-generation-id generation set child-allowance 0 set salary 0 set tax 0 set pension random 1001 + 500 ; sample average pension set num-seniors Senior_60_plus_Years ] ; Labels (conditionally display) ifelse show-id [ ask people [ ifelse partner-id != nobody and member? partner-id [who] of people [ let partner turtle partner-id ifelse [partner-id] of partner = who [ set label (word gen-id " → " [gen-id] of partner " | " generation) ] [ set label (word gen-id " | " generation) set partner-id nobody ] ] [ set label (word gen-id " | " generation) ] ] ] [ ask people [ set label "" ] ] set num-births-this-month 0 set num-deaths-this-month 0 set hazard-deaths-this-month 0 set num-deaths-this-month-based-on-probability 0 set num-no-income-adults count people with [age >= 13 and age < 60 and salary = 0] set num-mid-income-adults count people with [age >= 13 and age < 60 and salary > 0 and salary <= 4000] set num-high-income-adults count people with [age >= 13 and age < 60 and salary >= 8000] ; Update government totals ; Fiscal flow and surplus are calculated per month (not cumulative across ticks) set total-child-allowance sum [child-allowance] of people set total-tax-revenue sum [tax] of people set total-pension sum [pension] of people set net-balance total-tax-revenue - total-pension - total-child-allowance reset-ticks end to go if not any? people [ stop ] ; Labels (conditionally display) ifelse show-id [ ask people [ ifelse partner-id != nobody and member? partner-id [who] of people [ let partner turtle partner-id ifelse [partner-id] of partner = who [ set label (word gen-id " → " [gen-id] of partner " | " generation) ] [ set label (word gen-id " | " generation) set partner-id nobody ] ] [ set label (word gen-id " | " generation) ] ] ] [ ask people [ set label "" ] ] ; Age update and lifecycle transitions ask people [ set age age + 1 / 12 ; Update color by age ifelse age < 13 [ set color blue ] [ ifelse age < 60 [ set color green ] [ set color orange ] ] ; Transition from child to adult if age >= 13 and age < 13 + 1 / 12 [ set child-allowance 0 let income-type random-float 1 if income-type < 0.01 [ set salary 0 ] if income-type >= 0.01 and income-type < 0.96 [ set salary random 2501 + 1500 ] if income-type >= 0.96 [ set salary random 7001 + 8000 ] if salary = 0 [ set tax 0 ] if salary > 0 and salary <= 4000 [ set tax salary * tax-percentage-income-less-than-4000 / 100 ] if salary > 4000 [ set tax salary * tax-percentage-income-higher-than-4000 / 100 ] ] ; Transition from adult to senior if age >= 60 and age < 60 + 1 / 12 [ set pension salary * pension-percentage / 100 set salary 0 set tax 0 ] ] ask people with [partner-id != nobody] [ if not member? partner-id [who] of people [ set partner-id nobody ] ] ; Pair up unpartnered fertile adults of the same generation let unpartnered people with [ age >= marriage-minimum-age and age <= marriage-maximum-age and partner-id = nobody ] let shuffled shuffle sort unpartnered let pair-count floor (length shuffled / 2) repeat pair-count [ let a1 item 0 shuffled let a2 item 1 shuffled ; Remove them from pool now to avoid reuse set shuffled remove a1 shuffled set shuffled remove a2 shuffled ; Only allow same-generation pairing if ([generation] of a1 = [generation] of a2) and ([partner-id] of a1 = nobody) and ([partner-id] of a2 = nobody) [ ask a1 [ set partner-id [who] of a2 ] ask a2 [ set partner-id [who] of a1 ] ] ] ; === Births === set num-births-this-month 0 let birth-count 0 ask people with [partner-id != nobody and age >= fertility-minimum-age and age <= fertility-maximum-age] [ let mate turtle partner-id if mate != nobody and [partner-id] of mate = who [ if [age] of mate >= fertility-minimum-age and [age] of mate <= fertility-maximum-age [ if random-float 1 < birth-probability [ set birth-count birth-count + 1 ] ] ] ] create-people birth-count [ set age 0 set color blue setxy random-xcor random-ycor set partner-id nobody ; Generation and ID logic let parent one-of people with [ partner-id != nobody and age >= fertility-minimum-age and age <= fertility-maximum-age ] ifelse parent != nobody [ set generation [generation] of parent + 1 ][ set generation 1 ] set gen-id update-generation-id generation set child-allowance child-allowance-per-child ] set num-births-this-month birth-count ; === Deaths === set num-deaths-this-month-based-on-probability 0 ask people [ if (age < 13 and random-float 1 < child-death-probability) or (age >= 13 and age < 60 and random-float 1 < adult-death-probability) or (age >= 60 and random-float 1 < senior-death-probability) or (age >= 100) [ set num-deaths-this-month-based-on-probability num-deaths-this-month-based-on-probability + 1 die ] ] if ticks mod 120 = 0 [ ; Create a new hazard zone set hazard-center-x random-xcor set hazard-center-y random-ycor set hazard-radius 5 + random 5 ; radius between 5 and 10 set hazard-start-tick ticks ] set hazard-deaths-this-month 0 ; at start of go if hazard-death and ticks = hazard-start-tick + 12 [ let dying-people people with [distancexy hazard-center-x hazard-center-y <= hazard-radius] set hazard-deaths-this-month count dying-people ask dying-people [ die ] ] ask patches [ let dist distancexy hazard-center-x hazard-center-y if abs (ticks - hazard-start-tick) < 12 and dist <= hazard-radius [ ; Create smooth gradient: red at center to white at edge let norm-dist dist / hazard-radius ; 0 at center, 1 at edge set pcolor scale-color red (1 - norm-dist) 0 1 ] if ticks - hazard-start-tick >= 12 [ set pcolor black ; reset after hazard ends ] ] set num-deaths-this-month hazard-deaths-this-month + num-deaths-this-month-based-on-probability ; Count by group set num-children count people with [age < 13] set num-adults count people with [age >= 13 and age < 60] set num-seniors count people with [age >= 60] set num-no-income-adults count people with [age >= 13 and age < 60 and salary = 0] set num-mid-income-adults count people with [age >= 13 and age < 60 and salary > 0 and salary <= 4000] set num-high-income-adults count people with [age >= 13 and age < 60 and salary >= 8000] ; Update government totals ; Fiscal flow and surplus are calculated per month (not cumulative across ticks) set total-child-allowance sum [child-allowance] of people set total-tax-revenue sum [tax] of people set total-pension sum [pension] of people set net-balance total-tax-revenue - total-pension - total-child-allowance tick end to-report update-generation-id [gen] let next-id 1 let found? false let new-map [] ; Scan existing generation-id-map foreach generation-id-map [ gen-pair -> ifelse item 0 gen-pair = gen [ set next-id item 1 gen-pair set new-map lput (list gen (next-id + 1)) new-map set found? true ] [ set new-map lput gen-pair new-map ] ] ; If generation was new, initialize it if not found? [ set new-map lput (list gen 2) new-map set next-id 1 ] set generation-id-map new-map report next-id end
There is only one version of this model, created 24 days ago by Dharti DODIYA.
Attached files
File | Type | Description | Last updated | |
---|---|---|---|---|
Simple_Demographic_and_Fiscal_Dynamics.png | preview | Preview for 'Simple_Demographic_and_Fiscal_Dynamics' | 24 days ago, by Dharti DODIYA | Download |
This model does not have any ancestors.
This model does not have any descendants.