Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Diagnostics;
- namespace PopulationSim2k19
- {
- public class Agent
- {
- public int ID { get; set; } = 0;
- public int Age { get; set; } = 0;
- public bool Dead { get; set; } = false;
- public int Repro { get; set; } = 780; //age at reproductive maturity
- public int PRepro { get; set; } = 2080; //post-reproductive maturity,
- public bool Pregnant { get; set; } = false;
- public double FertilityRoll { get; set; } = 0.02; //%chance of pregnancy,
- public int WeekOfPregnancy { get; set; } = 0;
- public int Gestation { get; set; } = 38; //length in weeks until birth
- public double PGestation { get; set; } = 0.5; //post-gestational regeneration (multiplier of gestation time),
- public bool PGestational { get; set; } = false; //post-gestational stage boolean,
- public int PGestationalWeek { get; set; } = 0;
- public int Pregnancies { get; set; } = 0;
- public bool Adult { get; set; } = false;
- public Agent()
- {
- }
- }
- class Program
- {
- static readonly int pop_num = 1000;
- static readonly int desired_length = 20;
- static readonly int desired_simulations = 52000; //52000
- static readonly bool verboseoutput = true;
- static readonly double prerepro = 0.35;
- static readonly double repro = 0.6;
- static readonly double postrepro = 0.05;
- static readonly double basedeathfactor = 0.02;
- static readonly double basefertilityfactor = 0.02;
- static readonly int sim_length = desired_length * 52;
- static readonly int max_pop_size = 10000;
- static readonly int sim_interval = 10;
- static readonly double sim_time_length = 0.066;
- static int pop_actual = pop_num;
- static int week = 0;
- static int sim_number = 0;
- static Stopwatch sw = new Stopwatch();
- static List<Agent> pop = new List<Agent>();
- static System.IO.StreamWriter F = new System.IO.StreamWriter(@"C:\Users\Elmeri\Desktop\results.txt");
- static void CreateLogLine(int numDead, int numPopulation, int numBorn, int numPregnant)
- {
- F.WriteLine("\n" + week + "\t" + numDead + "\t" + numPopulation + "\t" + numBorn + "\t" + numPregnant);
- }
- static void CreateLastLog()
- {
- if (verboseoutput)
- return;
- F.WriteLine("\n*At week " + week + " the simulation ended with " + pop_actual + " agents");
- }
- static double GetRandomNumber(double minimum, double maximum)
- {
- Random random = new Random();
- return random.NextDouble() * (maximum - minimum) + minimum;
- }
- static void CreateAgents(int numAgents, string creationType)
- {
- if (creationType == "SimStart")
- {
- double prereprocount = Math.Ceiling(pop_num * prerepro);
- double reprocount = Math.Ceiling(pop_num * repro);
- double postreprocount = Math.Ceiling(pop_num * postrepro);
- Console.WriteLine("Starting simulation " + sim_number + " with agent configuration " + prereprocount + "/" + reprocount + "/" + postreprocount + " for a total of " + (prereprocount + reprocount + postreprocount) + " agents");
- reprocount = reprocount + prereprocount;
- postreprocount = postreprocount + reprocount;
- for (int i = 0; i < numAgents; i++)
- {
- if ((prereprocount > i) && (i >= 0))
- {
- Agent newAgent = new Agent();
- newAgent.Age = (int)GetRandomNumber(0.0, newAgent.Repro);
- pop.Add(newAgent);
- }
- else if ((reprocount > i) && (i >= prereprocount))
- {
- Agent newAgent = new Agent();
- newAgent.Age = (int)GetRandomNumber(newAgent.Repro, newAgent.PRepro);
- pop.Add(newAgent);
- }
- else if ((postreprocount > i) && (i >= reprocount))
- {
- Agent newAgent = new Agent();
- newAgent.Age = (int)GetRandomNumber(newAgent.PRepro, 3000);
- pop.Add(newAgent);
- }
- }
- }
- else if (creationType == "Birth")
- {
- for (int i = 0; i < numAgents; i++)
- {
- Agent newAgent = new Agent();
- pop.Add(newAgent);
- }
- }
- }
- static bool Mortality(int ageWeeks)
- {
- double input = (double)ageWeeks / 1000.0;
- double deathFunction = 0.1 * (Math.Pow(0.6 * (input + 1.0), 2.0) * Math.Pow(0.01 * (input - 2.5), 2.0) * Math.Pow(0.9 * (input - 2.0), 2.0) + basedeathfactor);
- Random random = new Random();
- double deathRoll = random.NextDouble();
- if (deathRoll <= deathFunction)
- {
- return true;
- }
- return false;
- }
- static bool Fecundity(double chancepregnant)
- {
- Random random = new Random();
- double pRoll = random.NextDouble();
- if (pRoll < chancepregnant)
- {
- return false;
- }
- return true;
- }
- static void Simulate(int dsrlngth)
- {
- for (int i = 0; i < dsrlngth; i++)
- {
- if ((pop_actual > max_pop_size) || (pop_actual <= 10) || (week == dsrlngth))
- {
- sw.Stop();
- double time_length = sw.Elapsed.TotalSeconds;
- Console.WriteLine("The simulation has ended after " + time_length + " seconds with " + pop_actual + " agents and " + week + " weeks");
- break;
- }
- int deaths = 0;
- int births = 0;
- int pregnants = 0;
- List<int> deadindices = new List<int>();
- //age all the agents
- foreach (Agent a in pop)
- {
- a.Age++;
- if (Mortality(a.Age))
- {
- a.Dead = true;
- deadindices.Add(pop.IndexOf(a));
- deaths++;
- }
- }
- //remove dead ones to prevent dead ones from being pregnant
- foreach (int ind in deadindices)
- {
- pop.RemoveAt(ind);
- }
- //make agents pregnant, advance their fetal ages, check for whether it is time for birth, check whether the agent can be returned to a fertile status (post-gestational period)
- foreach (Agent a in pop)
- {
- //check for pregnant or post-gestational
- if (a.Pregnant)
- {
- pregnants++;
- //check for whether its delivery time
- if (a.WeekOfPregnancy >= a.Gestation)
- {
- a.Pregnant = false;
- a.Pregnancies++;
- a.PGestational = true;
- births++;
- }
- a.WeekOfPregnancy++;
- }
- else if (a.PGestational)
- {
- //check for whether the post - birth recovery period is over
- if (a.PGestationalWeek >= (a.Gestation * a.PGestation))
- {
- a.PGestational = false;
- }
- a.PGestationalWeek++;
- }
- else if (!a.Pregnant && !a.PGestational)
- {
- //calculate chance of pregnancy and manipulate the agent accordingly
- if (a.Age > a.Repro && a.Age < a.PRepro)
- {
- if (Fecundity(a.FertilityRoll))
- a.Pregnant = true;
- }
- }
- }
- for (int b = 0; b < births; b++)
- {
- CreateAgents(1, "Birth");
- }
- pop_actual = (pop_actual - deaths) + births;
- week++;
- CreateLogLine(deaths, pop_actual, births, pregnants);
- }
- }
- static void Main(string[] args)
- {
- sw.Start();
- F.WriteLine("week \t deaths \t population \t births \t pregnancies");
- CreateAgents(pop_num, "SimStart");
- Simulate(desired_simulations);
- F.Close();
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement