Пример #1
0
        public void Run(HouseholdDayWrapper householdDay, TripWrapper trip)
        {
            if (trip == null)
            {
                throw new ArgumentNullException("trip");
            }

            trip.PersonDay.ResetRandom(40 * (2 * trip.Tour.Sequence - 1 + trip.Direction - 1) + 50 + trip.Sequence - 1);

            if (Global.Configuration.IsInEstimationMode)
            {
                if (Global.Configuration.EstimationModel != CHOICE_MODEL_NAME)
                {
                    return;
                }
            }

            ChoiceProbabilityCalculator choiceProbabilityCalculator = _helpers[ParallelUtility.threadLocalAssignedIndex.Value].GetChoiceProbabilityCalculator(trip.Id);

            if (_helpers[ParallelUtility.threadLocalAssignedIndex.Value].ModelIsInEstimationMode)
            {
                if (trip.DestinationParcel == null || trip.OriginParcel == null || trip.Mode <= Global.Settings.Modes.None || trip.Mode > Global.Settings.Modes.WalkRideBike)
                {
                    return;
                }

                RunModel(choiceProbabilityCalculator, householdDay, trip, new HTripTime(trip.DepartureTime));

                choiceProbabilityCalculator.WriteObservation();
            }
            else
            {
                RunModel(choiceProbabilityCalculator, householdDay, trip);

                ChoiceProbabilityCalculator.Alternative chosenAlternative = choiceProbabilityCalculator.SimulateChoice(trip.Household.RandomUtility);

                if (chosenAlternative == null)
                {
                    Global.PrintFile.WriteNoAlternativesAvailableWarning(CHOICE_MODEL_NAME, "Run", trip.PersonDay.Id);
                    if (Global.Configuration.IsInEstimationMode)
                    {
                        trip.PersonDay.IsValid = false;
                    }
                    return;
                }

                HTripTime choice = (HTripTime)chosenAlternative.Choice;

                trip.DepartureTime = choice.GetRandomFeasibleMinute(trip, choice);
            }
        }
