//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>[] ChooseMultipleTutors(SimParams par, Population pop, List <int> learners, List <int> notVacant, int numTutors) { /*remove chicks and songless birds + any Misc, mark all excluded * birds as unavailable*/ HashSet <int> PotentialTutorsTemp = new HashSet <int>(notVacant.Where(x => pop.Age[x] > 0)); PotentialTutorsTemp.ExceptWith(PotentialTutorsTemp.Where(x => pop.SyllableRepertoire[x] == 0).ToArray()); List <int>[] Tutors = new List <int> [learners.Count]; if (par.LocalTutor) { HashSet <int> Unavailable = new HashSet <int>(Enumerable.Range(0, par.NumBirds)); Unavailable.ExceptWith(PotentialTutorsTemp); for (int i = 0; i < learners.Count; i++) { if (par.SocialCues) { Tutors[i] = Locations.GetLocalBirds(par, pop, learners[i], Unavailable, numTutors, pop.Bred).ToList(); } else { Tutors[i] = Locations.GetLocalBirds(par, pop, learners[i], Unavailable, numTutors).ToList(); } } } else { List <int> PotentialTutors; for (int i = 0; i < learners.Count; i++) { PotentialTutors = PotentialTutorsTemp.ToList(); PotentialTutors.Remove(learners[i]); if (par.SocialCues) { float[] TutorProbs = new float[PotentialTutors.Count]; for (int j = 0; j < TutorProbs.Length; j++) { TutorProbs[j] = pop.Bred[PotentialTutors[j]]; } int[] ChosenIndex = par.RandomSampleUnequal(TutorProbs, numTutors); for (int j = 0; j < numTutors; j++) { ChosenIndex[j] = PotentialTutors[ChosenIndex[j]]; } Tutors[i] = ChosenIndex.ToList(); } else { Tutors[i] = par.RandomSampleEqualNoReplace(PotentialTutors, numTutors).ToList(); } } } return(Tutors); }
/*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); }
public static int[] GetGlobalBirds(SimParams par, Population pop, int learner, List <int> potentialBirds, int numBirds = 1) { int[] Birds; List <int> PotentialBirds = potentialBirds.ToList(); PotentialBirds.Remove(learner); if (numBirds == 1) { Birds = par.RandomSampleEqualReplace(PotentialBirds, numBirds); } else { Birds = par.RandomSampleEqualNoReplace(PotentialBirds, numBirds); } return(Birds); }
public static InvasionData Invasion(SimParams par, string type, float invaderStat, int numInvaders = 1, int burnIn = 500) { CheckStatValue(par, type, invaderStat); Population Pop = new Population(par); //Get to Equilibrium for (int i = 0; i < burnIn; i++) { Pop = BirthDeathCycle.Step(par, Pop); } //Invade int[] InvaderIndex = par.RandomSampleEqualNoReplace(Enumerable.Range(0, par.NumBirds).ToList(), numInvaders); for (int i = 0; i < numInvaders; i++) { CreateInvader(Pop, type, InvaderIndex[i], invaderStat); //Pop.Age[InvaderIndex[i]] = 1; //Pop.LearningThreshold[InvaderIndex[i]] = invaderStat; } //Postinvasion run int Counter = 1; int Categories = 2; while (Categories != 1) { Counter += 1; Pop = BirthDeathCycle.Step(par, Pop); if (Counter == 400) { break; } else { Categories = CountCategories(Pop, type);//Pop.LearningThreshold.Distinct().Count(); } } InvasionData Results = new InvasionData(Counter, GetAverage(Pop, type));//Pop.LearningThreshold.Average()); return(Results); }
//Getting local and global birds public static int[] GetLocalBirds(SimParams par, Population pop, int target, HashSet <int> unavailable, int numBirds = 1, float[] probs = null) { //pick Tutors locally int[] Birds = new int[numBirds]; int[] UsableInd; UsableInd = LocalSearch(par, pop, target, unavailable, numBirds).ToArray(); //return the right number of birds if (UsableInd.Length == numBirds)//only numTutors choice(s) { return(UsableInd); } else //Multiple choices { if (probs != null)//unequal probabilities { int[] Index; float[] Prob = new float[UsableInd.Length]; for (int j = 0; j < UsableInd.Length; j++) { Prob[j] = probs[UsableInd[j]]; } Index = par.RandomSampleUnequal(Prob, numBirds, false); for (int j = 0; j < numBirds; j++) { Birds[j] = UsableInd[Index[j]]; } return(Birds); } if (numBirds == 1)//can use the faster with replace { Birds[0] = UsableInd[par.RandomSampleEqualReplace(UsableInd.ToList(), 1)[0]]; return(Birds); }//need the slower without replace Birds = par.RandomSampleEqualNoReplace(UsableInd.ToList(), numBirds); return(Birds); } }
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); }