private void SetupPopulation(SparseArray<IPerson[]> pop, Dictionary<int, List<IPerson>> tempPop, IZone[] flatZones) { var flatPop = pop.GetFlatData(); Parallel.For( 0, flatZones.Length, delegate(int i) { List<IPerson> temp; if ( tempPop.TryGetValue( flatZones[i].ZoneNumber, out temp ) ) { flatPop[i] = temp.ToArray(); } else { flatPop[i] = new Person[0]; } } ); this.Population = pop; }
private void GenerateZone(SparseArray<IPerson[]> population, int zoneIndex, int pop, Random rand) { Household[] Households = new Household[3]; for ( int i = 0; i < 3; i++ ) { Households[i] = new Household() { Zone = this.ZoneSystem.ZoneArray[zoneIndex], Cars = i }; } Person[] people = new Person[pop]; population[zoneIndex] = people; for ( int k = 0; k < pop; k++ ) { people[k] = new Person(); } /* * To generate the population follow these steps, and at each one clear to integers * Step 1) Split into Age Cat's * Step 2) Split into ( Unemployed, Full-time, Part-Time ) * Step 3) Split into ( Non-Student, Student ) , ( Occupation ) * Step 4) Split into Driver's License ( Not Have / Have ) */ SparseArray<int> agePop = SplitAges( zoneIndex, pop, rand ); int ageOffset = 0; foreach ( var validAgeIndex in this.ValidAges ) { var numberOfPeople = agePop[validAgeIndex]; var employmentPop = SplitEmployment( zoneIndex, validAgeIndex, numberOfPeople, rand ); int employmentOffset = 0; foreach ( var validEmploymentStatusIndex in employmentPop.ValidIndexies() ) { var numberOfEmploymentClassifiedPeople = employmentPop[validEmploymentStatusIndex]; int StudentPop = SplitStudents( zoneIndex, validAgeIndex, validEmploymentStatusIndex, numberOfEmploymentClassifiedPeople, rand ); int numberOfDriversLicenses = this.SplitDrivers( zoneIndex, validAgeIndex, validEmploymentStatusIndex, numberOfEmploymentClassifiedPeople, rand ); var OccupationSplit = this.SplitOccupations( zoneIndex, validAgeIndex, validEmploymentStatusIndex, numberOfEmploymentClassifiedPeople, rand ); AssignEmploymentStatus( people, ageOffset, employmentOffset, validEmploymentStatusIndex, numberOfEmploymentClassifiedPeople ); AssignSchools( people, ageOffset, employmentOffset, StudentPop ); AssignOccupationAndLicenese( people, ageOffset, employmentOffset, OccupationSplit, numberOfEmploymentClassifiedPeople, numberOfDriversLicenses, rand ); employmentOffset += numberOfEmploymentClassifiedPeople; } AssignAge( rand, people, ageOffset, validAgeIndex, numberOfPeople ); // Assign people to households depending on the number of cars they will have foreach ( var validOccupationIndex in this.Demographics.OccupationCategories.ValidIndexies() ) { int[] haveLicenseIndexes, doNotHaveLicenseIndexes; var haveLicense = this.SplitCars( people, zoneIndex, validAgeIndex, validOccupationIndex, true, ageOffset, numberOfPeople, rand, out haveLicenseIndexes ); var doNotHaveLicense = this.SplitCars( people, zoneIndex, validAgeIndex, validOccupationIndex, false, ageOffset, numberOfPeople, rand, out doNotHaveLicenseIndexes ); AssignCars( people, haveLicenseIndexes, haveLicense, Households, ageOffset, rand ); AssignCars( people, doNotHaveLicenseIndexes, doNotHaveLicense, Households, ageOffset, rand ); } ageOffset += numberOfPeople; } }
private SparseArray<int> SplitCars(Person[] people, int zoneIndex, int validAgeIndex, int validOccupationIndex, bool license, int ageOffset, int agePop, Random rand, out int[] indexes) { SparseArray<float> ret = new SparseArray<float>( new SparseIndexing() { Indexes = new SparseSet[] { new SparseSet() { Start = 0, Stop = 2 } } } ); // Because everything is random at this point we actually need to scan to see how many people we have List<int> indexesList = new List<int>( agePop ); if ( validOccupationIndex == this.UnemployedOccupation ) { for ( int i = 0; i < agePop; i++ ) { var person = people[i + ageOffset]; if ( person.DriversLicense == license ) { var range = this.Demographics.AgeCategories[validAgeIndex]; var age = person.Age; if ( age >= range.Start && age <= range.Stop ) { indexesList.Add( i ); } } } var data = this.Demographics.NonWorkerVehicleRates[zoneIndex]; foreach ( var validCarsIndex in ret.ValidIndexies() ) { ret[validCarsIndex] = data[license ? 1 : 0, validAgeIndex, validCarsIndex]; } } else { for ( int i = 0; i < agePop; i++ ) { var person = people[i + ageOffset]; if ( person.DriversLicense == license && person.Occupation == validOccupationIndex ) { indexesList.Add( i ); } } var data = this.Demographics.WorkerVehicleRates[zoneIndex]; foreach ( var validCarsIndex in ret.ValidIndexies() ) { ret[validCarsIndex] = data[license ? 1 : 0, validOccupationIndex, validCarsIndex]; } } indexes = indexesList.ToArray(); return this.SplitAndClear( indexes.Length, ret, rand ); }
private void AssignOccupationAndLicenese(Person[] people, int ageOffset, int employmentOffset, SparseArray<int> OccupationSplit, int numberOfEmploymentClassifiedPeople, int numberOfLicenses, Random r) { int[] personIndex = new int[numberOfEmploymentClassifiedPeople]; for ( int i = 0; i < numberOfEmploymentClassifiedPeople; i++ ) { personIndex[i] = i; } // Randomize the population for assignment (Card shuffle algorithm) for ( int i = 0; i < numberOfEmploymentClassifiedPeople; i++ ) { var selectedIndex = r.Next( i, numberOfEmploymentClassifiedPeople ); var temp = personIndex[selectedIndex]; personIndex[selectedIndex] = personIndex[i]; personIndex[i] = temp; } // assign the occupations int occOffset = 0; foreach ( var occIndex in OccupationSplit.ValidIndexies() ) { var occPop = OccupationSplit[occIndex]; for ( int i = 0; i < occPop; i++ ) { people[personIndex[occOffset + i] + ageOffset + employmentOffset].Occupation = occIndex; } occOffset += occPop; } // Randomize the population for assignment (Card shuffle algorithm) for ( int i = 0; i < numberOfEmploymentClassifiedPeople; i++ ) { var selectedIndex = r.Next( i, numberOfEmploymentClassifiedPeople ); var temp = personIndex[selectedIndex]; personIndex[selectedIndex] = personIndex[i]; personIndex[i] = temp; } // assign the occupations for ( int i = 0; i < numberOfLicenses; i++ ) { people[personIndex[i] + ageOffset + employmentOffset].DriversLicense = true; } }
private void AssignCars(Person[] people, int[] indexes, SparseArray<int> split, Household[] households, int ageOffset, Random rand) { var numberOfPeople = indexes.Length; // randomly shuffle the indexes before we actually assign the households for ( int i = 0; i < numberOfPeople; i++ ) { var selectedIndex = rand.Next( i, numberOfPeople ); var temp = indexes[selectedIndex]; indexes[selectedIndex] = indexes[i]; indexes[i] = temp; } int typeOffset = 0; foreach ( var carType in split.ValidIndexies() ) { var numberInType = split[carType]; for ( int i = 0; i < numberInType; i++ ) { people[indexes[i + typeOffset] + ageOffset].Household = households[carType]; } typeOffset += numberInType; } }
private void AssignAge(Random rand, Person[] people, int ageOffset, int validAgeIndex, int numberOfPeople) { Range ageRange = this.Demographics.AgeCategories[validAgeIndex]; for ( int p = 0; p < numberOfPeople; p++ ) { people[p + ageOffset].Age = rand.Next( ageRange.Start, int.MaxValue == ageRange.Stop ? int.MaxValue : ageRange.Stop + 1 ); people[p + ageOffset].ExpansionFactor = 1; } }
private static void AssignSchools(Person[] people, int ageOffset, int employmentOffset, int StudentPop) { for ( int p = 0; p < StudentPop; p++ ) { people[p + ageOffset + employmentOffset].StudentStatus = 1; } }
private static void AssignEmploymentStatus(Person[] people, int ageOffset, int employmentOffset, int validEmploymentStatusIndex, int numberOfEmploymentClassifiedPeople) { for ( int p = 0; p < numberOfEmploymentClassifiedPeople; p++ ) { people[p + ageOffset + employmentOffset].EmploymentStatus = validEmploymentStatusIndex; } }