Пример #2
0
        private void RunModel(ChoiceProbabilityCalculator choiceProbabilityCalculator, IHouseholdDayWrapper householdDay, ITripWrapper trip, HTripTime choice = null)
        {
            var person    = trip.Person;
            var personDay = trip.PersonDay;
            var tour      = trip.Tour;

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

            // set tour inputs
            var workTourFlag         = tour.IsWorkPurpose().ToFlag();
            var notWorkTourFlag      = (!tour.IsWorkPurpose()).ToFlag();
            var notHomeBasedTourFlag = (!tour.IsHomeBasedTour).ToFlag();
            var jointTourFlag        = (tour.JointTourSequence > 0) ? 1 : 0;
            var partialHalfTourFlag  = (trip.IsHalfTourFromOrigin ? tour.PartialHalfTour1Sequence > 0 : tour.PartialHalfTour2Sequence > 0) ? 1 : 0;
            var fullHalfTourFlag     = (trip.IsHalfTourFromOrigin ? tour.FullHalfTour1Sequence > 0 : tour.FullHalfTour2Sequence > 0) ? 1 : 0;

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

            // set remaining inputs
            // set remaining inputs
            TimeWindow timeWindow = new TimeWindow();

            if (tour.JointTourSequence > 0)
            {
                foreach (PersonDayWrapper pDay in householdDay.PersonDays)
                {
                    var tInJoint = pDay.Tours.Find(t => t.JointTourSequence == tour.JointTourSequence);
                    if (!(tInJoint == null))
                    {
                        // set jointTour time window
                        timeWindow.IncorporateAnotherTimeWindow(tInJoint.PersonDay.TimeWindow);
                    }
                }
            }
            else if (trip.Direction == Global.Settings.TourDirections.OriginToDestination && tour.FullHalfTour1Sequence > 0)
            {
                foreach (PersonDayWrapper pDay in householdDay.PersonDays)
                {
                    var tInJoint = pDay.Tours.Find(t => t.FullHalfTour1Sequence == tour.FullHalfTour1Sequence);
                    if (!(tInJoint == null))
                    {
                        // set jointTour time window
                        timeWindow.IncorporateAnotherTimeWindow(tInJoint.PersonDay.TimeWindow);
                    }
                }
            }
            else if (trip.Direction == Global.Settings.TourDirections.DestinationToOrigin && tour.FullHalfTour2Sequence > 0)
            {
                foreach (PersonDayWrapper pDay in householdDay.PersonDays)
                {
                    var tInJoint = pDay.Tours.Find(t => t.FullHalfTour2Sequence == tour.FullHalfTour2Sequence);
                    if (!(tInJoint == null))
                    {
                        // set jointTour time window
                        timeWindow.IncorporateAnotherTimeWindow(tInJoint.PersonDay.TimeWindow);
                    }
                }
            }
            else if (tour.ParentTour == null)
            {
                timeWindow.IncorporateAnotherTimeWindow(personDay.TimeWindow);
            }
            else
            {
                timeWindow.IncorporateAnotherTimeWindow(tour.ParentTour.TimeWindow);
            }

            //set the availability and impedances for the periods
            HTripTime.SetTimeImpedances(trip);

            var remainingToursCount     = personDay.HomeBasedTours - personDay.GetTotalSimulatedTours();
            var tripRemainingInHalfTour = (trip.DestinationParcel != null && trip.DestinationParcel != tour.OriginParcel).ToFlag(); // we don't know exact #

            var previousArrivalTime = trip.IsHalfTourFromOrigin
                     ? (trip.Sequence == 1 ? tour.DestinationDepartureTime : trip.GetPreviousTrip().ArrivalTime)
                     : (trip.Sequence == 1 ? tour.DestinationArrivalTime : trip.GetPreviousTrip().ArrivalTime);

            var previousArrivalPeriod = new HTripTime(previousArrivalTime).DeparturePeriod;

            foreach (var time in HTripTime.Times[ParallelUtility.threadLocalAssignedIndex.Value])
            {
                var period = time.DeparturePeriod;

                var departurePeriodFraction = timeWindow.TotalAvailableMinutes(period.Start, period.End) / (period.End - period.Start + 1D);

                var departureShift = period.Middle / 60.0;
                var durationShift  = Math.Abs(period.Middle - previousArrivalPeriod.Middle) / 60.0;

                var available = time.Available && departurePeriodFraction > 0;

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


                if (!alternative.Available)
                {
                    continue;
                }

                alternative.Choice = time;

                var indicatedTravelTime  = (int)time.ModeLOS.PathTime;
                var indicatedArrivalTime = trip.IsHalfTourFromOrigin
                     ? Math.Max(1, period.Middle - indicatedTravelTime)
                     : Math.Min(1440, period.Middle + indicatedTravelTime);

                var totalWindowRemaining = trip.IsHalfTourFromOrigin
                     ? timeWindow.TotalAvailableMinutesBefore(indicatedArrivalTime) + timeWindow.TotalAvailableMinutesAfter(previousArrivalTime)
                     : timeWindow.TotalAvailableMinutesAfter(indicatedArrivalTime) + timeWindow.TotalAvailableMinutesBefore(previousArrivalTime);

                var maxWindowRemaining = trip.IsHalfTourFromOrigin
                     ? timeWindow.MaxAvailableMinutesBefore(indicatedArrivalTime) + timeWindow.MaxAvailableMinutesAfter(previousArrivalTime)
                     : timeWindow.MaxAvailableMinutesAfter(indicatedArrivalTime) + timeWindow.MaxAvailableMinutesBefore(previousArrivalTime);

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

                alternative.AddUtilityTerm(41, partTimeWorkerFlag * departureShift);
                alternative.AddUtilityTerm(43, nonworkingAdultFlag * departureShift);
                alternative.AddUtilityTerm(45, universityStudentFlag * departureShift);
                alternative.AddUtilityTerm(47, retiredAdultFlag * departureShift);
                alternative.AddUtilityTerm(49, drivingAgeStudentFlag * departureShift);
                alternative.AddUtilityTerm(51, childAge5Through15Flag * departureShift);
                alternative.AddUtilityTerm(53, childUnder5Flag * departureShift);
                alternative.AddUtilityTerm(61, jointTourFlag * departureShift);
                alternative.AddUtilityTerm(63, partialHalfTourFlag * departureShift);
                alternative.AddUtilityTerm(65, fullHalfTourFlag * departureShift);

                alternative.AddUtilityTerm(131, workTourFlag * halfTourFromOriginFlag * departureShift);
                alternative.AddUtilityTerm(133, workTourFlag * halfTourFromDestinationFlag * departureShift);
                alternative.AddUtilityTerm(135, notWorkTourFlag * halfTourFromDestinationFlag * departureShift);
                alternative.AddUtilityTerm(137, notHomeBasedTourFlag * departureShift);
                alternative.AddUtilityTerm(145, originEscortFlag * departureShift);
                alternative.AddUtilityTerm(147, originShoppingFlag * departureShift);
                alternative.AddUtilityTerm(149, originMealFlag * departureShift);
                alternative.AddUtilityTerm(151, originSocialFlag * departureShift);
                alternative.AddUtilityTerm(153, originPersonalBusinessFlag * departureShift);
                alternative.AddUtilityTerm(155, originSchoolFlag * departureShift);

                alternative.AddUtilityTerm(42, partTimeWorkerFlag * durationShift);
                alternative.AddUtilityTerm(44, nonworkingAdultFlag * durationShift);
                alternative.AddUtilityTerm(46, universityStudentFlag * durationShift);
                alternative.AddUtilityTerm(48, retiredAdultFlag * durationShift);
                alternative.AddUtilityTerm(50, drivingAgeStudentFlag * durationShift);
                alternative.AddUtilityTerm(52, childAge5Through15Flag * durationShift);
                alternative.AddUtilityTerm(54, childUnder5Flag * durationShift);
                alternative.AddUtilityTerm(62, jointTourFlag * durationShift);
                alternative.AddUtilityTerm(64, partialHalfTourFlag * durationShift);
                alternative.AddUtilityTerm(66, fullHalfTourFlag * durationShift);

                alternative.AddUtilityTerm(132, workTourFlag * halfTourFromOriginFlag * durationShift);
                alternative.AddUtilityTerm(134, workTourFlag * halfTourFromDestinationFlag * durationShift);
                alternative.AddUtilityTerm(136, notWorkTourFlag * halfTourFromDestinationFlag * durationShift);
                alternative.AddUtilityTerm(138, notHomeBasedTourFlag * durationShift);
                alternative.AddUtilityTerm(146, originEscortFlag * durationShift);
                alternative.AddUtilityTerm(148, originShoppingFlag * durationShift);
                alternative.AddUtilityTerm(150, originMealFlag * durationShift);
                alternative.AddUtilityTerm(152, originSocialFlag * durationShift);
                alternative.AddUtilityTerm(154, originPersonalBusinessFlag * durationShift);
                alternative.AddUtilityTerm(156, originSchoolFlag * durationShift);

                alternative.AddUtilityTerm(86, sovOrHovTripFlag * Math.Max(time.ModeLOS.GeneralizedTimeLogsum, 0) * tour.TimeCoefficient);
                alternative.AddUtilityTerm(88, transitTripFlag * Math.Max(time.ModeLOS.GeneralizedTimeLogsum, 0) * tour.TimeCoefficient);
                alternative.AddUtilityTerm(92, halfTourFromOriginFlag * Math.Log(departurePeriodFraction));
                alternative.AddUtilityTerm(92, halfTourFromDestinationFlag * Math.Log(departurePeriodFraction));
                alternative.AddUtilityTerm(99, tripRemainingInHalfTour / (Math.Max(1D, Math.Abs(trip.ArrivalTimeLimit - period.Middle))));
                alternative.AddUtilityTerm(97, remainingToursCount / (Math.Max(1D, totalWindowRemaining)));
                alternative.AddUtilityTerm(98, remainingToursCount / (Math.Max(1D, maxWindowRemaining)));
            }
        }
