public bool Equals(DayPattern other) { if (ReferenceEquals(null, other)) { return(false); } if (ReferenceEquals(this, other)) { return(true); } int workToursFlag = (WorkTours > 0).ToFlag(); int schoolToursFlag = (SchoolTours > 0).ToFlag(); int escortToursFlag = (EscortTours > 0).ToFlag(); int personalBusinessToursFlag = (PersonalBusinessTours > 0).ToFlag(); int shoppingToursFlag = (ShoppingTours > 0).ToFlag(); int mealToursFlag = (MealTours > 0).ToFlag(); int socialToursFlag = (SocialTours > 0).ToFlag(); int workTours2Flag = (other.WorkTours > 0).ToFlag(); int schoolTours2Flag = (other.SchoolTours > 0).ToFlag(); int escortTours2Flag = (other.EscortTours > 0).ToFlag(); int personalBusinessTours2Flag = (other.PersonalBusinessTours > 0).ToFlag(); int shoppingTours2Flag = (other.ShoppingTours > 0).ToFlag(); int mealTours2Flag = (other.MealTours > 0).ToFlag(); int socialTours2Flag = (other.SocialTours > 0).ToFlag(); int workStopsFlag = (WorkStops > 0).ToFlag(); int schoolStopsFlag = (SchoolStops > 0).ToFlag(); int escortStopsFlag = (EscortStops > 0).ToFlag(); int personalBusinessStopsFlag = (PersonalBusinessStops > 0).ToFlag(); int shoppingStopsFlag = (ShoppingStops > 0).ToFlag(); int mealStopsFLag = (MealStops > 0).ToFlag(); int socialStopsFlag = (SocialStops > 0).ToFlag(); int workStops2Flag = (other.WorkStops > 0).ToFlag(); int schoolStops2Flag = (other.SchoolStops > 0).ToFlag(); int escortStops2Flag = (other.EscortStops > 0).ToFlag(); int personalBusinessStops2Flag = (other.PersonalBusinessStops > 0).ToFlag(); int shoppingStops2Flag = (other.ShoppingStops > 0).ToFlag(); int mealStops2Flag = (other.MealStops > 0).ToFlag(); int socialStops2Flag = (other.SocialStops > 0).ToFlag(); return (workToursFlag == workTours2Flag && schoolToursFlag == schoolTours2Flag && escortToursFlag == escortTours2Flag && personalBusinessToursFlag == personalBusinessTours2Flag && shoppingToursFlag == shoppingTours2Flag && mealToursFlag == mealTours2Flag && socialToursFlag == socialTours2Flag && workStopsFlag == workStops2Flag && schoolStopsFlag == schoolStops2Flag && escortStopsFlag == escortStops2Flag && personalBusinessStopsFlag == personalBusinessStops2Flag && shoppingStopsFlag == shoppingStops2Flag && mealStopsFLag == mealStops2Flag && socialStopsFlag == socialStops2Flag); }
public void Run(IPersonDayWrapper personDay) { if (personDay == null) { throw new ArgumentNullException("personDay"); } personDay.ResetRandom(5); if (Global.Configuration.IsInEstimationMode) { if (Global.Configuration.EstimationModel != CHOICE_MODEL_NAME) { return; } } ChoiceProbabilityCalculator choiceProbabilityCalculator = _helpers[ParallelUtility.threadLocalAssignedIndex.Value].GetChoiceProbabilityCalculator(personDay.Id); if (_helpers[ParallelUtility.threadLocalAssignedIndex.Value].ModelIsInEstimationMode) { RunModel(choiceProbabilityCalculator, personDay, new DayPattern(personDay)); choiceProbabilityCalculator.WriteObservation(); } else { if (personDay.Person.UsualWorkParcelId != Global.Settings.OutOfRegionParcelId && personDay.Person.UsualSchoolParcelId != Global.Settings.OutOfRegionParcelId) { RunModel(choiceProbabilityCalculator, personDay); ChoiceProbabilityCalculator.Alternative chosenAlternative = choiceProbabilityCalculator.SimulateChoice(personDay.Household.RandomUtility); DayPattern choice = (DayPattern)chosenAlternative.Choice; personDay.WorkTours = choice.WorkTours; personDay.SchoolTours = choice.SchoolTours; personDay.EscortTours = choice.EscortTours; personDay.PersonalBusinessTours = choice.PersonalBusinessTours; personDay.ShoppingTours = choice.ShoppingTours; personDay.MealTours = choice.MealTours; personDay.SocialTours = choice.SocialTours; personDay.WorkStops = choice.WorkStops; personDay.SchoolStops = choice.SchoolStops; personDay.EscortStops = choice.EscortStops; personDay.PersonalBusinessStops = choice.PersonalBusinessStops; personDay.ShoppingStops = choice.ShoppingStops; personDay.MealStops = choice.MealStops; personDay.SocialStops = choice.SocialStops; } } }
private static TimelineMask AlicesWorkPattern() { var start = new LocalDate(2014, 12, 22); var workDay = new DayPattern { new LocalTimeInterval(new LocalTime(09, 00), new LocalTime(12, 30)), new LocalTimeInterval(new LocalTime(13, 00), new LocalTime(17, 30)), }; var pattern = new WorkPattern(LocalTimeZone, start); pattern.Add(null); pattern.Add(workDay); pattern.Add(workDay); pattern.Add(workDay); pattern.Add(workDay); pattern.Add(workDay); pattern.Add(null); return(pattern); }
private void InitializeDayPatterns() { if (_dayPatterns != null) { return; } _dayPatterns = new DayPattern[TOTAL_ALTERNATIVES]; int alternativeIndex = -1; for (int workTours = 0; workTours <= 1; workTours++) { for (int schoolTours = 0; schoolTours <= 1; schoolTours++) { for (int escortTours = 0; escortTours <= 1; escortTours++) { for (int personalBusinessTours = 0; personalBusinessTours <= 1; personalBusinessTours++) { for (int shoppingTours = 0; shoppingTours <= 1; shoppingTours++) { for (int mealTours = 0; mealTours <= 1; mealTours++) { for (int socialTours = 0; socialTours <= 1; socialTours++) { for (int workStops = 0; workStops <= 1; workStops++) { for (int schoolStops = 0; schoolStops <= 1; schoolStops++) { for (int escortStops = 0; escortStops <= 1; escortStops++) { for (int personalBusinessStops = 0; personalBusinessStops <= 1; personalBusinessStops++) { for (int shoppingStops = 0; shoppingStops <= 1; shoppingStops++) { for (int mealStops = 0; mealStops <= 1; mealStops++) { for (int socialStops = 0; socialStops <= 1; socialStops++) { int totalTours = workTours + schoolTours + escortTours + personalBusinessTours + shoppingTours + mealTours + socialTours; int totalStops = workStops + schoolStops + escortStops + personalBusinessStops + shoppingStops + mealStops + socialStops; // checks for: // three tours or less // four stops or less // five stops total or less // stops are less than or equal to tours // school and work stops are less than or equal to school and work tours // not both work and school stops if (totalTours > 3 || totalStops > 4 || totalTours + totalStops > 5 || Math.Min(totalStops, 1) > totalTours || Math.Min(workStops + schoolStops, 1) > workTours + schoolTours || workStops + schoolStops > 1) { continue; } alternativeIndex++; // next alternative int[] tours = new int[Global.Settings.Purposes.TotalPurposes]; tours[Global.Settings.Purposes.Work] = workTours; tours[Global.Settings.Purposes.School] = schoolTours; tours[Global.Settings.Purposes.Escort] = escortTours; tours[Global.Settings.Purposes.PersonalBusiness] = personalBusinessTours; tours[Global.Settings.Purposes.Shopping] = shoppingTours; tours[Global.Settings.Purposes.Meal] = mealTours; tours[Global.Settings.Purposes.Social] = socialTours; int[] stops = new int[Global.Settings.Purposes.TotalPurposes]; stops[Global.Settings.Purposes.Work] = workStops; stops[Global.Settings.Purposes.School] = schoolStops; stops[Global.Settings.Purposes.Escort] = escortStops; stops[Global.Settings.Purposes.PersonalBusiness] = personalBusinessStops; stops[Global.Settings.Purposes.Shopping] = shoppingStops; stops[Global.Settings.Purposes.Meal] = mealStops; stops[Global.Settings.Purposes.Social] = socialStops; _dayPatterns[alternativeIndex] = new DayPattern(tours, totalTours, stops, totalStops); } } } } } } } } } } } } } } }
private void RunModel(ChoiceProbabilityCalculator choiceProbabilityCalculator, IPersonDayWrapper personDay, DayPattern choice = null) { IHouseholdWrapper household = personDay.Household; IParcelWrapper residenceParcel = household.ResidenceParcel; IPersonWrapper person = personDay.Person; int carsPerDriver = household.GetCarsPerDriver(); double mixedDensity = residenceParcel.MixedUse3Index2(); double intersectionDensity = residenceParcel.IntersectionDensity34Minus1Buffer2(); double[] purposeLogsums = new double[Global.Settings.Purposes.TotalPurposes]; double[] atUsualLogsums = new double[3]; int carOwnership = person.GetCarOwnershipSegment(); int votSegment = person.Household.GetVotALSegment(); int transitAccess = residenceParcel.TransitAccessSegment(); if (person.UsualWorkParcel == null || person.UsualWorkParcelId == household.ResidenceParcelId) { purposeLogsums[Global.Settings.Purposes.Work] = 0; } else { int destinationArrivalTime = ChoiceModelUtility.GetDestinationArrivalTime(Global.Settings.Models.WorkTourModeModel); int destinationDepartureTime = ChoiceModelUtility.GetDestinationDepartureTime(Global.Settings.Models.WorkTourModeModel); ChoiceProbabilityCalculator.Alternative nestedAlternative = Global.ChoiceModelSession.Get <WorkTourModeModel>().RunNested(personDay, residenceParcel, person.UsualWorkParcel, destinationArrivalTime, destinationDepartureTime, household.VehiclesAvailable); purposeLogsums[Global.Settings.Purposes.Work] = nestedAlternative == null ? 0 : nestedAlternative.ComputeLogsum(); atUsualLogsums[Global.Settings.Purposes.Work] = Global.AggregateLogsums[person.UsualWorkParcel.ZoneId][Global.Settings.Purposes.HomeBasedComposite][carOwnership][votSegment][person.UsualWorkParcel.TransitAccessSegment()]; } if (person.UsualSchoolParcel == null || person.UsualSchoolParcelId == household.ResidenceParcelId) { purposeLogsums[Global.Settings.Purposes.School] = 0; } else { int destinationArrivalTime = ChoiceModelUtility.GetDestinationArrivalTime(Global.Settings.Models.SchoolTourModeModel); int destinationDepartureTime = ChoiceModelUtility.GetDestinationDepartureTime(Global.Settings.Models.SchoolTourModeModel); ChoiceProbabilityCalculator.Alternative nestedAlternative = Global.ChoiceModelSession.Get <SchoolTourModeModel>().RunNested(personDay, residenceParcel, person.UsualSchoolParcel, destinationArrivalTime, destinationDepartureTime, household.VehiclesAvailable); purposeLogsums[Global.Settings.Purposes.School] = nestedAlternative == null ? 0 : nestedAlternative.ComputeLogsum(); atUsualLogsums[Global.Settings.Purposes.School] = Global.AggregateLogsums[person.UsualSchoolParcel.ZoneId][Global.Settings.Purposes.HomeBasedComposite][carOwnership][votSegment][person.UsualSchoolParcel.TransitAccessSegment()]; } double compositeLogsum = Global.AggregateLogsums[household.ResidenceZoneId][Global.Settings.Purposes.HomeBasedComposite][carOwnership][votSegment][transitAccess]; purposeLogsums[Global.Settings.Purposes.Escort] = Global.AggregateLogsums[household.ResidenceZoneId][Global.Settings.Purposes.Escort][carOwnership][votSegment][transitAccess]; purposeLogsums[Global.Settings.Purposes.PersonalBusiness] = Global.AggregateLogsums[household.ResidenceZoneId][Global.Settings.Purposes.PersonalBusiness][carOwnership][votSegment][transitAccess]; purposeLogsums[Global.Settings.Purposes.Shopping] = Global.AggregateLogsums[household.ResidenceZoneId][Global.Settings.Purposes.Shopping][carOwnership][votSegment][transitAccess]; purposeLogsums[Global.Settings.Purposes.Meal] = Global.AggregateLogsums[household.ResidenceZoneId][Global.Settings.Purposes.Meal][carOwnership][votSegment][transitAccess]; purposeLogsums[Global.Settings.Purposes.Social] = Global.AggregateLogsums[household.ResidenceZoneId][Global.Settings.Purposes.Social][carOwnership][votSegment][transitAccess]; purposeLogsums[Global.Settings.Purposes.Recreation] = compositeLogsum; purposeLogsums[Global.Settings.Purposes.Medical] = compositeLogsum; for (int xPurpose = Global.Settings.Purposes.Work; xPurpose <= Global.Settings.Purposes.Social + 10; xPurpose++) { // extra components 1-5 are for 2,3,4,5,6 tour purposes // extra components 6-10 are for 2,3,4,5,6 stop puroposes // recode purpose to match coefficients int purpose = xPurpose <= Global.Settings.Purposes.Social ? xPurpose : xPurpose <= Global.Settings.Purposes.Social + 5 ? Global.Settings.Purposes.Social + 1 : Global.Settings.Purposes.Social + 2; // get correct multiplier on coefficients. double xMultiplier = xPurpose <= Global.Settings.Purposes.Social ? 1.0 : xPurpose <= Global.Settings.Purposes.Social + 5 ? Math.Log(xPurpose - Global.Settings.Purposes.Social + 1) : Math.Log(xPurpose - Global.Settings.Purposes.Social - 5 + 1); choiceProbabilityCalculator.CreateUtilityComponent(xPurpose); ChoiceProbabilityCalculator.Component component = choiceProbabilityCalculator.GetUtilityComponent(xPurpose); component.AddUtilityTerm(100 * purpose + 51, xMultiplier * person.IsFulltimeWorker.ToFlag()); component.AddUtilityTerm(100 * purpose + 2, xMultiplier * person.IsPartTimeWorker.ToFlag()); component.AddUtilityTerm(100 * purpose + 3, xMultiplier * person.IsRetiredAdult.ToFlag()); component.AddUtilityTerm(100 * purpose + 4, xMultiplier * person.IsNonworkingAdult.ToFlag()); component.AddUtilityTerm(100 * purpose + 5, xMultiplier * person.IsUniversityStudent.ToFlag()); component.AddUtilityTerm(100 * purpose + 6, xMultiplier * person.IsDrivingAgeStudent.ToFlag()); component.AddUtilityTerm(100 * purpose + 7, xMultiplier * person.IsChildAge5Through15.ToFlag()); component.AddUtilityTerm(100 * purpose + 8, xMultiplier * person.IsChildUnder5.ToFlag()); component.AddUtilityTerm(100 * purpose + 9, xMultiplier * household.Has0To25KIncome.ToFlag()); component.AddUtilityTerm(100 * purpose + 10, xMultiplier * household.Has25To45KIncome.ToFlag()); component.AddUtilityTerm(100 * purpose + 11, xMultiplier * household.Has75KPlusIncome.ToFlag()); component.AddUtilityTerm(100 * purpose + 12, xMultiplier * carsPerDriver); component.AddUtilityTerm(100 * purpose + 13, xMultiplier * person.IsOnlyAdult().ToFlag()); component.AddUtilityTerm(100 * purpose + 14, xMultiplier * person.IsOnlyFullOrPartTimeWorker().ToFlag()); component.AddUtilityTerm(100 * purpose + 15, xMultiplier * 0); component.AddUtilityTerm(100 * purpose + 16, xMultiplier * person.IsFemale.ToFlag() * person.IsAdult.ToFlag() * (!household.HasChildrenUnder16).ToFlag()); component.AddUtilityTerm(100 * purpose + 17, xMultiplier * person.IsFemale.ToFlag() * person.IsAdult.ToFlag() * household.HasChildrenUnder5.ToFlag()); component.AddUtilityTerm(100 * purpose + 18, xMultiplier * person.IsFemale.ToFlag() * person.IsAdult.ToFlag() * household.HasChildrenAge5Through15.ToFlag()); component.AddUtilityTerm(100 * purpose + 19, xMultiplier * person.IsMale.ToFlag() * person.IsAdult.ToFlag() * household.HasChildrenUnder5.ToFlag()); component.AddUtilityTerm(100 * purpose + 20, xMultiplier * person.IsMale.ToFlag() * person.IsAdult.ToFlag() * household.HasChildrenAge5Through15.ToFlag()); component.AddUtilityTerm(100 * purpose + 21, xMultiplier * person.AgeIsBetween18And25.ToFlag()); component.AddUtilityTerm(100 * purpose + 22, xMultiplier * person.AgeIsBetween26And35.ToFlag()); component.AddUtilityTerm(100 * purpose + 23, xMultiplier * person.AgeIsBetween51And65.ToFlag()); component.AddUtilityTerm(100 * purpose + 24, xMultiplier * person.WorksAtHome().ToFlag()); component.AddUtilityTerm(100 * purpose + 25, xMultiplier * mixedDensity); component.AddUtilityTerm(100 * purpose + 26, xMultiplier * intersectionDensity); component.AddUtilityTerm(100 * purpose + 27, xMultiplier * purposeLogsums[purpose]); component.AddUtilityTerm(100 * purpose + 28, xMultiplier * person.TransitPassOwnership); } // tour utility int tourComponentIndex = Global.Settings.Purposes.Social + 11; choiceProbabilityCalculator.CreateUtilityComponent(tourComponentIndex); ChoiceProbabilityCalculator.Component tourComponent = choiceProbabilityCalculator.GetUtilityComponent(tourComponentIndex); tourComponent.AddUtilityTerm(1401, carsPerDriver); tourComponent.AddUtilityTerm(1402, person.WorksAtHome().ToFlag()); tourComponent.AddUtilityTerm(1403, mixedDensity); tourComponent.AddUtilityTerm(1404, mixedDensity * person.IsChildAge5Through15.ToFlag()); tourComponent.AddUtilityTerm(1405, compositeLogsum); tourComponent.AddUtilityTerm(1406, person.TransitPassOwnership); // stop utility int stopComponentIndex = Global.Settings.Purposes.Social + 12; choiceProbabilityCalculator.CreateUtilityComponent(stopComponentIndex); ChoiceProbabilityCalculator.Component stopComponent = choiceProbabilityCalculator.GetUtilityComponent(stopComponentIndex); stopComponent.AddUtilityTerm(1411, carsPerDriver); stopComponent.AddUtilityTerm(1412, person.WorksAtHome().ToFlag()); stopComponent.AddUtilityTerm(1413, mixedDensity); stopComponent.AddUtilityTerm(1414, mixedDensity * person.IsChildAge5Through15.ToFlag()); stopComponent.AddUtilityTerm(1415, compositeLogsum); stopComponent.AddUtilityTerm(1416, person.TransitPassOwnership); for (int alternativeIndex = 0; alternativeIndex < TOTAL_ALTERNATIVES; alternativeIndex++) { DayPattern dayPattern = _dayPatterns[alternativeIndex]; bool available = // work tours and stops only available for workers (person.IsWorker || (dayPattern.WorkTours <= 0 && dayPattern.WorkStops <= 0)) && // school tours and stops only available for students with usual school parcel not at home ((person.IsStudent && person.UsualSchoolParcel != null && person.UsualSchoolParcel != person.Household.ResidenceParcel) || (dayPattern.SchoolTours <= 0 && dayPattern.SchoolStops <= 0)) && // school stops not available if usual school parcel is same as usual work parcel ((person.IsStudent && person.UsualSchoolParcel != null && person.UsualSchoolParcel != person.UsualWorkParcel) || (dayPattern.SchoolStops <= 0)); ChoiceProbabilityCalculator.Alternative alternative = choiceProbabilityCalculator.GetAlternative(alternativeIndex, available, choice != null && choice.Equals(dayPattern)); if (!Global.Configuration.IsInEstimationMode && !alternative.Available) { continue; } alternative.Choice = dayPattern; // components for the purposes for (int purpose = Global.Settings.Purposes.Work; purpose <= Global.Settings.Purposes.Social; purpose++) { if (dayPattern.Tours[purpose] > 0 || dayPattern.Stops[purpose] > 0) { alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(purpose)); if (dayPattern.Tours[purpose] > 0) { alternative.AddUtilityTerm(100 * purpose, 1); // tour purpose ASC alternative.AddUtilityTerm(100 * purpose + 29, purposeLogsums[purpose]); // tour purpose logsum alternative.AddUtilityTerm(100 * purpose + 30, person.PaidParkingAtWorkplace); // only use for work purpose } if (dayPattern.Stops[purpose] > 0) { alternative.AddUtilityTerm(100 * purpose + 1, 1); // stop purpose ASC alternative.AddUtilityTerm(100 * purpose + 31, purposeLogsums[purpose]); // stop purpose logsum } if (Global.Configuration.IsInEstimationMode) { alternative.AddUtilityTerm(100 * purpose + 32, 1 - person.PaperDiary); alternative.AddUtilityTerm(100 * purpose + 33, person.ProxyResponse); } } } // multiple tour purposes component if (dayPattern.TotalTours > 1) { alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(Global.Settings.Purposes.Social + (dayPattern.TotalTours - 1))); } // multiple stop purposes component if (dayPattern.TotalStops > 1) { alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(Global.Settings.Purposes.Social + 5 + (dayPattern.TotalStops - 1))); } for (int tourPurpose = Global.Settings.Purposes.Work; tourPurpose <= Global.Settings.Purposes.Social; tourPurpose++) { for (int stopPurpose = Global.Settings.Purposes.Work; stopPurpose <= Global.Settings.Purposes.Social - 1; stopPurpose++) { if (tourPurpose > Global.Settings.Purposes.School && stopPurpose <= Global.Settings.Purposes.School) { continue; } if (dayPattern.Tours[tourPurpose] > 0 && dayPattern.Stops[stopPurpose] > 0) { alternative.AddUtilityTerm(1000 + 10 * tourPurpose + stopPurpose, 1); // tour-stop comb. utility } } } for (int tourPurpose = Global.Settings.Purposes.Work; tourPurpose <= Global.Settings.Purposes.School; tourPurpose++) { if (dayPattern.Tours[tourPurpose] == 1 && dayPattern.TotalStops >= 1) { alternative.AddUtilityTerm(1000 + 10 * tourPurpose, purposeLogsums[tourPurpose]); // usual location logsum x presence of stops in work or school pattern alternative.AddUtilityTerm(1000 + 10 * tourPurpose + 8, compositeLogsum); // home aggregate logsum x presence of stops in work or school pattern alternative.AddUtilityTerm(1000 + 10 * tourPurpose + 9, atUsualLogsums[tourPurpose]); // at usual location aggregate logsum x presence of stops in work or school pattern } } for (int tourPurpose = Global.Settings.Purposes.Work; tourPurpose <= Global.Settings.Purposes.Social - 2; tourPurpose++) { for (int tourPurpose2 = tourPurpose + 1; tourPurpose2 <= Global.Settings.Purposes.Social; tourPurpose2++) { if (dayPattern.Tours[tourPurpose] > 0 && dayPattern.Tours[tourPurpose2] > 0) { alternative.AddUtilityTerm(1100 + 10 * tourPurpose + tourPurpose2, 1); // tour-tour comb. utility } } } for (int stopPurpose = Global.Settings.Purposes.Work; stopPurpose <= Global.Settings.Purposes.Social - 2; stopPurpose++) { for (int stopPurpose2 = stopPurpose + 1; stopPurpose2 <= Global.Settings.Purposes.Social; stopPurpose2++) { if (dayPattern.Stops[stopPurpose] > 0 && dayPattern.Stops[stopPurpose2] > 0) { alternative.AddUtilityTerm(1200 + 10 * stopPurpose + stopPurpose2, 1); // stop-stop comb. utility } } } if (dayPattern.TotalTours > 0 && dayPattern.TotalStops > 0) { int totalStops = dayPattern.TotalStops; if (totalStops > 3) { totalStops = 3; } alternative.AddUtilityTerm(1300 + 10 * dayPattern.TotalTours + totalStops, 1); // nttour-ntstop utility } if (dayPattern.TotalTours - dayPattern.Tours[Global.Settings.Purposes.Work] - dayPattern.Tours[Global.Settings.Purposes.School] > 0) { // tour utility alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(tourComponentIndex)); } if (dayPattern.TotalStops - dayPattern.Stops[Global.Settings.Purposes.Work] - dayPattern.Stops[Global.Settings.Purposes.School] > 0) { // stop utility alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(stopComponentIndex)); } } }
public void Add(DayPattern dayPattern) { Shifts[Shifts.Count] = dayPattern ?? new DayPattern(); }
public void Run(PersonDayWrapper personDay, HouseholdDayWrapper householdDay) { DayPattern[] dayPatterns = new DayPattern[TOTAL_ALTERNATIVES]; if (householdDay.Household.Id == 80170 && personDay.Person.Sequence == 1) { bool testbreak = true; } if (personDay == null) { throw new ArgumentNullException("personDay"); } personDay.ResetRandom(948); if (Global.Configuration.IsInEstimationMode) { if (Global.Configuration.EstimationModel != CHOICE_MODEL_NAME) { DayPattern dayPattern = new DayPattern(personDay); if (dayPattern.EscortTours > 0 && personDay.CreatedEscortTours == 0) { personDay.CreatedEscortTours++; } if (dayPattern.PersonalBusinessTours > 0 && personDay.CreatedPersonalBusinessTours == 0) { personDay.CreatedPersonalBusinessTours++; } if (dayPattern.ShoppingTours > 0 && personDay.CreatedShoppingTours == 0) { personDay.CreatedShoppingTours++; } if (dayPattern.SocialTours > 0 && personDay.CreatedSocialTours == 0) { personDay.CreatedSocialTours++; } return; } } InitializeDayPatterns(personDay, dayPatterns); var choiceProbabilityCalculator = _helpers[ParallelUtility.threadLocalAssignedIndex.Value].GetChoiceProbabilityCalculator(personDay.Person.Id * 10 + personDay.Day); if (_helpers[ParallelUtility.threadLocalAssignedIndex.Value].ModelIsInEstimationMode) { DayPattern dayPattern = new DayPattern(personDay); RunModel(choiceProbabilityCalculator, personDay, householdDay, dayPatterns, dayPattern); if (dayPattern.EscortTours > 0 && personDay.CreatedEscortTours == 0) { personDay.CreatedEscortTours++; } if (dayPattern.PersonalBusinessTours > 0 && personDay.CreatedPersonalBusinessTours == 0) { personDay.CreatedPersonalBusinessTours++; } if (dayPattern.ShoppingTours > 0 && personDay.CreatedShoppingTours == 0) { personDay.CreatedShoppingTours++; } if (dayPattern.SocialTours > 0 && personDay.CreatedSocialTours == 0) { personDay.CreatedSocialTours++; } choiceProbabilityCalculator.WriteObservation(); } else { if (personDay.Person.UsualWorkParcelId != Global.Settings.OutOfRegionParcelId && personDay.Person.UsualSchoolParcelId != Global.Settings.OutOfRegionParcelId) { RunModel(choiceProbabilityCalculator, personDay, householdDay, dayPatterns); var chosenAlternative = choiceProbabilityCalculator.SimulateChoice(personDay.Household.RandomUtility); if (chosenAlternative == null) { personDay.IsValid = false; householdDay.IsValid = false; return; } var dayPattern = (DayPattern)chosenAlternative.Choice; if (dayPattern.EscortTours > 0 && personDay.CreatedEscortTours == 0) { personDay.GetNewTour(Global.Settings.AddressTypes.Home, personDay.Household.ResidenceParcelId, personDay.Household.ResidenceZoneKey, Global.Settings.Purposes.Escort); personDay.CreatedEscortTours++; } if (dayPattern.PersonalBusinessTours > 0 && personDay.CreatedPersonalBusinessTours == 0) { personDay.GetNewTour(Global.Settings.AddressTypes.Home, personDay.Household.ResidenceParcelId, personDay.Household.ResidenceZoneKey, Global.Settings.Purposes.PersonalBusiness); personDay.CreatedPersonalBusinessTours++; } if (dayPattern.ShoppingTours > 0 && personDay.CreatedShoppingTours == 0) { personDay.GetNewTour(Global.Settings.AddressTypes.Home, personDay.Household.ResidenceParcelId, personDay.Household.ResidenceZoneKey, Global.Settings.Purposes.Shopping); personDay.CreatedShoppingTours++; } if (dayPattern.SocialTours > 0 && personDay.CreatedSocialTours == 0) { personDay.GetNewTour(Global.Settings.AddressTypes.Home, personDay.Household.ResidenceParcelId, personDay.Household.ResidenceZoneKey, Global.Settings.Purposes.Social); personDay.CreatedSocialTours++; } personDay.EscortStops = dayPattern.EscortStops; personDay.PersonalBusinessStops = dayPattern.PersonalBusinessStops; personDay.ShoppingStops = dayPattern.ShoppingStops; personDay.SocialStops = dayPattern.SocialStops; } } }
private void RunModel(ChoiceProbabilityCalculator choiceProbabilityCalculator, PersonDayWrapper personDay, HouseholdDayWrapper householdDay, DayPattern[] dayPatterns, DayPattern choice = null) { var household = personDay.Household; var residenceParcel = household.ResidenceParcel; var person = personDay.Person; var carsPerDriver = household.GetCarsPerDriver(); var mixedDensity = residenceParcel.MixedUse3Index2(); var intersectionDensity = residenceParcel.IntersectionDensity34Minus1Buffer2(); var purposeLogsums = new double[Global.Settings.Purposes.TotalPurposes + 2]; var atUsualLogsums = new double[3]; //var carOwnership = person.CarOwnershipSegment; //GV: sat car ownership not to impact logsums var carOwnership = 0; var votSegment = person.Household.GetVotALSegment(); var transitAccess = residenceParcel.TransitAccessSegment(); //GV: input 26. july 2013 // household inputs //var childrenUnder5 = householdTotals.ChildrenUnder5; //var childrenAge5Through15 = householdTotals.ChildrenAge5Through15; //var nonworkingAdults = householdTotals.NonworkingAdults; //var retiredAdults = householdTotals.RetiredAdults; var onePersonHouseholdFlag = household.IsOnePersonHousehold.ToFlag(); var twoPersonHouseholdFlag = household.IsTwoPersonHousehold.ToFlag(); var householdCars = household.VehiclesAvailable; //var noCarsInHouseholdFlag = HouseholdWrapper.GetNoCarsInHouseholdFlag(householdCars); //var carsLessThanDriversFlag = household.GetCarsLessThanDriversFlag(householdCars); //var carsLessThanWorkersFlag = household.GetCarsLessThanWorkersFlag(householdCars); var HHwithChildrenFlag = household.HasChildren.ToFlag(); var HHwithSmallChildrenFlag = household.HasChildrenUnder5.ToFlag(); var HHwithLowIncomeFlag = (household.Income >= 300000 && household.Income < 600000).ToFlag(); var HHwithMidleIncomeFlag = (household.Income >= 600000 && household.Income < 900000).ToFlag(); var HHwithHighIncomeFlag = (household.Income >= 900000).ToFlag(); var primaryFamilyTimeFlag = householdDay.PrimaryPriorityTimeFlag; //GV: input 26. july 2013 // person inputs var partTimeWorkerFlag = person.IsPartTimeWorker.ToFlag(); var nonworkingAdultFlag = person.IsNonworkingAdult.ToFlag(); var universityStudentFlag = person.IsUniversityStudent.ToFlag(); var retiredAdultFlag = person.IsRetiredAdult.ToFlag(); var fullTimeWorkerFlag = person.IsFulltimeWorker.ToFlag(); var childAge5Through15Flag = person.IsChildAge5Through15.ToFlag(); var childUnder5Flag = person.IsChildUnder5.ToFlag(); var adultFlag = person.IsAdult.ToFlag(); var maleFlag = person.IsMale.ToFlag(); var femaleFlag = person.IsFemale.ToFlag(); if (person.UsualWorkParcel == null || person.UsualWorkParcelId == household.ResidenceParcelId) { purposeLogsums[Global.Settings.Purposes.Work] = 0; } else { var destinationArrivalTime = ChoiceModelUtility.GetDestinationArrivalTime(Global.Settings.Models.WorkTourModeModel); var destinationDepartureTime = ChoiceModelUtility.GetDestinationDepartureTime(Global.Settings.Models.WorkTourModeModel); //JLB 201406 //var nestedAlternative = Global.ChoiceModelSession.Get<WorkTourModeModel>().RunNested(personDay, residenceParcel, person.UsualWorkParcel, destinationArrivalTime, destinationDepartureTime, household.VehiclesAvailable); var nestedAlternative = Global.ChoiceModelSession.Get <WorkTourModeTimeModel>().RunNested(personDay, residenceParcel, person.UsualWorkParcel, destinationArrivalTime, destinationDepartureTime, household.VehiclesAvailable); purposeLogsums[Global.Settings.Purposes.Work] = nestedAlternative == null ? 0 : nestedAlternative.ComputeLogsum(); atUsualLogsums[Global.Settings.Purposes.Work] = Global.AggregateLogsums[person.UsualWorkParcel.ZoneId][Global.Settings.Purposes.HomeBasedComposite][carOwnership][votSegment][person.UsualWorkParcel.TransitAccessSegment()]; } if (person.UsualSchoolParcel == null || person.UsualSchoolParcelId == household.ResidenceParcelId) { purposeLogsums[Global.Settings.Purposes.School] = 0; } else { var destinationArrivalTime = ChoiceModelUtility.GetDestinationArrivalTime(Global.Settings.Models.SchoolTourModeModel); var destinationDepartureTime = ChoiceModelUtility.GetDestinationDepartureTime(Global.Settings.Models.SchoolTourModeModel); //JLB 201406 //var nestedAlternative = Global.ChoiceModelSession.Get<SchoolTourModeModel>().RunNested(personDay, residenceParcel, person.UsualSchoolParcel, destinationArrivalTime, destinationDepartureTime, household.VehiclesAvailable); var nestedAlternative = Global.ChoiceModelSession.Get <SchoolTourModeTimeModel>().RunNested(personDay, residenceParcel, person.UsualSchoolParcel, destinationArrivalTime, destinationDepartureTime, household.VehiclesAvailable); purposeLogsums[Global.Settings.Purposes.School] = nestedAlternative == null ? 0 : nestedAlternative.ComputeLogsum(); atUsualLogsums[Global.Settings.Purposes.School] = Global.AggregateLogsums[person.UsualSchoolParcel.ZoneId][Global.Settings.Purposes.HomeBasedComposite][carOwnership][votSegment][person.UsualSchoolParcel.TransitAccessSegment()]; } var compositeLogsum = Global.AggregateLogsums[household.ResidenceZoneId][Global.Settings.Purposes.HomeBasedComposite][carOwnership][votSegment][transitAccess]; purposeLogsums[Global.Settings.Purposes.Escort] = Global.AggregateLogsums[household.ResidenceZoneId][Global.Settings.Purposes.Escort][carOwnership][votSegment][transitAccess]; purposeLogsums[Global.Settings.Purposes.PersonalBusiness] = Global.AggregateLogsums[household.ResidenceZoneId][Global.Settings.Purposes.PersonalBusiness][carOwnership][votSegment][transitAccess]; purposeLogsums[Global.Settings.Purposes.Shopping] = Global.AggregateLogsums[household.ResidenceZoneId][Global.Settings.Purposes.Shopping][carOwnership][votSegment][transitAccess]; purposeLogsums[Global.Settings.Purposes.Social] = Global.AggregateLogsums[household.ResidenceZoneId][Global.Settings.Purposes.Social][carOwnership][votSegment][transitAccess]; for (var xPurpose = Global.Settings.Purposes.Escort; xPurpose <= Global.Settings.Purposes.Social + 10; xPurpose++) { // extra components 1-5 are for 2,3,4,5,6 tour purposes // extra components 6-10 are for 2,3,4,5,6 stop puroposes // recode purpose to match coefficients var purpose = xPurpose <= Global.Settings.Purposes.Social ? xPurpose : xPurpose <= Global.Settings.Purposes.Social + 5 ? Global.Settings.Purposes.Social + 1 : Global.Settings.Purposes.Social + 2; // get correct multiplier on coefficients. var xMultiplier = xPurpose <= Global.Settings.Purposes.Social ? 1.0 : xPurpose <= Global.Settings.Purposes.Social + 5 ? Math.Log(xPurpose - Global.Settings.Purposes.Social + 1) : Math.Log(xPurpose - Global.Settings.Purposes.Social - 5 + 1); choiceProbabilityCalculator.CreateUtilityComponent(xPurpose); var component = choiceProbabilityCalculator.GetUtilityComponent(xPurpose); component.AddUtilityTerm(100 * purpose + 1, xMultiplier * person.IsFulltimeWorker.ToFlag()); component.AddUtilityTerm(100 * purpose + 2, xMultiplier * person.IsPartTimeWorker.ToFlag()); component.AddUtilityTerm(100 * purpose + 3, xMultiplier * person.IsRetiredAdult.ToFlag()); component.AddUtilityTerm(100 * purpose + 4, xMultiplier * person.IsNonworkingAdult.ToFlag()); component.AddUtilityTerm(100 * purpose + 5, xMultiplier * person.IsUniversityStudent.ToFlag()); component.AddUtilityTerm(100 * purpose + 6, xMultiplier * person.IsDrivingAgeStudent.ToFlag()); component.AddUtilityTerm(100 * purpose + 7, xMultiplier * person.IsChildAge5Through15.ToFlag()); component.AddUtilityTerm(100 * purpose + 8, xMultiplier * person.IsChildUnder5.ToFlag()); component.AddUtilityTerm(100 * purpose + 9, xMultiplier * HHwithLowIncomeFlag); component.AddUtilityTerm(100 * purpose + 10, xMultiplier * HHwithMidleIncomeFlag); component.AddUtilityTerm(100 * purpose + 11, xMultiplier * HHwithHighIncomeFlag); //component.AddUtilityTerm(100 * purpose + 12, xMultiplier * carsPerDriver); component.AddUtilityTerm(100 * purpose + 12, xMultiplier * householdCars); component.AddUtilityTerm(100 * purpose + 13, xMultiplier * person.IsOnlyAdult().ToFlag()); component.AddUtilityTerm(100 * purpose + 14, xMultiplier * person.IsOnlyFullOrPartTimeWorker().ToFlag()); component.AddUtilityTerm(100 * purpose + 15, xMultiplier * 0); component.AddUtilityTerm(100 * purpose + 16, xMultiplier * person.IsFemale.ToFlag() * person.IsAdult.ToFlag() * (!household.HasChildrenUnder16).ToFlag()); component.AddUtilityTerm(100 * purpose + 17, xMultiplier * person.IsFemale.ToFlag() * person.IsAdult.ToFlag() * household.HasChildrenUnder5.ToFlag()); component.AddUtilityTerm(100 * purpose + 18, xMultiplier * person.IsFemale.ToFlag() * person.IsAdult.ToFlag() * household.HasChildrenAge5Through15.ToFlag()); component.AddUtilityTerm(100 * purpose + 19, xMultiplier * person.IsMale.ToFlag() * person.IsAdult.ToFlag() * household.HasChildrenUnder5.ToFlag()); component.AddUtilityTerm(100 * purpose + 20, xMultiplier * person.IsMale.ToFlag() * person.IsAdult.ToFlag() * household.HasChildrenAge5Through15.ToFlag()); //component.AddUtilityTerm(100 * purpose + 21, xMultiplier * primaryFamilyTimeFlag); //GV: wrong sign //component.AddUtilityTerm(100 * purpose + 21, xMultiplier * person.AgeIsBetween18And25.ToFlag()); //component.AddUtilityTerm(100 * purpose + 22, xMultiplier * person.AgeIsBetween26And35.ToFlag()); //component.AddUtilityTerm(100 * purpose + 23, xMultiplier * person.AgeIsBetween51And65.ToFlag()); component.AddUtilityTerm(100 * purpose + 24, xMultiplier * person.WorksAtHome.ToFlag()); component.AddUtilityTerm(100 * purpose + 25, xMultiplier * mixedDensity); component.AddUtilityTerm(100 * purpose + 26, xMultiplier * intersectionDensity); //component.AddUtilityTerm(100 * purpose + 27, xMultiplier * purposeLogsums[purpose]); //GV: 17.08.2013, the logsums are wrong //component.AddUtilityTerm(100 * purpose + 28, xMultiplier * person.TransitPassOwnershipFlag); } // tour utility const int tourComponentIndex = 18; choiceProbabilityCalculator.CreateUtilityComponent(tourComponentIndex); var tourComponent = choiceProbabilityCalculator.GetUtilityComponent(tourComponentIndex); //tourComponent.AddUtilityTerm(1701, carsPerDriver); tourComponent.AddUtilityTerm(1701, householdCars); tourComponent.AddUtilityTerm(1702, person.WorksAtHome.ToFlag()); tourComponent.AddUtilityTerm(1703, mixedDensity); tourComponent.AddUtilityTerm(1704, mixedDensity * person.IsChildAge5Through15.ToFlag()); tourComponent.AddUtilityTerm(1705, compositeLogsum); //tourComponent.AddUtilityTerm(1706, person.TransitPassOwnershipFlag); tourComponent.AddUtilityTerm(1706, primaryFamilyTimeFlag); // stop utility const int stopComponentIndex = 19; choiceProbabilityCalculator.CreateUtilityComponent(stopComponentIndex); var stopComponent = choiceProbabilityCalculator.GetUtilityComponent(stopComponentIndex); //stopComponent.AddUtilityTerm(1711, carsPerDriver); stopComponent.AddUtilityTerm(1711, householdCars); stopComponent.AddUtilityTerm(1712, person.WorksAtHome.ToFlag()); stopComponent.AddUtilityTerm(1713, mixedDensity); stopComponent.AddUtilityTerm(1714, mixedDensity * person.IsChildAge5Through15.ToFlag()); stopComponent.AddUtilityTerm(1715, compositeLogsum); //stopComponent.AddUtilityTerm(1716, person.TransitPassOwnershipFlag); //stopComponent.AddUtilityTerm(1716, primaryFamilyTimeFlag); //GV: 17.08.2013, the logsums are wrong for (var alternativeIndex = 0; alternativeIndex < TOTAL_ALTERNATIVES; alternativeIndex++) { var dayPattern = dayPatterns[alternativeIndex]; var available = dayPattern.Available; var alternative = choiceProbabilityCalculator.GetAlternative(alternativeIndex, available, choice != null && choice.Equals(dayPattern)); if (!Global.Configuration.IsInEstimationMode && !alternative.Available) { continue; } alternative.Choice = dayPattern; // components for the purposes for (var purpose = Global.Settings.Purposes.Escort; purpose <= Global.Settings.Purposes.Social; purpose++) { if (dayPattern.Tours[purpose] > 0 || dayPattern.Stops[purpose] > 0) { alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(purpose)); if (dayPattern.Tours[purpose] > 0) { alternative.AddUtilityTerm(100 * purpose + 50, 1); // tour purpose ASC //alternative.AddUtilityTerm(100 * purpose + 51, purposeLogsums[purpose]); // tour purpose logsum GV: 17.08.2013, the logsums are wrong } if (dayPattern.Stops[purpose] > 0) { alternative.AddUtilityTerm(100 * purpose + 60, 1); // stop purpose ASC //alternative.AddUtilityTerm(100 * purpose + 61, purposeLogsums[purpose]); // stop purpose logsum GV: 17.08.2013, the logsums are wrong } if (Global.Configuration.IsInEstimationMode) { //GV commented out //alternative.AddUtilityTerm(100 * purpose + 70, 1 - person.PaperDiary); //GV commented out //alternative.AddUtilityTerm(100 * purpose + 71, person.ProxyResponse); } } } // multiple tour purposes component if (dayPattern.TotalTourPurposes > 1) { alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(Global.Settings.Purposes.Social + (dayPattern.TotalTourPurposes - 1))); } // multiple stop purposes component if (dayPattern.TotalStopPurposes > 1) { alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(Global.Settings.Purposes.Social + 5 + (dayPattern.TotalStopPurposes - 1))); } for (var tourPurpose = Global.Settings.Purposes.Work; tourPurpose <= Global.Settings.Purposes.Social; tourPurpose++) { for (var stopPurpose = Global.Settings.Purposes.Work; stopPurpose <= Global.Settings.Purposes.Social - 1; stopPurpose++) { if (tourPurpose > Global.Settings.Purposes.School && stopPurpose <= Global.Settings.Purposes.School) { continue; } if (dayPattern.Tours[tourPurpose] > 0 && dayPattern.Stops[stopPurpose] > 0) { alternative.AddUtilityTerm(1200 + 10 * tourPurpose + stopPurpose, 1); // tour-stop comb. utility } } } for (var tourPurpose = Global.Settings.Purposes.Work; tourPurpose <= Global.Settings.Purposes.School; tourPurpose++) { if (dayPattern.Tours[tourPurpose] == 1 && dayPattern.TotalStopPurposes >= 1) { alternative.AddUtilityTerm(1300 + 10 * tourPurpose, purposeLogsums[tourPurpose]); // usual location logsum x presence of stops in work or school pattern alternative.AddUtilityTerm(1300 + 10 * tourPurpose + 1, compositeLogsum); // home aggregate logsum x presence of stops in work or school pattern //alternative.AddUtilityTerm(1300 + 10 * tourPurpose + 2, atUsualLogsums[tourPurpose]); // at usual location aggregate logsum x presence of stops in work or school pattern GV: commented out as the sign is wrong } } for (var tourPurpose = Global.Settings.Purposes.Work; tourPurpose <= Global.Settings.Purposes.Social - 2; tourPurpose++) { for (var tourPurpose2 = tourPurpose + 1; tourPurpose2 <= Global.Settings.Purposes.Social; tourPurpose2++) { if (dayPattern.Tours[tourPurpose] > 0 && dayPattern.Tours[tourPurpose2] > 0) { alternative.AddUtilityTerm(1400 + 10 * tourPurpose + tourPurpose2, 1); // tour-tour comb. utility } } } for (var tourPurpose = Global.Settings.Purposes.Business; tourPurpose <= Global.Settings.Purposes.Business; tourPurpose++) { for (var tourPurpose2 = Global.Settings.Purposes.Escort; tourPurpose2 <= Global.Settings.Purposes.Social; tourPurpose2++) { if (dayPattern.Tours[tourPurpose] > 0 && dayPattern.Tours[tourPurpose2] > 0) { alternative.AddUtilityTerm(1461, 1); // tour-tour comb. utility for business combos } } } for (var stopPurpose = Global.Settings.Purposes.Work; stopPurpose <= Global.Settings.Purposes.Social - 2; stopPurpose++) { for (var stopPurpose2 = stopPurpose + 1; stopPurpose2 <= Global.Settings.Purposes.Social; stopPurpose2++) { if (dayPattern.Stops[stopPurpose] > 0 && dayPattern.Stops[stopPurpose2] > 0) { alternative.AddUtilityTerm(1500 + 10 * stopPurpose + stopPurpose2, 1); // stop-stop comb. utility } } } if (dayPattern.TotalTourPurposes > 0 && dayPattern.TotalStopPurposes > 0) { var totalStopPurposes = dayPattern.TotalStopPurposes; if (totalStopPurposes > 3) { totalStopPurposes = 3; } alternative.AddUtilityTerm(1600 + 10 * dayPattern.TotalTourPurposes + totalStopPurposes, 1); // nttour-ntstop utility } if (dayPattern.TotalTourPurposes - dayPattern.Tours[Global.Settings.Purposes.Work] - dayPattern.Tours[Global.Settings.Purposes.Business] - dayPattern.Tours[Global.Settings.Purposes.School] > 0) { // tour utility alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(tourComponentIndex)); } if (dayPattern.TotalStopPurposes - dayPattern.Stops[Global.Settings.Purposes.Work] - dayPattern.Stops[Global.Settings.Purposes.Business] - dayPattern.Stops[Global.Settings.Purposes.School] > 0) { // stop utility alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(stopComponentIndex)); } } }
private void InitializeDayPatterns(PersonDayWrapper personDay, DayPattern[] dayPatterns) { // if (_dayPatterns != null) { // return; // } var workTours = personDay.WorkTours > 0 ? 1 : 0; var schoolTours = personDay.SchoolTours > 0 ? 1 : 0; var businessTours = personDay.BusinessTours > 0 ? 1 : 0; var workStops = personDay.WorkStops > 0 ? 1 : 0; var schoolStops = personDay.SchoolStops > 0 ? 1 : 0; var businessStops = personDay.BusinessStops > 0 ? 1 : 0; var priorEscortTours = (personDay.EscortFullHalfTours > 0 || personDay.EscortJointTours > 0) ? 1 : 0; var priorPersonalBusinessTours = personDay.PersonalBusinessJointTours > 0 ? 1 : 0; var priorShoppingTours = personDay.ShoppingJointTours > 0 ? 1 : 0; var priorSocialTours = personDay.SocialJointTours > 0 ? 1 : 0; var alternativeIndex = -1; for (var escortTours = 0; escortTours <= 1; escortTours++) { for (var personalBusinessTours = 0; personalBusinessTours <= 1; personalBusinessTours++) { for (var shoppingTours = 0; shoppingTours <= 1; shoppingTours++) { for (var socialTours = 0; socialTours <= 1; socialTours++) { for (var escortStops = 0; escortStops <= 1; escortStops++) { for (var personalBusinessStops = 0; personalBusinessStops <= 1; personalBusinessStops++) { for (var shoppingStops = 0; shoppingStops <= 1; shoppingStops++) { for (var socialStops = 0; socialStops <= 1; socialStops++) { var totalNonMandatoryTourPurposes = escortTours + personalBusinessTours + shoppingTours + socialTours; var totalNonMandatoryStopPurposes = escortStops + personalBusinessStops + shoppingStops + socialStops; var totalTourPurposes = totalNonMandatoryTourPurposes + workTours + schoolTours + businessTours; var totalStopPurposes = totalNonMandatoryStopPurposes + workStops + schoolStops + businessStops; // checks for: // three tours or less // four stops or less // five stops total or less if (totalNonMandatoryTourPurposes > 3 || totalNonMandatoryStopPurposes > 4 || totalNonMandatoryTourPurposes + totalNonMandatoryStopPurposes > 5) { continue; } alternativeIndex++; // next alternative var tours = new int[Global.Settings.Purposes.TotalPurposes]; tours[Global.Settings.Purposes.Work] = workTours; tours[Global.Settings.Purposes.School] = schoolTours; tours[Global.Settings.Purposes.Business] = businessTours; tours[Global.Settings.Purposes.Escort] = escortTours; tours[Global.Settings.Purposes.PersonalBusiness] = personalBusinessTours; tours[Global.Settings.Purposes.Shopping] = shoppingTours; tours[Global.Settings.Purposes.Social] = socialTours; var stops = new int[Global.Settings.Purposes.TotalPurposes]; stops[Global.Settings.Purposes.Work] = workStops; stops[Global.Settings.Purposes.School] = schoolStops; stops[Global.Settings.Purposes.Business] = businessStops; stops[Global.Settings.Purposes.Escort] = escortStops; stops[Global.Settings.Purposes.PersonalBusiness] = personalBusinessStops; stops[Global.Settings.Purposes.Shopping] = shoppingStops; stops[Global.Settings.Purposes.Social] = socialStops; bool available = totalNonMandatoryStopPurposes > 0 && totalTourPurposes == 0 ? false : priorEscortTours > 0 && escortTours == 0 ? false : priorPersonalBusinessTours > 0 && personalBusinessTours == 0 ? false : priorShoppingTours > 0 && shoppingTours == 0 ? false : priorSocialTours > 0 && socialTours == 0 ? false : totalTourPurposes > 3 || totalStopPurposes > 4 || totalTourPurposes + totalStopPurposes > 5 ? false : Math.Min(totalStopPurposes, 1) > totalTourPurposes ? false : true; dayPatterns[alternativeIndex] = new DayPattern(tours, totalTourPurposes, stops, totalStopPurposes, available); } } } } } } } } }