/** * A component of a library for * GENESIS * Copyright (C) 2008 * Andy Turner, * University of Leeds. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ package uk.ac.leeds.ccg.andyt.projects.genesis.process; import java.io.File; import java.util.HashSet; import java.util.Iterator; import java.util.Random; import uk.ac.leeds.ccg.andyt.grids.core.Grid2DSquareCellDouble; import uk.ac.leeds.ccg.andyt.grids.core.Grid2DSquareCellDoubleFactory; import uk.ac.leeds.ccg.andyt.grids.exchange.ImageExporter; import uk.ac.leeds.ccg.andyt.projects.genesis.society.demography.Demographics; import uk.ac.leeds.ccg.andyt.projects.genesis.society.demography.Fertility; import uk.ac.leeds.ccg.andyt.projects.genesis.society.demography.Mapping; import uk.ac.leeds.ccg.andyt.projects.genesis.society.demography.Mortality; import uk.ac.leeds.ccg.andyt.projects.genesis.society.demography.Movement; import uk.ac.leeds.ccg.andyt.projects.genesis.society.environment.Environment; import uk.ac.leeds.ccg.andyt.projects.genesis.society.environment.Location; import uk.ac.leeds.ccg.andyt.projects.genesis.society.organisations.Household; import uk.ac.leeds.ccg.andyt.projects.genesis.society.persons.Female; import uk.ac.leeds.ccg.andyt.projects.genesis.society.persons.Male; import uk.ac.leeds.ccg.andyt.projects.genesis.society.persons.Person; import uk.ac.leeds.ccg.andyt.projects.genesis.society.environment.Time; import uk.ac.leeds.ccg.andyt.projects.genesis.utilities.ErrorHandler; /** * A class to generate a society. */ public class GenerateSociety_1 extends ErrorHandler { private int _RandomSeed; private Environment _Environment; /** * _Population[0] is a Female HashSet * _Population[1] is a Male HashSet */ private Object[] _Population; public ImageExporter _ImageExporter; public String _Type; public GenerateSociety_1() { } public static void main(String args[]) { GenerateSociety_1 _GenerateSociety_1 = new GenerateSociety_1(); _GenerateSociety_1.run(); } /** * Example run producing a map of locations at each day time step. */ public void run() { _RandomSeed = 0; Time _Time = new Time(20, 0); HashSet _Grid2DSquareCells = new HashSet(); boolean _HandleOutOfMemoryError = false; long _NRows = 100; long _NCols = 200; Grid2DSquareCellDoubleFactory _Grid2DSquareCellDoubleFactory = new Grid2DSquareCellDoubleFactory(_Grid2DSquareCells, _HandleOutOfMemoryError); Grid2DSquareCellDouble _World_Grid2DSquareCellDouble = (Grid2DSquareCellDouble) _Grid2DSquareCellDoubleFactory.create(_NRows, _NCols); long row; long col; for (row = 0; row < _NRows; row++) { for (col = 0; col < _NCols; col++) { _World_Grid2DSquareCellDouble.setCell(row, col, 0.0d, _HandleOutOfMemoryError); } } _Environment = new Environment( new Random(_RandomSeed), _Time, _Grid2DSquareCellDoubleFactory, _World_Grid2DSquareCellDouble, _HandleOutOfMemoryError); _Time = new Time(0, 0); _Initialise_Population( _Environment, _Time); _ImageExporter = new ImageExporter(); _Type = "PNG"; File _File = new File("C:/temp/_Density_Map_Population." + _Type); Mapping._Map_Population( _File, _Type, _ImageExporter, _Environment, _Population); Demographics _Demographics = new Demographics(); _Simulate(_Demographics, 300); } /** * Initialises Persons in a simple society. * There are a number of households each consisting of 100 Males and 100 * Females as yet unrelated. * These Persons are spatially located within the Environment at Random. */ public void _Initialise_Population( Environment _Environment, Time _Time) { _Population = new Object[2]; HashSet _Males = new HashSet(); HashSet _Females = new HashSet(); int _NumberOfHouseholds = 1; int _NumberOfMalesPerHousehold = 100; int _NumberOfFemalesPerHousehold = 100; int i; int _Household_int; Object _ID; Male _Male; Female _Female; //Person _Person; Time _Min_Time_Birth = new Time(0, 0, 0); Time _Max_Time_Birth = new Time(15, 0, 0); Time _Time_Birth; //Calendar _DateOfBirth_Calendar; for (_Household_int = 0; _Household_int < _NumberOfHouseholds; _Household_int++) { Location _Location; _Location = _Environment.getRandomLocation(); Household _Household = new Household(_Location); // Generate Females for (i = 0; i < _NumberOfFemalesPerHousehold; i++) { _Location = _Environment.getRandomLocation(); _ID = new Object(); _Time_Birth = Time.get_RandomTime( _Min_Time_Birth, _Max_Time_Birth, _Environment._Random); _Female = new Female( _Environment, _ID, _Time_Birth, _Household, _Location); _Females.add(_Female); } // Generate Males for (i = 0; i < _NumberOfMalesPerHousehold; i++) { _Location = _Environment.getRandomLocation(); _ID = new Object(); _Time_Birth = Time.get_RandomTime( _Min_Time_Birth, _Max_Time_Birth, _Environment._Random); _Male = new Male( _Environment, _ID, _Time_Birth, _Household, _Location); _Males.add(_Male); } } _Population[0] = _Females; _Population[1] = _Males; } /** * Dynamically simulates a population over time. * @param _Demographics * @param _Years The number of years over which the simulation occurs */ public void _Simulate( Demographics _Demographics, int _Years) { Mortality _Mortality = new Mortality(_Environment); int _TotalBirths = 0; int _TotalBirthsInYear = 0; int _TotalDeaths = 0; int _TotalDeathsInYear = 0; int _TotalPregnancies = 0; int _TotalPregnanciesInYear = 0; int _TotalMiscarriages = 0; int _TotalMiscarriagesInYear = 0; HashSet _PregnantFemales = new HashSet(); Grid2DSquareCellDouble _Population_Location_Composite_Map = (Grid2DSquareCellDouble) _Environment._Grid2DSquareCellDoubleFactory.create(_Environment._World_Grid2DSquareCellDouble); File _File; Fertility _Fertility = new Fertility(); for (int _Year = 0; _Year < _Years; _Year++) { _TotalBirthsInYear = 0; _TotalDeathsInYear = 0; _TotalPregnanciesInYear = 0; _TotalMiscarriagesInYear = 0; for (int _Day = 0; _Day < Time._Normal_Days_In_Year; _Day++) { _SimulateMovement(); // Output Location Map _File = new File("C:/temp/_Density_Map_Population" + _Year + "_" + _Day + "." + _Type); Mapping._Map_Population( _File, _Type, _ImageExporter, _Environment, _Population); // Deaths // Does anyone die today? _TotalDeathsInYear += _SimulateDeath( _Mortality); // Births // Is anyone born today? _TotalBirthsInYear += _SimulateBirth(); // Pregnancy // Does anyone get pregnant today? _TotalPregnanciesInYear += _SimulatePregnancy( _PregnantFemales, _Fertility); // Miscarriage // Does anyone miscarry today? _TotalMiscarriagesInYear += _SimulateMiscarriage( _PregnantFemales); _Environment._Time._Increment_Day(); System.out.println( "_Year " + _Year + "_Day " + _Day); } _TotalDeaths += _TotalDeathsInYear; _TotalBirths += _TotalBirthsInYear; _TotalPregnancies += _TotalPregnanciesInYear; System.out.println( "_Year " + _Year + ", _TotalDeathsInYear " + _TotalDeathsInYear + ", _TotalBirthsInYear " + _TotalBirthsInYear + ", _TotalPregnanciesInYear " + _TotalPregnanciesInYear + ", _TotalMiscarriagesInYear " + _TotalMiscarriagesInYear); _Demographics._AgeGenderPlot( _Population, _Environment._Time); } System.out.println( ", _TotalDeaths " + _TotalDeaths + ", _TotalBirths " + _TotalBirths + ", _TotalPregnancies " + _TotalPregnancies + ", _TotalMiscarriages " + _TotalMiscarriages); } public int _SimulateDeath( Mortality _Mortality) { int _TotalDeaths = 0; //double _FixedDailyDeathRate = 0.001; //0.5; double _DailyDeathRate; HashSet _Females = (HashSet) _Population[0]; HashSet _Males = (HashSet) _Population[1]; Iterator _Iterator; Female _Female; Male _Male; double comparison; _Iterator = _Females.iterator(); while (_Iterator.hasNext()) { _Female = (Female) _Iterator.next(); // Only people who are not already dead can die. if (_Female._Time_Death == null) { _DailyDeathRate = _Mortality.get_AnnualMortalityLikelihood(_Female) / 365.0d; comparison = _Environment._Random.nextDouble(); //if (comparison<_FixedDailyDeathRate){ if (comparison < _DailyDeathRate) { _Female.set_Time_Death(_Environment._Time); _TotalDeaths++; //System.out.println("Death of Person " + _Female); // } else { // System.out.println("Living Person " + _Female); } } } _Iterator = _Males.iterator(); while (_Iterator.hasNext()) { _Male = (Male) _Iterator.next(); // Only people who are not already dead can die. if (_Male._Time_Death == null) { _DailyDeathRate = _Mortality.get_AnnualMortalityLikelihood(_Male) / 365.0d; comparison = _Environment._Random.nextDouble(); //if (comparison<_FixedDailyDeathRate){ if (comparison < _DailyDeathRate) { _Male.set_Time_Death(_Environment._Time); _TotalDeaths++; //System.out.println("Death of Person " + _Male); // } else { // System.out.println("Living Person " + _Male); } } } return _TotalDeaths++; } /** * @return Total number of births */ public int _SimulateBirth() { int _TotalBirths = 0; HashSet _Females = (HashSet) _Population[0]; Iterator _Iterator; Female _Female; HashSet newbornFemales = new HashSet(); _Iterator = _Females.iterator(); while (_Iterator.hasNext()) { _Female = (Female) _Iterator.next(); if (_Female._IsPregnant()) { if (_Female._Time_DueToGiveBirth.compareTo(_Environment._Time) == 0) { Person _Person = _Female._Gives_Birth(); if (_Person.get_Gender() == 0) { newbornFemales.add(_Person); } else { ((HashSet) _Population[1]).add(_Person); } _TotalBirths++; //System.out.println("Birth"); //} else { // System.out.println("Birth due in " + _Female._Time_DueToGiveBirth._Difference(_Environment._Time)); } } } _Females.addAll(newbornFemales); return _TotalBirths; } public int _SimulatePregnancy( HashSet _PregnantFemales, Fertility _Fertility) { int _TotalPregnancies = 0; HashSet _Females = (HashSet) _Population[0]; Iterator _Iterator; Female _Female; int _Age; double fertility; double comparison; _Iterator = _Females.iterator(); while (_Iterator.hasNext()) { _Female = (Female) _Iterator.next(); _Age = _Female.get_AgeInYears_int(); if (!_Female._IsPregnant() && _Female._Time_Death == null) { fertility = _Fertility.get_Fertility_Female(_Age); comparison = _Environment._Random.nextDouble(); if (comparison < fertility) { _Female.set_Pregnant(); //_Female.set_UnbornsFather(_Father); _PregnantFemales.add(_Female); _TotalPregnancies++; //System.out.println("Pregnancy"); } } } return _TotalPregnancies; } /** * @param _PregnantFemales */ public int _SimulateMiscarriage( HashSet _PregnantFemales) { int _TotalMiscarriages = 0; // Fixed chance of miscarriage double _MiscarriageProbablity = 0.0005; double comparison; Iterator _Iterator; Female _Female; _Iterator = _PregnantFemales.iterator(); HashSet _MiscarriedFemales = new HashSet(); while (_Iterator.hasNext()) { _Female = (Female) _Iterator.next(); comparison = _Environment._Random.nextDouble(); if (comparison < _MiscarriageProbablity) { _Female._Time_DueToGiveBirth = null; _MiscarriedFemales.add(_Female); _TotalMiscarriages++; //System.out.println("Miscarriage"); } } _PregnantFemales.removeAll(_MiscarriedFemales); return _TotalMiscarriages; } /** * Each agent is moved to any position in a 1 cell radius of their current * location at random. */ public void _SimulateMovement() { Iterator _Iterator; HashSet _Females = (HashSet) _Population[0]; Female _Female; int _Movement; _Iterator = _Females.iterator(); while (_Iterator.hasNext()) { _Female = (Female) _Iterator.next(); _Movement = _Environment._Random.nextInt(8); _Female._Location = Movement.getNewLocation( _Female._Location, _Movement, _Environment); } HashSet _Males = (HashSet) _Population[1]; Male _Male; _Iterator = _Males.iterator(); while (_Iterator.hasNext()) { _Male = (Male) _Iterator.next(); _Movement = _Environment._Random.nextInt(8); _Male._Location = Movement.getNewLocation( _Male._Location, _Movement, _Environment); } } }