Пример #3
0
        public virtual void HPTBikeTourUpdateTripValues()
        {
            //new version for trips on tours with mode 9, 10, 11, 13
            // for Actum
            // assumes that mode and departure time have been set
            // assumes one of tour modes 9, 10, 11, 13

            //time windows also reset in estimation mode  - this just resets for one window
            var timeWindow = Tour.IsHomeBasedTour ? Tour.PersonDay.TimeWindow : Tour.ParentTour.TimeWindow;

            if (!Global.Configuration.IsInEstimationMode)
            {
                //some variables reset only in application mode
                var time   = new HTripTime(DepartureTime);
                var period = time.DeparturePeriod;

                // set availability
                if (period.End < this.EarliestDepartureTime || period.Start > this.LatestDepartureTime)
                {
                    time.Available = false;
                }


                var travelTime = this.Direction == 1 ? this.Tour.HalfTour1TravelTime : this.Tour.HalfTour2TravelTime;

                //set the feasible window within the small period, accounting for travel time, and recheck availability
                if (time.Available)
                {
                    time.EarliestFeasibleDepatureTime = Math.Max(period.Start,
                                                                 this.IsHalfTourFromOrigin
                                                                 //JLB 20130723 replace next line
                                                                 //? trip.ArrivalTimeLimit + - (int) (time.ModeLOS.PathTime + 0.5)
                                                        ? this.ArrivalTimeLimit + (int)(travelTime + 0.5)
                                                        : this.EarliestDepartureTime);

                    time.LatestFeasibleDepartureTime = Math.Min(period.End,
                                                                this.IsHalfTourFromOrigin
                                                        ? this.LatestDepartureTime
                                                        : this.ArrivalTimeLimit - (int)(travelTime + 0.5));

                    time.Available = time.EarliestFeasibleDepatureTime < time.LatestFeasibleDepartureTime;
                }

                //HTripTime.SetTimeImpedanceAndWindow(this, time);

                if (!time.Available)
                {
                    if (!Global.Configuration.IsInEstimationMode)
                    {
                        PersonDay.IsValid = false;
                    }
                    return;
                }

                TravelTime     = travelTime;
                TravelCost     = this.Tour.TravelCostForPTBikeTour / 2.0;
                TravelDistance = this.Tour.TravelDistanceForPTBikeTour / 2.0;
                PathType       = this.Tour.PathType;

                if (this.Direction == 1)
                {
                    this.AccessCost     = this.Tour.HalfTour1AccessCost;
                    this.AccessDistance = this.Tour.HalfTour1AccessDistance;
                    this.AccessMode     = this.Tour.HalfTour1AccessMode;
                    this.AccessPathType = this.Tour.HalfTour1AccessPathType;
                    this.AccessStopArea = this.Tour.HalfTour1AccessStopAreaKey;
                    this.AccessTime     = this.Tour.HalfTour1AccessTime;
                    this.EgressCost     = this.Tour.HalfTour1EgressCost;
                    this.EgressDistance = this.Tour.HalfTour1EgressDistance;
                    this.EgressMode     = this.Tour.HalfTour1EgressMode;
                    this.EgressPathType = this.Tour.HalfTour1EgressPathType;
                    this.EgressStopArea = this.Tour.HalfTour1EgressStopAreaKey;
                    this.EgressTime     = this.Tour.HalfTour1EgressTime;
                }
                else
                {
                    this.AccessCost     = this.Tour.HalfTour2AccessCost;
                    this.AccessDistance = this.Tour.HalfTour2AccessDistance;
                    this.AccessMode     = this.Tour.HalfTour2AccessMode;
                    this.AccessPathType = this.Tour.HalfTour2AccessPathType;
                    this.AccessStopArea = this.Tour.HalfTour2AccessStopAreaKey;
                    this.AccessTime     = this.Tour.HalfTour2AccessTime;
                    this.EgressCost     = this.Tour.HalfTour2EgressCost;
                    this.EgressDistance = this.Tour.HalfTour2EgressDistance;
                    this.EgressMode     = this.Tour.HalfTour2EgressMode;
                    this.EgressPathType = this.Tour.HalfTour2EgressPathType;
                    this.EgressStopArea = this.Tour.HalfTour2EgressStopAreaKey;
                    this.EgressTime     = this.Tour.HalfTour2EgressTime;
                }

                var duration = (int)(TravelTime + 0.5);

                if (duration == Constants.DEFAULT_VALUE && Global.Configuration.ReportInvalidPersonDays)
                {
                    Global.PrintFile.WriteDurationIsInvalidWarning("TripWrapper", "UpdateTripValues", PersonDay.Id, TravelTime, TravelCost, TravelDistance);

                    if (!Global.Configuration.IsInEstimationMode)
                    {
                        PersonDay.IsValid = false;
                    }

                    return;
                }

                ArrivalTime =
                    IsHalfTourFromOrigin
                                                ? Math.Max(1, DepartureTime - duration)
                                                : Math.Min(Global.Settings.Times.MinutesInADay, DepartureTime + duration);

                /* doesn't have much effect - turn off for now
                 *                                       if (!Global.Configuration.AllowTripArrivalTimeOverlaps && timeWindow.IsBusy(ArrivalTime))   {
                 *                                                // move entire trip up to 15 minutes later or earlier depending on half tour direction.
                 *                                                // Find the smallest shift that will make the arrival time a non-busy minute while still leaving
                 *                                                // a gap between the departure time and the arrival time at the trip origin (non-0 activity duration)
                 *                                                //NOTE: This was copied over from the old version above.
                 *                                                // This could possibly cause some inconsistencies for times for different people on joint tours, if it is done separately for each
                 *                                                // (will work better if done before cloning....)
                 *                                                const int moveLimit = 15;
                 *
                 *                                                if (IsHalfTourFromOrigin)     {
                 *                                                              int originArrivalTime = Sequence == 1 ? Tour.DestinationDepartureTime : PreviousTrip.ArrivalTime;
                 *                                                              int moveLater = 0;
                 *                                                              do       {
                 *                                                                       moveLater++;
                 *                                                              } while (moveLater <= moveLimit && DepartureTime + moveLater < originArrivalTime && timeWindow.IsBusy(ArrivalTime + moveLater));
                 *
                 *                                                              if (!timeWindow.IsBusy(ArrivalTime + moveLater)) {
                 *                                                                       ArrivalTime += moveLater;
                 *                                                                       DepartureTime += moveLater;
                 *                                                                       if (Sequence == 1) Tour.DestinationArrivalTime += moveLater;
                 *                                                                       if (Global.Configuration.ReportInvalidPersonDays) Global.PrintFile.WriteLine("Tour {0}. Arrival time moved later by {1} minutes, New departure time {2}, Origin arrival {3}", Tour.Id, moveLater, DepartureTime, originArrivalTime);
                 *                                                              }
                 *                                                }
                 *                                                else  {
                 *                                                              int originArrivalTime = Sequence == 1 ? Tour.DestinationArrivalTime : PreviousTrip.ArrivalTime;
                 *                                                              int moveEarlier = 0;
                 *                                                              do   {
                 *                                                                       moveEarlier++;
                 *                                                              } while (moveEarlier <= moveLimit && DepartureTime - moveEarlier > originArrivalTime && timeWindow.IsBusy(ArrivalTime - moveEarlier));
                 *
                 *                                                              if (!timeWindow.IsBusy(ArrivalTime - moveEarlier))   {
                 *                                                                       ArrivalTime -= moveEarlier;
                 *                                                                       DepartureTime -= moveEarlier;
                 *                                                                       if (Sequence == 1) Tour.DestinationDepartureTime -= moveEarlier;
                 *                                                                       if (Global.Configuration.ReportInvalidPersonDays) Global.PrintFile.WriteLine("Tour {0}. Arrival time moved earlier by {1} minutes, New departure time {2}, Origin arrival {3}", Tour.Id, moveEarlier, DepartureTime, originArrivalTime);
                 *                                                              }
                 *                                                }
                 *                                       }
                 */
                //check again after possible adjustment

                if (!Global.Configuration.AllowTripArrivalTimeOverlaps && timeWindow.IsBusy(ArrivalTime))
                {
                    if (Global.Configuration.ReportInvalidPersonDays)
                    {
                        Global.PrintFile.WriteLine("Arrival time {0} is busy for trip {1}.", ArrivalTime, Id);
                    }

                    if (!Global.Configuration.IsInEstimationMode)
                    {
                        PersonDay.IsValid = false;
                    }
                }
                else                 //check if another trip needs to be scheduled and there only a few minutes left
                if ((IsHalfTourFromOrigin && ArrivalTime < Tour.EarliestOriginDepartureTime + 3 && DestinationParcel != Tour.OriginParcel) || (!IsHalfTourFromOrigin && ArrivalTime > Tour.LatestOriginArrivalTime - 3 && DestinationParcel != Tour.OriginParcel))
                {
                    if (!Global.Configuration.IsInEstimationMode)
                    {
                        PersonDay.IsValid = false;
                    }
                }

                if (Global.Configuration.TraceModelResultValidity)
                {
                    if (PersonDay.HouseholdDay.AttemptedSimulations >= Global.Configuration.InvalidAttemptsBeforeTrace)
                    {
                        Global.PrintFile.WriteLine("  >> HUpdateTripValues HH/P/T/Hf/T/Arrival time/valid {0} {1} {2} {3} {4} {5} {6}", Household.Id, Person.Sequence, Tour.Sequence, Direction, Sequence, ArrivalTime, PersonDay.IsValid);
                    }
                }

                if (!PersonDay.IsValid)
                {
                    return;
                }

                //if first trip in half tour, use departure time to reset tour times
                if (Sequence == 1)
                {
                    if (IsHalfTourFromOrigin)
                    {
                        Tour.DestinationArrivalTime = DepartureTime;
                    }
                    else
                    {
                        Tour.DestinationDepartureTime = DepartureTime;
                    }
                }
            }

            //adjust the time window for busy minutes at the stop origin and during the trip - done also in estimation mode
            var earliestBusyMinute =
                IsHalfTourFromOrigin
                                        ? ArrivalTime
                                        : Sequence == 1
                                                ? Tour.DestinationDepartureTime
                                                : GetPreviousTrip().ArrivalTime;

            var latestBusyMinute =
                !IsHalfTourFromOrigin
                                        ? ArrivalTime
                                        : Sequence == 1
                                                ? Tour.DestinationArrivalTime
                                                : GetPreviousTrip().ArrivalTime;

            timeWindow.SetBusyMinutes(earliestBusyMinute, latestBusyMinute + 1);

            if (!Global.Configuration.TraceModelResultValidity || PersonDay.HouseholdDay.AttemptedSimulations < Global.Configuration.InvalidAttemptsBeforeTrace)
            {
                return;
            }

            if (Tour.IsHomeBasedTour)
            {
                Global.PrintFile.WriteLine("  >> HUpdateTripValues SetBusyMinutes HH/P/PDay/Min1/Min2 {0} {1} {2} {3} {4}", Household.Id, Person.Sequence, PersonDay.Id, earliestBusyMinute, latestBusyMinute + 1);
            }
            else
            {
                Global.PrintFile.WriteLine("  >> HUpdateTripValues SetBusyMinutes HH/P/TOUR/Min1/Min2 {0} {1} {2} {3} {4}", Household.Id, Person.Sequence, Tour.ParentTour.Sequence, earliestBusyMinute, latestBusyMinute + 1);
            }
        }
