Exemplo n.º 1
0
        private void RunModel(ChoiceProbabilityCalculator choiceProbabilityCalculator, ITripWrapper trip, TripTime choice = null)
        {
            IPersonWrapper    person    = trip.Person;
            IPersonDayWrapper personDay = trip.PersonDay;
            ITourWrapper      tour      = trip.Tour;

            // person inputs
            int partTimeWorkerFlag     = person.IsPartTimeWorker.ToFlag();
            int nonworkingAdultFlag    = person.IsNonworkingAdult.ToFlag();
            int universityStudentFlag  = person.IsUniversityStudent.ToFlag();
            int retiredAdultFlag       = person.IsRetiredAdult.ToFlag();
            int drivingAgeStudentFlag  = person.IsDrivingAgeStudent.ToFlag();
            int childAge5Through15Flag = person.IsChildAge5Through15.ToFlag();
            int childUnder5Flag        = person.IsChildUnder5.ToFlag();

            // set tour inputs
            int workTourFlag         = tour.IsWorkPurpose().ToFlag();
            int notWorkTourFlag      = (!tour.IsWorkPurpose()).ToFlag();
            int notHomeBasedTourFlag = (!tour.IsHomeBasedTour).ToFlag();

            // set trip inputs
            bool originChangeMode            = trip.Sequence > 1 && trip.GetPreviousTrip().DestinationPurpose == Global.Settings.Purposes.ChangeMode;
            int  originWorkFlag              = trip.IsWorkOriginPurpose().ToFlag();
            int  originSchoolFlag            = trip.IsSchoolOriginPurpose().ToFlag();
            int  originEscortFlag            = trip.IsEscortOriginPurpose().ToFlag();
            int  originShoppingFlag          = trip.IsShoppingOriginPurpose().ToFlag();
            int  originPersonalBusinessFlag  = trip.IsPersonalBusinessOriginPurpose().ToFlag();
            int  originMealFlag              = trip.IsMealOriginPurpose().ToFlag();
            int  originSocialFlag            = trip.IsSocialOriginPurpose().ToFlag();
            int  sovOrHovTripFlag            = trip.UsesSovOrHovModes().ToFlag();
            int  transitTripFlag             = trip.IsTransitMode().ToFlag();
            int  halfTourFromOriginFlag      = trip.IsHalfTourFromOrigin.ToFlag();
            int  halfTourFromDestinationFlag = (!trip.IsHalfTourFromOrigin).ToFlag();

            // set remaining inputs
            ITimeWindow timeWindow = tour.IsHomeBasedTour ? personDay.TimeWindow : tour.ParentTour.TimeWindow;

            ITripModeImpedance[] impedances = trip.GetTripModeImpedances();
            int remainingToursCount         = personDay.HomeBasedTours - personDay.GetTotalSimulatedTours();
            int tripRemainingInHalfTour     = (trip.DestinationParcel != null && trip.DestinationParcel != tour.OriginParcel).ToFlag(); // we don't know exact #

            for (int arrivalPeriodIndex = 1; arrivalPeriodIndex < DayPeriod.SmallDayPeriods.Length; arrivalPeriodIndex++)
            {
                MinuteSpan arrivalPeriod       = DayPeriod.SmallDayPeriods[arrivalPeriodIndex];
                int        previousArrivalTime = trip.GetPreviousTrip().ArrivalTime;

                if (previousArrivalTime < arrivalPeriod.Start || previousArrivalTime > arrivalPeriod.End)
                {
                    continue;
                }
                ITripModeImpedance arrivalImpedance = impedances[arrivalPeriod.Index]; // moved to here so not reset for every alternative

                foreach (TripTime time in TripTime.Times)
                {
                    MinuteSpan         departurePeriod    = time.DeparturePeriod; // moved to here so can use travel time
                    ITripModeImpedance departureImpedance = impedances[departurePeriod.Index];

                    // change availability check to include travel duration
                    int travelDuration = (int)Math.Round(departureImpedance.TravelTime + 0.5);

                    // if not the trip home, on a home-based tour, also include fastest time from the destinatinon to home
                    //                    if (trip.Tour.IsHomeBasedTour && trip.DestinationPurpose != Global.Settings.Purposes.NoneOrHome) {
                    //                        var fastestMode = Math.Min(trip.Tour.Mode, Global.Settings.Modes.Hov3);
                    //                         var pathTypeModel = PathTypeModelFactory.Singleton.Run(trip.DestinationParcel, trip.Household.ResidenceParcel, departurePeriod.Middle, 0,
                    //                               trip.Tour.DestinationPurpose, trip.Tour.CostCoefficient, trip.Tour.TimeCoefficient,
                    //                                trip.Person.IsDrivingAge, trip.Household.VehiclesAvailable, trip.Tour.Person.TransitFareDiscountFraction, false, fastestMode).First();
                    //                        travelDuration += (int) Math.Round(pathTypeModel.PathTime + 0.5);
                    //                    }

                    int bestArrivalTime
                        = trip.IsHalfTourFromOrigin
                              ? Math.Max(departurePeriod.End - travelDuration, 1)
                              : Math.Min(departurePeriod.Start + travelDuration, Global.Settings.Times.MinutesInADay);

                    bool available =
                        originChangeMode
                            ? arrivalPeriod.Index == time.DeparturePeriod.Index
                            : (trip.IsHalfTourFromOrigin && // if change mode, must be in same period
                               arrivalPeriod.Index > departurePeriod.Index &&
                               timeWindow.EntireSpanIsAvailable(bestArrivalTime, arrivalPeriod.Start - 1)) ||
                        (!trip.IsHalfTourFromOrigin &&
                         arrivalPeriod.Index < departurePeriod.Index &&
                         timeWindow.EntireSpanIsAvailable(arrivalPeriod.End, bestArrivalTime - 1)) ||
                        arrivalPeriod.Index == time.DeparturePeriod.Index &&
                        timeWindow.TotalAvailableMinutes(arrivalPeriod.Start, arrivalPeriod.End) > travelDuration;

                    double departurePeriodFraction = timeWindow.TotalAvailableMinutes(departurePeriod.Start, departurePeriod.End) / (departurePeriod.End - departurePeriod.Start + 1D);
                    int    duration = Math.Abs(departurePeriod.Middle - arrivalPeriod.Middle);

                    available = available && departurePeriodFraction > 0;

                    //ensure transit path type is available in alternative
                    if (trip.Mode == Global.Settings.Modes.Transit && !Global.StopAreaIsEnabled)
                    {
                        double transitPathTypeInVehicleTime = ImpedanceRoster.GetValue("ivtime", trip.Mode, trip.PathType, trip.ValueOfTime, time.DeparturePeriod.Middle, trip.OriginParcel.ZoneId, trip.DestinationParcel.ZoneId).Variable;
                        available = available && (transitPathTypeInVehicleTime > 0);
                    }

                    ChoiceProbabilityCalculator.Alternative alternative = choiceProbabilityCalculator.GetAlternative(time.Index, available, choice != null && choice.Equals(time));

                    //                    if (choice.Equals(tripTime) && !available) {
                    //                        Console.WriteLine(available);
                    //                    }

                    if (!alternative.Available)
                    {
                        continue;
                    }

                    alternative.Choice = time;

                    double departurePeriodShift = time.DeparturePeriod.Index * (48.0 / DayPeriod.SMALL_DAY_PERIOD_TOTAL_TRIP_TIMES); //adjust shift amount if period lengths change

                    if (trip.IsHalfTourFromOrigin)
                    {
                        // outbound "departure" (arrival) period constants
                        alternative.AddUtilityTerm(11, time.DeparturePeriod.Middle.IsBetween(Global.Settings.Times.ThreeAM, Global.Settings.Times.SixAM).ToFlag());
                        alternative.AddUtilityTerm(12, time.DeparturePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.SixAM, Global.Settings.Times.SevenAM).ToFlag());
                        alternative.AddUtilityTerm(13, time.DeparturePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.SevenAM, Global.Settings.Times.EightAM).ToFlag());
                        alternative.AddUtilityTerm(14, time.DeparturePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.EightAM, Global.Settings.Times.NineAM).ToFlag());
                        alternative.AddUtilityTerm(15, time.DeparturePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.NineAM, Global.Settings.Times.TenAM).ToFlag());
                        alternative.AddUtilityTerm(16, time.DeparturePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.TenAM, Global.Settings.Times.OnePM).ToFlag());
                        alternative.AddUtilityTerm(17, time.DeparturePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.OnePM, Global.Settings.Times.FourPM).ToFlag());
                        alternative.AddUtilityTerm(18, time.DeparturePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.FourPM, Global.Settings.Times.SevenPM).ToFlag());
                        alternative.AddUtilityTerm(19, time.DeparturePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.SevenPM, Global.Settings.Times.TenPM).ToFlag());
                        alternative.AddUtilityTerm(20, time.DeparturePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.TenPM, Global.Settings.Times.MinutesInADay).ToFlag());
                    }
                    else
                    {
                        // return departure period constants
                        alternative.AddUtilityTerm(21, time.DeparturePeriod.Middle.IsBetween(Global.Settings.Times.ThreeAM, Global.Settings.Times.SevenAM).ToFlag());
                        alternative.AddUtilityTerm(22, time.DeparturePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.SevenAM, Global.Settings.Times.TenAM).ToFlag());
                        alternative.AddUtilityTerm(23, time.DeparturePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.TenAM, Global.Settings.Times.OnePM).ToFlag());
                        alternative.AddUtilityTerm(24, time.DeparturePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.OnePM, Global.Settings.Times.ThreePM).ToFlag());
                        alternative.AddUtilityTerm(124, time.DeparturePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.ThreePM, Global.Settings.Times.FourPM).ToFlag());
                        alternative.AddUtilityTerm(25, time.DeparturePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.FourPM, Global.Settings.Times.FivePM).ToFlag());
                        alternative.AddUtilityTerm(26, time.DeparturePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.FivePM, Global.Settings.Times.SixPM).ToFlag());
                        alternative.AddUtilityTerm(27, time.DeparturePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.SixPM, Global.Settings.Times.SevenPM).ToFlag());
                        alternative.AddUtilityTerm(28, time.DeparturePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.SevenPM, Global.Settings.Times.NinePM).ToFlag());
                        alternative.AddUtilityTerm(29, time.DeparturePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.NinePM, Global.Settings.Times.Midnight).ToFlag());
                        alternative.AddUtilityTerm(30, time.DeparturePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.Midnight, Global.Settings.Times.MinutesInADay).ToFlag());
                    }

                    alternative.AddUtilityTerm(31, duration.IsRightExclusiveBetween(Global.Settings.Times.ZeroHours, Global.Settings.Times.OneHour).ToFlag());           // 0 - 1
                    alternative.AddUtilityTerm(32, duration.IsRightExclusiveBetween(Global.Settings.Times.OneHour, Global.Settings.Times.TwoHours).ToFlag());            // 1 - 2
                    alternative.AddUtilityTerm(33, duration.IsRightExclusiveBetween(Global.Settings.Times.TwoHours, Global.Settings.Times.ThreeHours).ToFlag());         // 2 - 3
                    alternative.AddUtilityTerm(34, duration.IsRightExclusiveBetween(Global.Settings.Times.ThreeHours, Global.Settings.Times.FiveHours).ToFlag());        // 3 - 5
                    alternative.AddUtilityTerm(35, duration.IsRightExclusiveBetween(Global.Settings.Times.FiveHours, Global.Settings.Times.SevenHours).ToFlag());        // 5 - 7
                    alternative.AddUtilityTerm(36, duration.IsRightExclusiveBetween(Global.Settings.Times.SevenHours, Global.Settings.Times.NineHours).ToFlag());        // 7 - 9
                    alternative.AddUtilityTerm(37, duration.IsRightExclusiveBetween(Global.Settings.Times.NineHours, Global.Settings.Times.TwelveHours).ToFlag());       // 9 - 12
                    alternative.AddUtilityTerm(38, duration.IsRightExclusiveBetween(Global.Settings.Times.TwelveHours, Global.Settings.Times.FourteenHours).ToFlag());   // 12 - 14
                    alternative.AddUtilityTerm(39, duration.IsRightExclusiveBetween(Global.Settings.Times.FourteenHours, Global.Settings.Times.EighteenHours).ToFlag()); // 14 - 18
                    alternative.AddUtilityTerm(40, (duration >= Global.Settings.Times.EighteenHours).ToFlag());                                                          // 18 - 24

                    //these were duplicate departure shift variables before, and constrained to 0 in all the coefficient files - replaced by duration shifts
                    alternative.AddUtilityTerm(41, partTimeWorkerFlag * duration);
                    alternative.AddUtilityTerm(43, nonworkingAdultFlag * duration);
                    alternative.AddUtilityTerm(45, universityStudentFlag * duration);
                    alternative.AddUtilityTerm(47, retiredAdultFlag * duration);
                    alternative.AddUtilityTerm(49, drivingAgeStudentFlag * duration);
                    alternative.AddUtilityTerm(51, childAge5Through15Flag * duration);
                    alternative.AddUtilityTerm(53, childUnder5Flag * duration);
                    alternative.AddUtilityTerm(55, halfTourFromOriginFlag * duration);
                    alternative.AddUtilityTerm(131, workTourFlag * halfTourFromOriginFlag * duration);
                    alternative.AddUtilityTerm(133, workTourFlag * halfTourFromDestinationFlag * duration);
                    alternative.AddUtilityTerm(135, notWorkTourFlag * halfTourFromDestinationFlag * duration);
                    alternative.AddUtilityTerm(137, notHomeBasedTourFlag * duration);
                    alternative.AddUtilityTerm(145, originEscortFlag * duration);
                    alternative.AddUtilityTerm(147, originShoppingFlag * duration);
                    alternative.AddUtilityTerm(149, originMealFlag * duration);
                    alternative.AddUtilityTerm(151, originSocialFlag * duration);
                    alternative.AddUtilityTerm(153, originPersonalBusinessFlag * duration);
                    alternative.AddUtilityTerm(155, originSchoolFlag * duration);

                    alternative.AddUtilityTerm(42, partTimeWorkerFlag * departurePeriodShift);
                    alternative.AddUtilityTerm(44, nonworkingAdultFlag * departurePeriodShift);
                    alternative.AddUtilityTerm(46, universityStudentFlag * departurePeriodShift);
                    alternative.AddUtilityTerm(48, retiredAdultFlag * departurePeriodShift);
                    alternative.AddUtilityTerm(50, drivingAgeStudentFlag * departurePeriodShift);
                    alternative.AddUtilityTerm(52, childAge5Through15Flag * departurePeriodShift);
                    alternative.AddUtilityTerm(54, childUnder5Flag * departurePeriodShift);
                    alternative.AddUtilityTerm(56, halfTourFromOriginFlag * departurePeriodShift);
                    alternative.AddUtilityTerm(132, workTourFlag * halfTourFromOriginFlag * departurePeriodShift);
                    alternative.AddUtilityTerm(134, workTourFlag * halfTourFromDestinationFlag * departurePeriodShift);
                    alternative.AddUtilityTerm(136, notWorkTourFlag * halfTourFromDestinationFlag * departurePeriodShift);
                    alternative.AddUtilityTerm(138, notHomeBasedTourFlag * departurePeriodShift);
                    alternative.AddUtilityTerm(146, originEscortFlag * departurePeriodShift);
                    alternative.AddUtilityTerm(148, originShoppingFlag * departurePeriodShift);
                    alternative.AddUtilityTerm(150, originMealFlag * departurePeriodShift);
                    alternative.AddUtilityTerm(152, originSocialFlag * departurePeriodShift);
                    alternative.AddUtilityTerm(154, originPersonalBusinessFlag * departurePeriodShift);
                    alternative.AddUtilityTerm(156, originSchoolFlag * departurePeriodShift);

                    alternative.AddUtilityTerm(86, sovOrHovTripFlag * Math.Max(departureImpedance.GeneralizedTime, 0) * tour.TimeCoefficient);
                    alternative.AddUtilityTerm(88, transitTripFlag * Math.Max(departureImpedance.GeneralizedTime, 0) * tour.TimeCoefficient);
                    alternative.AddUtilityTerm(89, transitTripFlag * (departureImpedance.GeneralizedTime < 0).ToFlag());
                    alternative.AddUtilityTerm(92, halfTourFromOriginFlag * Math.Log(departurePeriodFraction));
                    alternative.AddUtilityTerm(92, halfTourFromDestinationFlag * Math.Log(departurePeriodFraction));
                    alternative.AddUtilityTerm(99, tripRemainingInHalfTour / (1D + halfTourFromOriginFlag * departureImpedance.AdjacentMinutesBefore + halfTourFromDestinationFlag * departureImpedance.AdjacentMinutesAfter));
                    alternative.AddUtilityTerm(97, remainingToursCount / (1D + halfTourFromOriginFlag * (arrivalImpedance.TotalMinutesAfter + departureImpedance.TotalMinutesBefore) + halfTourFromDestinationFlag * (arrivalImpedance.TotalMinutesBefore + departureImpedance.TotalMinutesAfter)));
                    alternative.AddUtilityTerm(98, remainingToursCount / (1D + halfTourFromOriginFlag * Math.Max(arrivalImpedance.MaxMinutesBefore, departureImpedance.MaxMinutesBefore) + halfTourFromDestinationFlag * Math.Max(arrivalImpedance.MaxMinutesBefore, departureImpedance.MaxMinutesAfter)));
                }
            }
        }
