private static List <int> TestLearningThreshold(SimParams par, Population pop, List <int> notVacant) { /*Get birds with a threshold below the age keepign in mind * the vertical learning threshold*/ float ModifiedThresh; List <int> Learners = new List <int> { }; for (int i = 0; i < notVacant.Count; i++) { ModifiedThresh = pop.LearningThreshold[notVacant[i]] >= 1? pop.LearningThreshold[notVacant[i]]: (pop.LearningThreshold[notVacant[i]] - par.VerticalLearningCutOff) / (1 - par.VerticalLearningCutOff); if (pop.Age[notVacant[i]] + 1 <= ModifiedThresh)//full learn to learn { Learners.Add(notVacant[i]); } else if (pop.Age[notVacant[i]] < ModifiedThresh) //Chance to learn during partical year { if (par.NextFloat() < ModifiedThresh - pop.Age[notVacant[i]]) { Learners.Add(notVacant[i]); } } } return(Learners); }
//Learning Accessory functions private static ConsensusResults ConsensusLearning(SimParams par, Population pop, List <int>[] tutors, List <int> learners) { //Create a consensus based on songs from several males List <int>[] ConsensusSongs = new List <int> [learners.Count]; List <int>[] AddSyls = new List <int> [learners.Count]; List <int>[] AllSongs; List <int> CollapsedSongs; float Conform; for (int i = 0; i < learners.Count; i++) { ConsensusSongs[i] = new List <int> { }; AddSyls[i] = new List <int> { }; AllSongs = ListeningTest(par, pop, tutors[i].ToArray(), par.ListeningThreshold); CollapsedSongs = AllSongs.SelectMany(x => x).ToList(); ConsensusSongs[i] = CollapsedSongs.Distinct().ToList(); for (int j = 0; j < ConsensusSongs[i].Count(); j++) { Conform = ConsensusCalc(par, ConsensusSongs[i][j], CollapsedSongs); if (par.NextFloat() < Conform) { AddSyls[i].Add(ConsensusSongs[i][j]); } } } ConsensusResults Returnable = new ConsensusResults(AddSyls, ConsensusSongs); return(Returnable); }
private static List <int> CheckEncounter(SimParams par, List <int> capable) { for (int i = capable.Count - 1; i >= 0; i--) { if (par.NextFloat() > par.EncounterSuccess) { capable.RemoveAt(i); } } return(capable); }
/*Functions for decideing how birds learn and * allowing them to do so*/ //Main process public static List <int> CoreLearningProcess(SimParams par, Population pop, int learner, List <int> learnerSong, List <int> tutorSong) { //Copy Tutor Syllables List <float> Rolls = new List <float> { }; float AccRoll; for (int i = 0; i < tutorSong.Count; i++) { AccRoll = par.NextFloat(); if (AccRoll < pop.Accuracy[learner])//Correct { learnerSong.Add(tutorSong[i]); } else { Rolls.Add(AccRoll); } } //Innovation if (Rolls.Count > 0) { int Innovation = 0; float InventThresh = 1 - ((1 - pop.Accuracy[learner]) * pop.ChanceInvent[learner]); for (int i = 0; i < Rolls.Count; i++) { if (Rolls[i] >= InventThresh) { Innovation += 1; } } if (Innovation > 0) { int[] NewSyls; HashSet <int> AvailableSyllables = new HashSet <int>(par.AllSyls); AvailableSyllables.ExceptWith(Enumerable.Concat(learnerSong, tutorSong)); if (Innovation >= AvailableSyllables.Count)//Not enough syls for sampling { NewSyls = AvailableSyllables.ToArray(); } else // Enough syls for sampling { NewSyls = par.RandomSampleEqualNoReplace(AvailableSyllables.ToList(), Innovation); } learnerSong.AddRange(NewSyls); } //Otherwise no innovation occured } //Otherwise no mistakes were made return(learnerSong); }
private static List <int> DropSyllables(SimParams par, List <int> song, List <int> droppableSyls, float chanceForget) { //Remove syllables not heard from tutor based on ChanceForget for (int i = 0; i < droppableSyls.Count; i++) { if (par.NextFloat() < chanceForget) { song.Remove(droppableSyls[i]); } } return(song); }
//Adult Learning-Specific Accessory functions private static List <int>[] ListeningTest(SimParams par, Population pop, int[] tutors, float lisThresh) { /*Get syls and test whether Repsize larger than listening threshold, * if so, randomly remove extra syllables.*/ List <int>[] TutorSyls = new List <int> [tutors.Length]; for (int i = 0; i < tutors.Length; i++) { TutorSyls[i] = pop.MaleSong[tutors[i]].ToList(); } if (lisThresh >= .999f & lisThresh < 1) { return(TutorSyls); } if (lisThresh % 1 == 0)//Absolute number of sylls learned { int Thresh = (int)lisThresh; int Remove; for (int i = 0; i < TutorSyls.Length; i++) { if (TutorSyls[i].Count > Thresh) { Remove = TutorSyls[i].Count - Thresh; par.RandomSampleEqualNoReplace(TutorSyls[i], Remove); } } } else //percentage of sylls learned { float Learnable; float Remove; for (int i = 0; i < TutorSyls.Length; i++) { Learnable = (TutorSyls[i].Count - par.MinLearnedSyllables) * lisThresh + par.MinLearnedSyllables; if (Learnable < TutorSyls[i].Count) { Learnable = par.NextFloat() < Learnable % 1? (float)Math.Ceiling(Learnable):(float)Math.Floor(Learnable); Remove = TutorSyls[i].Count - Learnable; if (Remove > 0) { par.RandomSampleEqualNoReplace(TutorSyls[i], (int)Remove); } } } } return(TutorSyls); }
private static List <int> GenerateNovelSong(SimParams par) { //Test whether each syllable is learned List <int> Song = new List <int>(); while (Song.Count == 0) { for (int i = 0; i < par.SongCore.Count; i++) { if (par.NextFloat() < par.SongCore[i]) { Song.Add(i); } } } return(Song); }
static int[] GetAgeGroup(SimParams par, float[] ageRates) { //get the number of birds that are in each age group List <int> AgeGroup = new List <int> { }; //Guaranteed ages int Birds = new int {}; for (int i = 0; i <= par.MaxAge; i++) { Birds = (int)Math.Floor(par.NumBirds * ageRates[i]); AgeGroup.AddRange(Enumerable.Repeat(i, Birds).ToList()); } //Get the chance ages if there are any int Remainder = par.NumBirds - AgeGroup.Count; List <int> RemainderAges = new List <int> { }; if (Remainder > 0) { float[] Chance = new float[Remainder]; for (int i = 0; i < Remainder; i++) { Chance[i] = par.NextFloat(); } //Chance to be at each possible age float[] CumulativeAgeProbability = new float[ageRates.Length + 1]; CumulativeAgeProbability[0] = 0; CumulativeAgeProbability[ageRates.Length] = 1; for (int i = 0; i < ageRates.Length - 1; i++) { CumulativeAgeProbability[i + 1] = ageRates[i] + CumulativeAgeProbability[i]; } //test whether Chance belongs to a given age group for (int i = 0; i <= par.MaxAge; i++) { int AgeN = Chance.Count(x => (x >= CumulativeAgeProbability[i] && x < CumulativeAgeProbability[i + 1])); if (AgeN == 1) { RemainderAges.Add(i); } else if (AgeN > 1) { RemainderAges.AddRange(Enumerable.Repeat(i, AgeN)); } } AgeGroup.AddRange(RemainderAges); } //Rearrange the age groups randomly List <int> Rearrange = Enumerable.Range(0, par.NumBirds).ToList(); int[] NewIndex = par.RandomSampleEqualNoReplace(Rearrange, par.NumBirds); //AgeGroup = AgeGroup.OrderBy(x => par.Rand.Next()).ToList(); for generating array with rand numbers int[] ScrambledAgeGroup = AgeGroup.ToArray(); Array.Sort(NewIndex, ScrambledAgeGroup); return(ScrambledAgeGroup); }
//Death private static int[] AgeDeath(SimParams par, Population pop) { //Send birds to the circus based on retirement age List <int> DeadIndex = new List <int> { }; float[] PickChance = LearningPenalty(par, pop.LearningThreshold); int[] AgePool; float Dead; int MustDie; float ChanceDie; int[] Chosen; int[] ChosenInd; float[] PickChanceSubSet; for (int i = 0; i < par.MaxAge; i++) { //which birds are age i AgePool = Enumerable.Range(0, pop.Age.Length) .Where(x => pop.Age[x] == i).ToArray(); if (AgePool.Length == 0)//No birds of a given age { continue; } Dead = AgePool.Length * (1 - pop.SurvivalChance[i]); MustDie = (int)Math.Floor(Dead); ChanceDie = Dead % 1; if (par.NextFloat() < ChanceDie) { MustDie += 1; } if (MustDie == 0) { continue; } Chosen = new int[MustDie]; if (MustDie >= AgePool.Length) { Chosen = AgePool; } else { PickChanceSubSet = new float[AgePool.Length]; for (int j = 0; j < AgePool.Length; j++) { PickChanceSubSet[j] = PickChance[AgePool[j]]; } ChosenInd = par.RandomSampleUnequal(PickChanceSubSet, MustDie, false); for (int j = 0; j < ChosenInd.Length; j++) { Chosen[j] = AgePool[ChosenInd[j]]; } } DeadIndex.AddRange(Chosen); } DeadIndex.AddRange(Enumerable.Range(0, pop.Age.Length).Where(x => pop.Age[x] == par.MaxAge).ToArray());//birds of max age must die /*double[] GetIndexer = new double[DeadIndex.Count]; * for(int i=0;i<DeadIndex.Count;i++){ * GetIndexer[i] = PickChance[DeadIndex[i]]; * } * Console.WriteLine(PickChance.Average()); * //Console.WriteLine(GetIndexer.Average());*/ return(DeadIndex.ToArray()); }