Пример #4
0
        private void RunModel(ChoiceProbabilityCalculator choiceProbabilityCalculator, HouseholdDayWrapper householdDay, TripWrapper trip, HTripTime choice = null)
        {
            if (householdDay.Household.Id == 80066 && trip.Person.Sequence == 1 && trip.Tour.Sequence == 2 &&
                trip.Direction == 2 && trip.Sequence == 1)
            {
            }

            PersonWrapper    person    = (PersonWrapper)trip.Person;
            PersonDayWrapper personDay = (PersonDayWrapper)trip.PersonDay;
            TourWrapper      tour      = (TourWrapper)trip.Tour;

            // person inputs + househol_PFPT
            int partTimeWorkerFlag    = person.IsPartTimeWorker.ToFlag();
            int nonworkingAdultFlag   = person.IsNonworkingAdult.ToFlag();
            int universityStudentFlag = person.IsUniversityStudent.ToFlag();
            int retiredAdultFlag      = person.IsRetiredAdult.ToFlag();
            //var drivingAgeStudentFlag = person.IsDrivingAgeStudent.ToFlag(); // excluded by GV
            int childAge5Through15Flag = person.IsChildAge5Through15.ToFlag();
            int childUnder5Flag        = person.IsChildUnder5.ToFlag();
            int femaleFlag             = person.IsFemale.ToFlag();
            int fullTimeWorkerFlag     = person.IsFulltimeWorker.ToFlag();
            int primaryFamilyTimeFlag  = householdDay.PrimaryPriorityTimeFlag;

            // set tour inputs
            int workTourFlag             = tour.IsWorkPurpose().ToFlag();
            int schoolTourFlag           = tour.IsSchoolPurpose().ToFlag();
            int businessTourFlag         = tour.IsBusinessPurpose().ToFlag();
            int escortTourFlag           = tour.IsEscortPurpose().ToFlag();
            int personalBusinessTourFlag = tour.IsPersonalBusinessPurpose().ToFlag();
            int shoppingTourFlag         = tour.IsShoppingPurpose().ToFlag();
            int socialTourFlag           = tour.IsSocialPurpose().ToFlag();
            int notWorkSchoolTourFlag    = 1 - workTourFlag - schoolTourFlag;
            int notWorkTourFlag          = (!tour.IsWorkPurpose()).ToFlag();
            int notHomeBasedTourFlag     = (!tour.IsHomeBasedTour).ToFlag();
            int jointTourFlag            = (tour.JointTourSequence > 0) ? 1 : 0;
            int partialHalfTourFlag      = (trip.IsHalfTourFromOrigin ? tour.PartialHalfTour1Sequence > 0 : tour.PartialHalfTour2Sequence > 0) ? 1 : 0;
            int fullHalfTourFlag         = (trip.IsHalfTourFromOrigin ? tour.FullHalfTour1Sequence > 0 : tour.FullHalfTour2Sequence > 0) ? 1 : 0;

            // set trip inputs - travel purpose
            bool originChangeMode           = trip.Sequence > 1 && trip.GetPreviousTrip().DestinationPurpose == Global.Settings.Purposes.ChangeMode;
            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  originBusinessFlag         = trip.IsBusinessOriginPurpose().ToFlag();

            // set trip inputs - travel modes
            int sovOrHovTripFlag      = trip.UsesSovOrHovModes().ToFlag();
            int bikeTripFlag          = trip.IsBikeMode().ToFlag();
            int walkTripFlag          = trip.IsWalkMode().ToFlag();
            int transitTripFlag       = trip.IsTransitMode().ToFlag();
            int carDriverAloneFlag    = trip.IsSovMode().ToFlag();
            int carDriverNotAloneFlag = trip.IsHov2Mode().ToFlag();
            int carPassengerFlag      = trip.IsHov3Mode().ToFlag();

            int halfTourFromOriginFlag      = trip.IsHalfTourFromOrigin.ToFlag();
            int halfTourFromDestinationFlag = (!trip.IsHalfTourFromOrigin).ToFlag();

            // set remaining inputs
            // set remaining inputs
            TimeWindow timeWindow = new TimeWindow();

            if (tour.JointTourSequence > 0)
            {
                foreach (PersonDayWrapper pDay in householdDay.PersonDays)
                {
                    TourWrapper tInJoint = (TourWrapper)pDay.Tours.Find(t => t.JointTourSequence == tour.JointTourSequence);
                    if (!(tInJoint == null))
                    {
                        // set jointTour time window
                        timeWindow.IncorporateAnotherTimeWindow(tInJoint.PersonDay.TimeWindow);
                    }
                }
            }
            else if (trip.Direction == Global.Settings.TourDirections.OriginToDestination && tour.FullHalfTour1Sequence > 0)
            {
                foreach (PersonDayWrapper pDay in householdDay.PersonDays)
                {
                    TourWrapper tInJoint = (TourWrapper)pDay.Tours.Find(t => t.FullHalfTour1Sequence == tour.FullHalfTour1Sequence);
                    if (!(tInJoint == null))
                    {
                        // set jointTour time window
                        timeWindow.IncorporateAnotherTimeWindow(tInJoint.PersonDay.TimeWindow);
                    }
                }
            }
            else if (trip.Direction == Global.Settings.TourDirections.DestinationToOrigin && tour.FullHalfTour2Sequence > 0)
            {
                foreach (PersonDayWrapper pDay in householdDay.PersonDays)
                {
                    TourWrapper tInJoint = (TourWrapper)pDay.Tours.Find(t => t.FullHalfTour2Sequence == tour.FullHalfTour2Sequence);
                    if (!(tInJoint == null))
                    {
                        // set jointTour time window
                        timeWindow.IncorporateAnotherTimeWindow(tInJoint.PersonDay.TimeWindow);
                    }
                }
            }
            else if (tour.ParentTour == null)
            {
                timeWindow.IncorporateAnotherTimeWindow(personDay.TimeWindow);
            }
            else
            {
                timeWindow.IncorporateAnotherTimeWindow(tour.ParentTour.TimeWindow);
            }

            //set the availability and impedances for the periods
            HTripTime.SetTimeImpedances(trip);

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

            int previousArrivalTime = trip.IsHalfTourFromOrigin
                     ? (trip.Sequence == 1 ? tour.DestinationDepartureTime : trip.GetPreviousTrip().ArrivalTime)
                     : (trip.Sequence == 1 ? tour.DestinationArrivalTime : trip.GetPreviousTrip().ArrivalTime);

            MinuteSpan previousArrivalPeriod = new HTripTime(previousArrivalTime).DeparturePeriod;

            foreach (HTripTime time in HTripTime.Times[ParallelUtility.threadLocalAssignedIndex.Value])
            {
                MinuteSpan period = time.DeparturePeriod;

                double departurePeriodFraction = timeWindow.TotalAvailableMinutes(period.Start, period.End) / (period.End - period.Start + 1D);

                double departureShiftHours  = period.Middle / 60.0;
                int    durationShiftMinutes = Math.Abs(period.Middle - previousArrivalPeriod.Middle);
                double durationShiftHours   = durationShiftMinutes / 60.0;



                bool available = time.Available && departurePeriodFraction > 0;

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


                if (!alternative.Available)
                {
                    continue;
                }

                alternative.Choice = time;

                int indicatedTravelTime  = (int)time.ModeLOS.PathTime;
                int indicatedArrivalTime = trip.IsHalfTourFromOrigin
                     ? Math.Max(1, period.Middle - indicatedTravelTime)
                     : Math.Min(1440, period.Middle + indicatedTravelTime);

                int totalWindowRemaining = trip.IsHalfTourFromOrigin
                     ? timeWindow.TotalAvailableMinutesBefore(indicatedArrivalTime) + timeWindow.TotalAvailableMinutesAfter(previousArrivalTime)
                     : timeWindow.TotalAvailableMinutesAfter(indicatedArrivalTime) + timeWindow.TotalAvailableMinutesBefore(previousArrivalTime);

                int maxWindowRemaining = trip.IsHalfTourFromOrigin
                     ? timeWindow.MaxAvailableMinutesBefore(indicatedArrivalTime) + timeWindow.MaxAvailableMinutesAfter(previousArrivalTime)
                     : timeWindow.MaxAvailableMinutesAfter(indicatedArrivalTime) + timeWindow.MaxAvailableMinutesBefore(previousArrivalTime);

                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());
                    //GV changed to 3pm
                    alternative.AddUtilityTerm(17, time.DeparturePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.OnePM, Global.Settings.Times.ThreePM).ToFlag());
                    alternative.AddUtilityTerm(18, time.DeparturePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.ThreePM, Global.Settings.Times.SixPM).ToFlag());
                    alternative.AddUtilityTerm(19, time.DeparturePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.SixPM, 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, durationShiftMinutes.IsRightExclusiveBetween(Global.Settings.Times.ZeroHours, Global.Settings.Times.OneHour).ToFlag());           // 0 - 1
                alternative.AddUtilityTerm(32, durationShiftMinutes.IsRightExclusiveBetween(Global.Settings.Times.OneHour, Global.Settings.Times.TwoHours).ToFlag());            // 1 - 2
                alternative.AddUtilityTerm(33, durationShiftMinutes.IsRightExclusiveBetween(Global.Settings.Times.TwoHours, Global.Settings.Times.ThreeHours).ToFlag());         // 2 - 3
                alternative.AddUtilityTerm(34, durationShiftMinutes.IsRightExclusiveBetween(Global.Settings.Times.ThreeHours, Global.Settings.Times.FiveHours).ToFlag());        // 3 - 5
                alternative.AddUtilityTerm(35, durationShiftMinutes.IsRightExclusiveBetween(Global.Settings.Times.FiveHours, Global.Settings.Times.SevenHours).ToFlag());        // 5 - 7
                alternative.AddUtilityTerm(36, durationShiftMinutes.IsRightExclusiveBetween(Global.Settings.Times.SevenHours, Global.Settings.Times.NineHours).ToFlag());        // 7 - 9
                alternative.AddUtilityTerm(37, durationShiftMinutes.IsRightExclusiveBetween(Global.Settings.Times.NineHours, Global.Settings.Times.TwelveHours).ToFlag());       // 9 - 12
                alternative.AddUtilityTerm(38, durationShiftMinutes.IsRightExclusiveBetween(Global.Settings.Times.TwelveHours, Global.Settings.Times.FourteenHours).ToFlag());   // 12 - 14
                alternative.AddUtilityTerm(39, durationShiftMinutes.IsRightExclusiveBetween(Global.Settings.Times.FourteenHours, Global.Settings.Times.EighteenHours).ToFlag()); // 14 - 18
                alternative.AddUtilityTerm(40, (durationShiftMinutes >= Global.Settings.Times.EighteenHours).ToFlag());                                                          // 18 - 24

                alternative.AddUtilityTerm(41, partTimeWorkerFlag * departureShiftHours);
                alternative.AddUtilityTerm(43, nonworkingAdultFlag * departureShiftHours);
                alternative.AddUtilityTerm(45, universityStudentFlag * departureShiftHours);
                alternative.AddUtilityTerm(47, retiredAdultFlag * departureShiftHours);
                alternative.AddUtilityTerm(49, femaleFlag * departureShiftHours);
                alternative.AddUtilityTerm(51, childAge5Through15Flag * departureShiftHours);
                alternative.AddUtilityTerm(53, childUnder5Flag * departureShiftHours);
                alternative.AddUtilityTerm(61, jointTourFlag * departureShiftHours);
                //alternative.AddUtilityTerm(63, partialHalfTourFlag * departureShiftHours);
                //alternative.AddUtilityTerm(65, fullHalfTourFlag * departureShiftHours);
                alternative.AddUtilityTerm(67, primaryFamilyTimeFlag * departureShiftHours);

                //alternative.AddUtilityTerm(131, workTourFlag * halfTourFromOriginFlag * departureShiftHours);
                //alternative.AddUtilityTerm(133, workTourFlag * halfTourFromDestinationFlag * departureShiftHours);
                //alternative.AddUtilityTerm(135, notWorkTourFlag * halfTourFromDestinationFlag * departureShiftHours);
                //alternative.AddUtilityTerm(137, notHomeBasedTourFlag * departureShiftHours);
                alternative.AddUtilityTerm(145, originEscortFlag * departureShiftHours);
                alternative.AddUtilityTerm(147, originShoppingFlag * departureShiftHours);
                alternative.AddUtilityTerm(149, originBusinessFlag * departureShiftHours);
                alternative.AddUtilityTerm(151, originSocialFlag * departureShiftHours);
                alternative.AddUtilityTerm(153, originPersonalBusinessFlag * departureShiftHours);
                alternative.AddUtilityTerm(155, originSchoolFlag * departureShiftHours);

                alternative.AddUtilityTerm(42, partTimeWorkerFlag * durationShiftHours);
                alternative.AddUtilityTerm(44, nonworkingAdultFlag * durationShiftHours);
                alternative.AddUtilityTerm(46, universityStudentFlag * durationShiftHours);
                alternative.AddUtilityTerm(48, retiredAdultFlag * durationShiftHours);
                alternative.AddUtilityTerm(50, femaleFlag * durationShiftHours);
                alternative.AddUtilityTerm(52, childAge5Through15Flag * durationShiftHours);
                alternative.AddUtilityTerm(54, childUnder5Flag * durationShiftHours);
                //alternative.AddUtilityTerm(62, jointTourFlag * durationShiftHours);
                //alternative.AddUtilityTerm(64, partialHalfTourFlag * durationShiftHours);
                //alternative.AddUtilityTerm(66, fullHalfTourFlag * durationShiftHours);
                alternative.AddUtilityTerm(68, primaryFamilyTimeFlag * durationShiftHours);

                alternative.AddUtilityTerm(132, workTourFlag * halfTourFromOriginFlag * durationShiftHours);
                alternative.AddUtilityTerm(134, workTourFlag * halfTourFromDestinationFlag * durationShiftHours);
                alternative.AddUtilityTerm(136, notWorkTourFlag * halfTourFromDestinationFlag * durationShiftHours);
                alternative.AddUtilityTerm(138, notHomeBasedTourFlag * durationShiftHours);
                alternative.AddUtilityTerm(146, originEscortFlag * durationShiftHours);
                alternative.AddUtilityTerm(148, originShoppingFlag * durationShiftHours);
                alternative.AddUtilityTerm(150, originBusinessFlag * durationShiftHours);
                alternative.AddUtilityTerm(152, originSocialFlag * durationShiftHours);
                alternative.AddUtilityTerm(154, originPersonalBusinessFlag * durationShiftHours);
                alternative.AddUtilityTerm(156, originSchoolFlag * durationShiftHours);

                alternative.AddUtilityTerm(158, workTourFlag * halfTourFromOriginFlag * (trip.Sequence == 1).ToFlag() * durationShiftHours);
                alternative.AddUtilityTerm(159, workTourFlag * halfTourFromDestinationFlag * (trip.Sequence == 1).ToFlag() * durationShiftHours);
                alternative.AddUtilityTerm(160, schoolTourFlag * halfTourFromOriginFlag * (trip.Sequence == 1).ToFlag() * durationShiftHours);
                alternative.AddUtilityTerm(161, schoolTourFlag * halfTourFromDestinationFlag * (trip.Sequence == 1).ToFlag() * durationShiftHours);
                alternative.AddUtilityTerm(162, businessTourFlag * halfTourFromOriginFlag * (trip.Sequence == 1).ToFlag() * durationShiftHours);
                alternative.AddUtilityTerm(163, businessTourFlag * halfTourFromDestinationFlag * (trip.Sequence == 1).ToFlag() * durationShiftHours);
                alternative.AddUtilityTerm(164, escortTourFlag * halfTourFromOriginFlag * (trip.Sequence == 1).ToFlag() * durationShiftHours);
                alternative.AddUtilityTerm(165, escortTourFlag * halfTourFromDestinationFlag * (trip.Sequence == 1).ToFlag() * durationShiftHours);
                alternative.AddUtilityTerm(166, personalBusinessTourFlag * halfTourFromOriginFlag * (trip.Sequence == 1).ToFlag() * durationShiftHours);
                alternative.AddUtilityTerm(167, personalBusinessTourFlag * halfTourFromDestinationFlag * (trip.Sequence == 1).ToFlag() * durationShiftHours);
                alternative.AddUtilityTerm(168, shoppingTourFlag * halfTourFromOriginFlag * (trip.Sequence == 1).ToFlag() * durationShiftHours);
                alternative.AddUtilityTerm(169, shoppingTourFlag * halfTourFromDestinationFlag * (trip.Sequence == 1).ToFlag() * durationShiftHours);
                alternative.AddUtilityTerm(170, socialTourFlag * halfTourFromOriginFlag * (trip.Sequence == 1).ToFlag() * durationShiftHours);
                alternative.AddUtilityTerm(171, socialTourFlag * halfTourFromDestinationFlag * (trip.Sequence == 1).ToFlag() * durationShiftHours);

                //alternative.AddUtilityTerm(172, workTourFlag * halfTourFromOriginFlag * (trip.Sequence==1).ToFlag() * departureShiftHours);


                alternative.AddUtilityTerm(86, sovOrHovTripFlag * Math.Max(time.ModeLOS.GeneralizedTimeLogsum, 0) * tour.TimeCoefficient);
                //alternative.AddUtilityTerm(87, sovOrHovTripFlag * notWorkSchoolTourFlag * Math.Max(time.ModeLOS.GeneralizedTimeLogsum, 0) * tour.TimeCoefficient);
                //alternative.AddUtilityTerm(88, transitTripFlag * Math.Max(time.ModeLOS.GeneralizedTimeLogsum, 0) * tour.TimeCoefficient);
                //alternative.AddUtilityTerm(89, sovOrHovTripFlag * notWorkSchoolTourFlag * (trip.Sequence==1).ToFlag() * Math.Max(time.ModeLOS.GeneralizedTimeLogsum, 0) * tour.TimeCoefficient);

                alternative.AddUtilityTerm(92, Math.Log(departurePeriodFraction));
                //alternative.AddUtilityTerm(92, halfTourFromDestinationFlag * Math.Log(departurePeriodFraction));
                alternative.AddUtilityTerm(99, tripRemainingInHalfTour / (Math.Max(1D, Math.Abs(trip.ArrivalTimeLimit - period.Middle))));
                //alternative.AddUtilityTerm(97, remainingToursCount / (Math.Max(1D, totalWindowRemaining)));
                alternative.AddUtilityTerm(98, 1000 * remainingToursCount / (Math.Max(1D, maxWindowRemaining)));
            }
        }