Exemplo n.º 2
0
        private void RunModel(ChoiceProbabilityCalculator choiceProbabilityCalculator, ITourWrapper tour, TourTime choice = null)
        {
            IHouseholdWrapper household = tour.Household;
            IPersonWrapper    person    = tour.Person;
            IPersonDayWrapper personDay = tour.PersonDay;

            // household inputs
            int income0To25KFlag   = household.Has0To25KIncome.ToFlag();
            int income100KPlusFlag = household.Has100KPlusIncome.ToFlag();

            // person inputs
            int partTimeWorkerFlag     = person.IsPartTimeWorker.ToFlag();
            int nonworkingAdultFlag    = person.IsNonworkingAdult.ToFlag();
            int universityStudentFlag  = person.IsUniversityStudent.ToFlag();
            int retiredAdultFlag       = person.IsRetiredAdult.ToFlag();
            int drivingAgeStudentFlag  = person.IsDrivingAgeStudent.ToFlag();
            int fulltimeWorkerFlag     = person.IsFulltimeWorker.ToFlag();
            int childAge5Through15Flag = person.IsChildAge5Through15.ToFlag();
            int childUnder5Flag        = person.IsChildUnder5.ToFlag();

            // person-day inputs
            int homeBasedToursOnlyFlag          = personDay.OnlyHomeBasedToursExist().ToFlag();
            int firstSimulatedHomeBasedTourFlag = personDay.IsFirstSimulatedHomeBasedTour().ToFlag();
            int laterSimulatedHomeBasedTourFlag = personDay.IsLaterSimulatedHomeBasedTour().ToFlag();
            int totalStopPurposes       = personDay.GetTotalStopPurposes(); // JLB 20150401 changed from GetTotalStops to assure consistent definition in apply and estimate
            int totalSimulatedStops     = personDay.GetTotalSimulatedStops();
            int escortStops             = personDay.EscortStops;
            int homeBasedTours          = personDay.HomeBasedTours;
            int simulatedHomeBasedTours = personDay.SimulatedHomeBasedTours;

            // tour inputs
            int escortTourFlag           = tour.IsEscortPurpose().ToFlag();
            int shoppingTourFlag         = tour.IsShoppingPurpose().ToFlag();
            int mealTourFlag             = tour.IsMealPurpose().ToFlag();
            int socialTourFlag           = tour.IsSocialPurpose().ToFlag();
            int personalBusinessTourFlag = tour.IsPersonalBusinessPurpose().ToFlag();

            int sovOrHovTourFlag = tour.IsAnAutoMode().ToFlag();
            int transitTourFlag  = tour.UsesTransitModes().ToFlag();

            // remaining inputs
            // Higher priority tour of 2+ tours for the same purpose
            int highPrioritySameFlag = (tour.GetTotalToursByPurpose() > tour.GetTotalSimulatedToursByPurpose() && tour.GetTotalSimulatedToursByPurpose() == 1).ToFlag();

            // Lower priority tour(s) of 2+ tours for the same purpose
            int lowPrioritySameFlag = (tour.GetTotalSimulatedToursByPurpose() > 1).ToFlag();

            // Higher priority tour of 2+ tours for different purposes
            int highPriorityDifferentFlag = (personDay.IsFirstSimulatedHomeBasedTour() && personDay.HomeBasedToursExist()).ToFlag() * (1 - highPrioritySameFlag);

            // Lower priority tour of 2+ tours for different purposes
            int lowPriorityDifferentFlag = (personDay.IsLaterSimulatedHomeBasedTour() && personDay.HomeBasedToursExist()).ToFlag() * (1 - lowPrioritySameFlag);

            ITimeWindow timeWindow = tour.ParentTour == null ? personDay.TimeWindow : tour.ParentTour.TimeWindow;

            ITourModeImpedance[] impedances = tour.GetTourModeImpedances();
            int period1Middle    = 15;
            int smallPeriodCount = DayPeriod.SmallDayPeriods.Count();

            for (int periodIndex = 0; periodIndex < smallPeriodCount; periodIndex++)
            {
                // set arrival period component
                int                arrivalPeriodIndex            = periodIndex;
                double             arrivalPeriodShift            = arrivalPeriodIndex * (48.0 / DayPeriod.SMALL_DAY_PERIOD_TOTAL_TRIP_TIMES); //adjust shift amount if period lengths change
                MinuteSpan         arrivalPeriod                 = DayPeriod.SmallDayPeriods[arrivalPeriodIndex];
                int                earlyArriveFlag               = arrivalPeriod.Middle.IsBetween(Global.Settings.Times.ThreeAM, Global.Settings.Times.SevenAM).ToFlag();
                ITourModeImpedance arrivalImpedance              = impedances[arrivalPeriodIndex];
                int                arrivalPeriodAvailableMinutes = timeWindow.TotalAvailableMinutes(arrivalPeriod.Start, arrivalPeriod.End);

                choiceProbabilityCalculator.CreateUtilityComponent(3 * periodIndex + 0);
                ChoiceProbabilityCalculator.Component arrivalComponent = choiceProbabilityCalculator.GetUtilityComponent(3 * periodIndex + 0);

                if (arrivalPeriodAvailableMinutes > 0 || Global.Configuration.IsInEstimationMode)
                {
                    arrivalComponent.AddUtilityTerm(11, arrivalPeriod.Middle.IsBetween(Global.Settings.Times.ThreeAM, Global.Settings.Times.SixAM).ToFlag());
                    arrivalComponent.AddUtilityTerm(12, arrivalPeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.SixAM, Global.Settings.Times.SevenAM).ToFlag());
                    arrivalComponent.AddUtilityTerm(13, arrivalPeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.SevenAM, Global.Settings.Times.EightAM).ToFlag());
                    arrivalComponent.AddUtilityTerm(14, arrivalPeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.EightAM, Global.Settings.Times.NineAM).ToFlag());
                    arrivalComponent.AddUtilityTerm(15, arrivalPeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.NineAM, Global.Settings.Times.TenAM).ToFlag());
                    arrivalComponent.AddUtilityTerm(16, arrivalPeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.TenAM, Global.Settings.Times.OnePM).ToFlag());
                    arrivalComponent.AddUtilityTerm(17, arrivalPeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.OnePM, Global.Settings.Times.FourPM).ToFlag());
                    arrivalComponent.AddUtilityTerm(18, arrivalPeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.FourPM, Global.Settings.Times.SevenPM).ToFlag());
                    arrivalComponent.AddUtilityTerm(19, arrivalPeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.SevenPM, Global.Settings.Times.TenPM).ToFlag());
                    arrivalComponent.AddUtilityTerm(20, arrivalPeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.TenPM, Global.Settings.Times.MinutesInADay).ToFlag());
                    arrivalComponent.AddUtilityTerm(41, partTimeWorkerFlag * arrivalPeriodShift);
                    arrivalComponent.AddUtilityTerm(43, nonworkingAdultFlag * arrivalPeriodShift);
                    arrivalComponent.AddUtilityTerm(45, universityStudentFlag * arrivalPeriodShift);
                    arrivalComponent.AddUtilityTerm(47, retiredAdultFlag * arrivalPeriodShift);
                    arrivalComponent.AddUtilityTerm(49, drivingAgeStudentFlag * arrivalPeriodShift);
                    arrivalComponent.AddUtilityTerm(139, fulltimeWorkerFlag * arrivalPeriodShift);
                    arrivalComponent.AddUtilityTerm(141, childAge5Through15Flag * arrivalPeriodShift);
                    arrivalComponent.AddUtilityTerm(143, childUnder5Flag * arrivalPeriodShift);
                    arrivalComponent.AddUtilityTerm(145, escortTourFlag * arrivalPeriodShift);
                    arrivalComponent.AddUtilityTerm(147, shoppingTourFlag * arrivalPeriodShift);
                    arrivalComponent.AddUtilityTerm(149, mealTourFlag * arrivalPeriodShift);
                    arrivalComponent.AddUtilityTerm(151, socialTourFlag * arrivalPeriodShift);
                    arrivalComponent.AddUtilityTerm(153, personalBusinessTourFlag * arrivalPeriodShift);
                    arrivalComponent.AddUtilityTerm(51, income0To25KFlag * arrivalPeriodShift);
                    arrivalComponent.AddUtilityTerm(53, income100KPlusFlag * arrivalPeriodShift);
                    arrivalComponent.AddUtilityTerm(55, highPrioritySameFlag * arrivalPeriodShift);
                    arrivalComponent.AddUtilityTerm(57, lowPrioritySameFlag * arrivalPeriodShift);
                    arrivalComponent.AddUtilityTerm(155, highPriorityDifferentFlag * arrivalPeriodShift);
                    arrivalComponent.AddUtilityTerm(157, lowPriorityDifferentFlag * arrivalPeriodShift);
                    arrivalComponent.AddUtilityTerm(59, homeBasedToursOnlyFlag * arrivalPeriodShift);
                    arrivalComponent.AddUtilityTerm(61, totalStopPurposes * homeBasedToursOnlyFlag * arrivalPeriodShift);
                    arrivalComponent.AddUtilityTerm(63, totalStopPurposes * (1 - homeBasedToursOnlyFlag) * arrivalPeriodShift);
                    arrivalComponent.AddUtilityTerm(65, (Math.Max(totalStopPurposes - totalSimulatedStops, 0)) * (1 - homeBasedToursOnlyFlag) * arrivalPeriodShift);
                    arrivalComponent.AddUtilityTerm(67, escortStops * arrivalPeriodShift);
                    arrivalComponent.AddUtilityTerm(69, tour.TotalSubtours * arrivalPeriodShift);
                    arrivalComponent.AddUtilityTerm(72, income100KPlusFlag * earlyArriveFlag);
                    arrivalComponent.AddUtilityTerm(175, escortTourFlag * earlyArriveFlag);
                    arrivalComponent.AddUtilityTerm(176, shoppingTourFlag * earlyArriveFlag);
                    arrivalComponent.AddUtilityTerm(177, mealTourFlag * earlyArriveFlag);
                    arrivalComponent.AddUtilityTerm(85, sovOrHovTourFlag * arrivalImpedance.GeneralizedTimeFromOrigin * tour.TimeCoefficient);
                    arrivalComponent.AddUtilityTerm(87, transitTourFlag * Math.Max(0, arrivalImpedance.GeneralizedTimeFromOrigin) * tour.TimeCoefficient);
                    arrivalComponent.AddUtilityTerm(89, transitTourFlag * (arrivalImpedance.GeneralizedTimeFromOrigin < 0).ToFlag());
                    arrivalComponent.AddUtilityTerm(91, Math.Log(Math.Max(1, arrivalPeriodAvailableMinutes)));
                    arrivalComponent.AddUtilityTerm(93, arrivalImpedance.AdjacentMinutesBefore * firstSimulatedHomeBasedTourFlag);
                    arrivalComponent.AddUtilityTerm(95, arrivalImpedance.AdjacentMinutesBefore * laterSimulatedHomeBasedTourFlag);
                    arrivalComponent.AddUtilityTerm(99, (Math.Max(totalStopPurposes - totalSimulatedStops, 0)) / (1D + arrivalImpedance.AdjacentMinutesBefore));
                }

                // set departure period component
                int                departurePeriodIndex            = periodIndex;
                double             departurePeriodShift            = departurePeriodIndex * (48.0 / DayPeriod.SMALL_DAY_PERIOD_TOTAL_TRIP_TIMES); //adjust shift amount if period lengths change
                MinuteSpan         departurePeriod                 = DayPeriod.SmallDayPeriods[departurePeriodIndex];
                int                lateDepartFlag                  = departurePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.NinePM, Global.Settings.Times.MinutesInADay).ToFlag();
                ITourModeImpedance departureImpedance              = impedances[departurePeriodIndex];
                int                departurePeriodAvailableMinutes = timeWindow.TotalAvailableMinutes(departurePeriod.Start, departurePeriod.End);

                choiceProbabilityCalculator.CreateUtilityComponent(3 * periodIndex + 1);
                ChoiceProbabilityCalculator.Component departureComponent = choiceProbabilityCalculator.GetUtilityComponent(3 * periodIndex + 1);

                if (departurePeriodAvailableMinutes > 0 || Global.Configuration.IsInEstimationMode)
                {
                    departureComponent.AddUtilityTerm(21, departurePeriod.Middle.IsBetween(Global.Settings.Times.ThreeAM, Global.Settings.Times.SevenAM).ToFlag());
                    departureComponent.AddUtilityTerm(22, departurePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.SevenAM, Global.Settings.Times.TenAM).ToFlag());
                    departureComponent.AddUtilityTerm(23, departurePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.TenAM, Global.Settings.Times.OnePM).ToFlag());
                    departureComponent.AddUtilityTerm(24, departurePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.OnePM, Global.Settings.Times.ThreePM).ToFlag());
                    departureComponent.AddUtilityTerm(124, departurePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.ThreePM, Global.Settings.Times.FourPM).ToFlag());
                    departureComponent.AddUtilityTerm(25, departurePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.FourPM, Global.Settings.Times.FivePM).ToFlag());
                    departureComponent.AddUtilityTerm(26, departurePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.FivePM, Global.Settings.Times.SixPM).ToFlag());
                    departureComponent.AddUtilityTerm(27, departurePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.SixPM, Global.Settings.Times.SevenPM).ToFlag());
                    departureComponent.AddUtilityTerm(28, departurePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.SevenPM, Global.Settings.Times.NinePM).ToFlag());
                    departureComponent.AddUtilityTerm(29, departurePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.NinePM, Global.Settings.Times.Midnight).ToFlag());
                    departureComponent.AddUtilityTerm(30, departurePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.Midnight, Global.Settings.Times.MinutesInADay).ToFlag());
                    //added
                    departureComponent.AddUtilityTerm(136, transitTourFlag * departurePeriodShift);
                    departureComponent.AddUtilityTerm(137, transitTourFlag * lateDepartFlag);
                    //
                    departureComponent.AddUtilityTerm(73, income100KPlusFlag * lateDepartFlag);
                    departureComponent.AddUtilityTerm(178, escortTourFlag * lateDepartFlag);
                    departureComponent.AddUtilityTerm(179, shoppingTourFlag * lateDepartFlag);
                    departureComponent.AddUtilityTerm(180, mealTourFlag * lateDepartFlag);
                    departureComponent.AddUtilityTerm(86, sovOrHovTourFlag * departureImpedance.GeneralizedTimeFromDestination * tour.TimeCoefficient);
                    departureComponent.AddUtilityTerm(88, transitTourFlag * Math.Max(0, departureImpedance.GeneralizedTimeFromDestination) * tour.TimeCoefficient);
                    departureComponent.AddUtilityTerm(89, transitTourFlag * (departureImpedance.GeneralizedTimeFromDestination < 0).ToFlag());
                    departureComponent.AddUtilityTerm(92, Math.Log(Math.Max(1, departurePeriodAvailableMinutes)));
                    departureComponent.AddUtilityTerm(94, departureImpedance.AdjacentMinutesAfter * firstSimulatedHomeBasedTourFlag);
                    departureComponent.AddUtilityTerm(96, departureImpedance.AdjacentMinutesAfter * laterSimulatedHomeBasedTourFlag);
                    departureComponent.AddUtilityTerm(100, (Math.Max(totalStopPurposes - totalSimulatedStops, 0)) / (1D + departureImpedance.AdjacentMinutesAfter));
                }

                // set duration component (relative to period 1)
                double periodSpan = periodIndex * (48.0 / DayPeriod.SMALL_DAY_PERIOD_TOTAL_TRIP_TIMES); //adjust shift amount if period lengths change;
                if (arrivalPeriodIndex == 0)
                {
                    period1Middle = arrivalPeriod.Middle;
                }
                int duration = departurePeriod.Middle - period1Middle;
                int durationUnder1HourFlag  = ChoiceModelUtility.GetDurationUnder1HourFlag(duration);
                int duration1To2HoursFlag   = ChoiceModelUtility.GetDuration1To2HoursFlag(duration);
                int durationUnder4HoursFlag = ChoiceModelUtility.GetDurationUnder4HoursFlag(duration);
                int durationUnder8HoursFlag = ChoiceModelUtility.GetDurationUnder8HoursFlag(duration);
                int durationUnder9HoursFlag = ChoiceModelUtility.GetDurationUnder9HoursFlag(duration);

                choiceProbabilityCalculator.CreateUtilityComponent(3 * periodIndex + 2);
                ChoiceProbabilityCalculator.Component durationComponent = choiceProbabilityCalculator.GetUtilityComponent(3 * periodIndex + 2);

                if (tour.IsWorkPurpose() || tour.IsSchoolPurpose())
                {
                    durationComponent.AddUtilityTerm(31, duration.IsRightExclusiveBetween(Global.Settings.Times.ZeroHours, Global.Settings.Times.ThreeHours).ToFlag());
                    durationComponent.AddUtilityTerm(32, duration.IsRightExclusiveBetween(Global.Settings.Times.ThreeHours, Global.Settings.Times.FiveHours).ToFlag());
                    durationComponent.AddUtilityTerm(33, duration.IsRightExclusiveBetween(Global.Settings.Times.FiveHours, Global.Settings.Times.SevenHours).ToFlag());
                    durationComponent.AddUtilityTerm(34, duration.IsRightExclusiveBetween(Global.Settings.Times.SevenHours, Global.Settings.Times.NineHours).ToFlag());
                    durationComponent.AddUtilityTerm(35, duration.IsRightExclusiveBetween(Global.Settings.Times.NineHours, Global.Settings.Times.TenHours).ToFlag());
                    durationComponent.AddUtilityTerm(36, duration.IsRightExclusiveBetween(Global.Settings.Times.TenHours, Global.Settings.Times.ElevenHours).ToFlag());
                    durationComponent.AddUtilityTerm(37, duration.IsRightExclusiveBetween(Global.Settings.Times.ElevenHours, Global.Settings.Times.TwelveHours).ToFlag());
                    durationComponent.AddUtilityTerm(38, duration.IsRightExclusiveBetween(Global.Settings.Times.TwelveHours, Global.Settings.Times.FourteenHours).ToFlag());
                    durationComponent.AddUtilityTerm(39, duration.IsRightExclusiveBetween(Global.Settings.Times.FourteenHours, Global.Settings.Times.EighteenHours).ToFlag());
                    durationComponent.AddUtilityTerm(40, (duration >= Global.Settings.Times.EighteenHours).ToFlag());
                }
                else
                {
                    durationComponent.AddUtilityTerm(31, duration.IsRightExclusiveBetween(Global.Settings.Times.ZeroHours, Global.Settings.Times.OneHour).ToFlag());
                    durationComponent.AddUtilityTerm(32, duration.IsRightExclusiveBetween(Global.Settings.Times.OneHour, Global.Settings.Times.TwoHours).ToFlag());
                    durationComponent.AddUtilityTerm(33, duration.IsRightExclusiveBetween(Global.Settings.Times.TwoHours, Global.Settings.Times.ThreeHours).ToFlag());
                    durationComponent.AddUtilityTerm(34, duration.IsRightExclusiveBetween(Global.Settings.Times.ThreeHours, Global.Settings.Times.FiveHours).ToFlag());
                    durationComponent.AddUtilityTerm(35, duration.IsRightExclusiveBetween(Global.Settings.Times.FiveHours, Global.Settings.Times.SevenHours).ToFlag());
                    durationComponent.AddUtilityTerm(36, duration.IsRightExclusiveBetween(Global.Settings.Times.SevenHours, Global.Settings.Times.NineHours).ToFlag());
                    durationComponent.AddUtilityTerm(37, duration.IsRightExclusiveBetween(Global.Settings.Times.NineHours, Global.Settings.Times.TwelveHours).ToFlag());
                    durationComponent.AddUtilityTerm(38, duration.IsRightExclusiveBetween(Global.Settings.Times.TwelveHours, Global.Settings.Times.FourteenHours).ToFlag());
                    durationComponent.AddUtilityTerm(39, duration.IsRightExclusiveBetween(Global.Settings.Times.FourteenHours, Global.Settings.Times.EighteenHours).ToFlag());
                    durationComponent.AddUtilityTerm(40, (duration >= Global.Settings.Times.EighteenHours).ToFlag());
                }

                durationComponent.AddUtilityTerm(42, partTimeWorkerFlag * periodSpan);
                durationComponent.AddUtilityTerm(44, nonworkingAdultFlag * periodSpan);
                durationComponent.AddUtilityTerm(46, universityStudentFlag * periodSpan);
                durationComponent.AddUtilityTerm(48, retiredAdultFlag * periodSpan);
                durationComponent.AddUtilityTerm(50, drivingAgeStudentFlag * periodSpan);
                durationComponent.AddUtilityTerm(140, fulltimeWorkerFlag * periodSpan);
                durationComponent.AddUtilityTerm(142, childAge5Through15Flag * periodSpan);
                durationComponent.AddUtilityTerm(144, childUnder5Flag * periodSpan);
                durationComponent.AddUtilityTerm(146, escortTourFlag * periodSpan);
                durationComponent.AddUtilityTerm(148, shoppingTourFlag * periodSpan);
                durationComponent.AddUtilityTerm(150, mealTourFlag * periodSpan);
                durationComponent.AddUtilityTerm(152, socialTourFlag * periodSpan);
                durationComponent.AddUtilityTerm(154, personalBusinessTourFlag * periodSpan);
                durationComponent.AddUtilityTerm(52, income0To25KFlag * periodSpan);
                durationComponent.AddUtilityTerm(54, income100KPlusFlag * periodSpan);
                durationComponent.AddUtilityTerm(56, highPrioritySameFlag * periodSpan);
                durationComponent.AddUtilityTerm(58, lowPrioritySameFlag * periodSpan);
                durationComponent.AddUtilityTerm(156, highPriorityDifferentFlag * periodSpan);
                durationComponent.AddUtilityTerm(158, lowPriorityDifferentFlag * periodSpan);
                durationComponent.AddUtilityTerm(60, homeBasedToursOnlyFlag * periodSpan);
                durationComponent.AddUtilityTerm(62, totalStopPurposes * homeBasedToursOnlyFlag * periodSpan);
                durationComponent.AddUtilityTerm(64, totalStopPurposes * (1 - homeBasedToursOnlyFlag) * periodSpan);
                durationComponent.AddUtilityTerm(66, (Math.Max(totalStopPurposes - totalSimulatedStops, 0)) * (1 - homeBasedToursOnlyFlag) * periodSpan);
                durationComponent.AddUtilityTerm(68, escortStops * periodSpan);
                durationComponent.AddUtilityTerm(70, tour.TotalSubtours * periodSpan);
                durationComponent.AddUtilityTerm(71, fulltimeWorkerFlag * durationUnder9HoursFlag);
                durationComponent.AddUtilityTerm(169, escortTourFlag * durationUnder1HourFlag);
                durationComponent.AddUtilityTerm(170, shoppingTourFlag * durationUnder1HourFlag);
                durationComponent.AddUtilityTerm(171, mealTourFlag * durationUnder1HourFlag);
                durationComponent.AddUtilityTerm(172, escortTourFlag * duration1To2HoursFlag);
                durationComponent.AddUtilityTerm(173, shoppingTourFlag * duration1To2HoursFlag);
                durationComponent.AddUtilityTerm(174, mealTourFlag * duration1To2HoursFlag);
                durationComponent.AddUtilityTerm(81, highPrioritySameFlag * durationUnder8HoursFlag);
                durationComponent.AddUtilityTerm(82, lowPrioritySameFlag * durationUnder8HoursFlag);
                durationComponent.AddUtilityTerm(83, highPriorityDifferentFlag * durationUnder8HoursFlag);
                durationComponent.AddUtilityTerm(84, lowPriorityDifferentFlag * durationUnder4HoursFlag);
            }

            foreach (TourTime time in TourTime.Times)
            {
                bool available =
                    (time.ArrivalPeriod.Index < time.DeparturePeriod.Index &&
                     timeWindow.EntireSpanIsAvailable(time.ArrivalPeriod.End, time.DeparturePeriod.Start)) ||
                    (time.ArrivalPeriod.Index == time.DeparturePeriod.Index &&
                     timeWindow.TotalAvailableMinutes(time.ArrivalPeriod.Start, time.ArrivalPeriod.End) > 1);

                ChoiceProbabilityCalculator.Alternative alternative = choiceProbabilityCalculator.GetAlternative(time.Index, available, choice != null && choice.Equals(time));

                if (!alternative.Available && !Global.Configuration.IsInEstimationMode)
                {
                    continue;
                }

                int arrivalPeriodIndex = time.ArrivalPeriod.Index;
                ITourModeImpedance arrivalImpedance   = impedances[arrivalPeriodIndex];
                int departurePeriodIndex              = time.DeparturePeriod.Index;
                ITourModeImpedance departureImpedance = impedances[departurePeriodIndex];

                alternative.Choice = time;

                // arrival period utility component
                alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(3 * time.ArrivalPeriod.Index + 0));

                // departure period utility component
                alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(3 * time.DeparturePeriod.Index + 1));

                // duration utility components
                alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(3 * (time.DeparturePeriod.Index - time.ArrivalPeriod.Index) + 2));

                alternative.AddUtilityTerm(97, Math.Min(0.3, (homeBasedTours - simulatedHomeBasedTours) / (1.0 + arrivalImpedance.TotalMinutesBefore + departureImpedance.TotalMinutesAfter)));
                alternative.AddUtilityTerm(98, Math.Min(0.3, (homeBasedTours - simulatedHomeBasedTours) / (1.0 + Math.Max(arrivalImpedance.MaxMinutesBefore, departureImpedance.MaxMinutesAfter))));
            }
        }