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));
                }
            }
        }
Ejemplo n.º 6
0
 public void Add(DayPattern dayPattern)
 {
     Shifts[Shifts.Count] = dayPattern ?? new DayPattern();
 }
Ejemplo n.º 7
0
        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;
                }
            }
        }
Ejemplo n.º 8
0
        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));
                }
            }
        }
Ejemplo n.º 9
0
        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);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }