/**
* 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);
}
}
}