Example #1
0
        public static void SetModeTimeImpedances(IHouseholdDayWrapper householdDay, ITourWrapper tour,
                                                 int constrainedMode, int constrainedArrivalTime, int constrainedDepartureTime, int constrainedHouseholdCars, double constrainedTransitDiscountFraction, IParcelWrapper alternativeDestination = null)
        {
            /*			if (householdDay.Household.Id == 80059 && tour.Person.Sequence == 2 && tour.Sequence == 2
             *                              && constrainedMode == 5 && constrainedArrivalTime == 354 && constrainedDepartureTime == 361) {
             *                              bool testBreak = true;
             *                      }
             */

            var timeWindow = (householdDay != null && tour != null) ? tour.GetRelevantTimeWindow(householdDay) : new TimeWindow();

            {
                foreach (var modeTimes in ModeTimes[ParallelUtility.GetBatchFromThreadId()])
                {
                    modeTimes.LongestFeasibleWindow = null;
                    if ((constrainedMode <= 0 || constrainedMode == modeTimes.Mode)
                        &&
                        (constrainedArrivalTime <= 0 ||
                         constrainedArrivalTime.IsBetween(modeTimes.ArrivalPeriod.Start, modeTimes.ArrivalPeriod.End))
                        &&
                        (constrainedDepartureTime <= 0 ||
                         constrainedDepartureTime.IsBetween(modeTimes.DeparturePeriod.Start, modeTimes.DeparturePeriod.End)))
                    {
                        SetImpedanceAndWindow(timeWindow, tour, modeTimes, constrainedHouseholdCars, constrainedTransitDiscountFraction, alternativeDestination);
                    }
                }
            }
        }
        public int Run(IPersonDayWrapper personDay, IHouseholdDayWrapper householdDay, int maxPurpose, int choice)
        {
            if (householdDay == null)
            {
                throw new ArgumentNullException("householdDay");
            }

            householdDay.ResetRandom(949 + personDay.GetTotalCreatedTours());

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

            ChoiceProbabilityCalculator choiceProbabilityCalculator = _helpers[ParallelUtility.threadLocalAssignedIndex.Value].GetChoiceProbabilityCalculator(((personDay.Person.Id * 10 + personDay.Day) * 397) ^ personDay.GetTotalCreatedTours());

            if (_helpers[ParallelUtility.threadLocalAssignedIndex.Value].ModelIsInEstimationMode)
            {
                RunModel(choiceProbabilityCalculator, personDay, householdDay, maxPurpose, choice);

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

                ChoiceProbabilityCalculator.Alternative chosenAlternative = choiceProbabilityCalculator.SimulateChoice(householdDay.Household.RandomUtility);
                choice = (int)chosenAlternative.Choice;
            }

            return(choice);
        }
Example #3
0
        private static TWrapper CreateWrapper(IPartialHalfTour partialHalfTour, IHouseholdDayWrapper householdDayWrapper)
        {
            Type   type     = typeof(TWrapper);
            object instance = Activator.CreateInstance(type, partialHalfTour, householdDayWrapper);

            return((TWrapper)instance);
        }
Example #4
0
        private static TWrapper CreateWrapper(IJointTour jointTour, IHouseholdDayWrapper householdDayWrapper)
        {
            Type   type     = typeof(TWrapper);
            object instance = Activator.CreateInstance(type, jointTour, householdDayWrapper);

            return((TWrapper)instance);
        }
Example #5
0
        private static TWrapper CreateWrapper(IFullHalfTour fullHalfTour, IHouseholdDayWrapper householdDayWrapper)
        {
            var type     = typeof(TWrapper);
            var instance = Activator.CreateInstance(type, fullHalfTour, householdDayWrapper);

            return((TWrapper)instance);
        }
Example #6
0
        public void Run(IPersonDayWrapper personDay, IHouseholdDayWrapper householdDay)
        {
            if (personDay == null)
            {
                throw new ArgumentNullException("personDay");
            }

            personDay.Person.ResetRandom(961);

            int choice = 0;

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

            ChoiceProbabilityCalculator choiceProbabilityCalculator = _helpers[ParallelUtility.threadLocalAssignedIndex.Value].GetChoiceProbabilityCalculator(personDay.Person.Id * 10 + personDay.Day);

            if (_helpers[ParallelUtility.threadLocalAssignedIndex.Value].ModelIsInEstimationMode)
            {
                choice = Math.Min(personDay.WorkStops, 1) + 2 * Math.Min(personDay.SchoolStops, 1);


                RunModel(choiceProbabilityCalculator, personDay, householdDay, choice);

                choiceProbabilityCalculator.WriteObservation();
            }
            else if (Global.Configuration.TestEstimationModelInApplicationMode)
            {
                Global.Configuration.IsInEstimationMode = false;

                RunModel(choiceProbabilityCalculator, personDay, householdDay);

                int observedChoice = Math.Min(personDay.WorkStops, 1) + 2 * Math.Min(personDay.SchoolStops, 1);

                ChoiceProbabilityCalculator.Alternative simulatedChoice = choiceProbabilityCalculator.SimulateChoice(householdDay.Household.RandomUtility, personDay.Id, observedChoice);

                Global.Configuration.IsInEstimationMode = true;
            }
            else
            {
                RunModel(choiceProbabilityCalculator, personDay, householdDay);

                ChoiceProbabilityCalculator.Alternative chosenAlternative = choiceProbabilityCalculator.SimulateChoice(householdDay.Household.RandomUtility);
                choice = (int)chosenAlternative.Choice;

                if (choice == 1 || choice == 3)
                {
                    personDay.WorkStops = 1;
                }
                if (choice == 2 || choice == 3)
                {
                    personDay.SchoolStops = 1;
                }
            }
        }
Example #7
0
        public void Run(IPersonDayWrapper personDay, IHouseholdDayWrapper householdDay)
        {
            if (personDay == null)
            {
                throw new ArgumentNullException("personDay");
            }

            personDay.Person.ResetRandom(904);

            if (Global.Configuration.IsInEstimationMode)
            {
                if (personDay.WorkAtHomeDuration >= 120 && personDay.Person.IsFullOrPartTimeWorker)
                {
                    personDay.WorksAtHomeFlag = 1;
                }
                else
                {
                    personDay.WorksAtHomeFlag = 0;
                }

                if (!_helpers[ParallelUtility.threadLocalAssignedIndex.Value].ModelIsInEstimationMode || !personDay.Person.IsFullOrPartTimeWorker)
                {
                    return;
                }
            }

            ChoiceProbabilityCalculator choiceProbabilityCalculator = _helpers[ParallelUtility.threadLocalAssignedIndex.Value].GetChoiceProbabilityCalculator(personDay.Person.Id * 10 + personDay.Day);

            if (_helpers[ParallelUtility.threadLocalAssignedIndex.Value].ModelIsInEstimationMode)
            {
                if (Global.Configuration.EstimationModel != CHOICE_MODEL_NAME)
                {
                    return;
                }

                RunModel(choiceProbabilityCalculator, personDay, householdDay, personDay.WorksAtHomeFlag);

                choiceProbabilityCalculator.WriteObservation();
            }
            else
            {
                int choice;

                if (!personDay.Person.IsFullOrPartTimeWorker)
                {
                    choice = 0;
                }
                else
                {
                    RunModel(choiceProbabilityCalculator, personDay, householdDay);

                    ChoiceProbabilityCalculator.Alternative chosenAlternative = choiceProbabilityCalculator.SimulateChoice(personDay.Household.RandomUtility);
                    choice = (int)chosenAlternative.Choice;
                }
                personDay.WorksAtHomeFlag    = choice;
                personDay.WorkAtHomeDuration = choice * 120; //default predicted duration for output
            }
        }
        public static void ResetRandom(this IHouseholdDayWrapper householdDay, int index)
        {
            if (householdDay == null)
            {
                throw new ArgumentNullException("householdDay");
            }

            ResetRandom(householdDay.Household.RandomUtility, householdDay.Household.SeedValues, index, householdDay.AttemptedSimulations);
        }
        public virtual IFullHalfTourWrapper CreateFullHalfTour(IHouseholdDayWrapper householdDay, IEnumerable <IPersonDayWrapper> orderedPersonDays, int[] participants, int direction)
        {
            householdDay.FullHalfTours++;

            var i = 0;
            var j = 0;
            var personSequence = new int[9];

            foreach (var personDay in orderedPersonDays)
            {
                i++;

                if (i > 5 || participants[i] != 1)
                {
                    continue;
                }

                j++;

                personSequence[j] = personDay.Person.Sequence;
            }

            var model = _fullHalfTourCreator.CreateModel();

            model.Sequence        = ++_fullHalfTourSequence;
            model.Id              = Id * 10 + _fullHalfTourSequence;
            model.HouseholdDayId  = Id;
            model.HouseholdId     = HouseholdId;
            model.Day             = Day;
            model.Direction       = direction;
            model.Participants    = participants[7];
            model.PersonSequence1 = personSequence[1];
            model.TourSequence1   = 0;
            model.PersonSequence2 = personSequence[2];
            model.TourSequence2   = 0;
            model.PersonSequence3 = personSequence[3];
            model.TourSequence3   = 0;
            model.PersonSequence4 = personSequence[4];
            model.TourSequence4   = 0;
            model.PersonSequence5 = personSequence[5];
            model.TourSequence5   = 0;
            model.PersonSequence6 = personSequence[6];
            model.TourSequence6   = 0;
            model.PersonSequence7 = personSequence[7];
            model.TourSequence7   = 0;
            model.PersonSequence8 = personSequence[8];
            model.TourSequence8   = 0;

            var fullHalfTour = _fullHalfTourCreator.CreateWrapper(model, householdDay);

            householdDay.FullHalfToursList.Add(fullHalfTour);

            return(fullHalfTour);
        }
        public virtual IJointTourWrapper CreateJointTour(IHouseholdDayWrapper householdDay, IEnumerable <IPersonDayWrapper> orderedPersonDays, int[] participants, int purpose)
        {
            householdDay.JointTours++;

            var i = 0;
            var j = 0;
            var personSequence = new int[9];

            foreach (var personDay in orderedPersonDays)
            {
                i++;

                if (i > 5 || participants[i] != 1)
                {
                    continue;
                }

                j++;

                personSequence[j] = personDay.Person.Sequence;
            }

            var model = _jointTourCreator.CreateModel();

            model.Sequence        = ++_jointTourSequence;
            model.Id              = Id * 10 + _jointTourSequence;
            model.HouseholdDayId  = Id;
            model.HouseholdId     = HouseholdId;
            model.Day             = Day;
            model.MainPurpose     = purpose;
            model.Participants    = participants[7];
            model.PersonSequence1 = personSequence[1];
            model.TourSequence1   = 0;
            model.PersonSequence2 = personSequence[2];
            model.TourSequence2   = 0;
            model.PersonSequence3 = personSequence[3];
            model.TourSequence3   = 0;
            model.PersonSequence4 = personSequence[4];
            model.TourSequence4   = 0;
            model.PersonSequence5 = personSequence[5];
            model.TourSequence5   = 0;
            model.PersonSequence6 = personSequence[6];
            model.TourSequence6   = 0;
            model.PersonSequence7 = personSequence[7];
            model.TourSequence7   = 0;
            model.PersonSequence8 = personSequence[8];
            model.TourSequence8   = 0;

            var jointTour = _jointTourCreator.CreateWrapper(model, this);

            householdDay.JointToursList.Add(jointTour);

            return(jointTour);
        }
        public virtual IPartialHalfTourWrapper CreatePartialHalfTour(IHouseholdDayWrapper householdDay, IEnumerable <IPersonDayWrapper> orderedPersonDays, int[] participants, int[] pickOrder, double[] distanceFromChauffeur, int direction)
        {
            householdDay.PartialHalfTours++;

            var personSequence = new int[9];
            var i = 0;

            foreach (var personDay in orderedPersonDays)
            {
                i++;

                for (var i2 = 0; i2 < 5; i2++)
                {
                    if (pickOrder[i2] == i)
                    {
                        personSequence[i2] = personDay.Person.Sequence;
                    }
                }
            }

            var model = _partialHalfTourCreator.CreateModel();

            model.Sequence        = ++_partialHalfTourSequence;
            model.Id              = Id * 10 + _partialHalfTourSequence;
            model.HouseholdDayId  = Id;
            model.HouseholdId     = HouseholdId;
            model.Day             = Day;
            model.Direction       = direction;
            model.Participants    = participants[7];
            model.PersonSequence1 = distanceFromChauffeur[0] > 998 ? 0 : personSequence[0];
            model.TourSequence1   = 0;
            model.PersonSequence2 = distanceFromChauffeur[1] > 998 ? 0 : personSequence[1];
            model.TourSequence2   = 0;
            model.PersonSequence3 = distanceFromChauffeur[2] > 998 ? 0 : personSequence[2];
            model.TourSequence3   = 0;
            model.PersonSequence4 = distanceFromChauffeur[3] > 998 ? 0 : personSequence[3];
            model.TourSequence4   = 0;
            model.PersonSequence5 = distanceFromChauffeur[4] > 998 ? 0 : personSequence[4];
            model.TourSequence5   = 0;
            model.PersonSequence6 = 0;             //distanceFromChauffeur[5] > 998 ? 0 : personSequence[5],
            model.TourSequence6   = 0;
            model.PersonSequence7 = 0;             //distanceFromChauffeur[6] > 998 ? 0 : personSequence[6],
            model.TourSequence7   = 0;
            model.PersonSequence8 = 0;             //distanceFromChauffeur[7] > 998 ? 0 : personSequence[7],
            model.TourSequence8   = 0;

            var partialHalfTour = _partialHalfTourCreator.CreateWrapper(model, householdDay);

            householdDay.PartialHalfToursList.Add(partialHalfTour);

            return(partialHalfTour);
        }
Example #12
0
        public void Run(IHouseholdDayWrapper householdDay, ITripWrapper 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;
                }
            }

            var 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.Other)
                {
                    return;
                }

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

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

                var 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;
                }

                var choice = (HTripTime)chosenAlternative.Choice;

                trip.DepartureTime = choice.GetRandomFeasibleMinute(trip, choice);
            }
        }
Example #13
0
        public PartialHalfTourWrapper(IPartialHalfTour partialHalfTour, IHouseholdDayWrapper householdDayWrapper)
        {
            _partialHalfTour = partialHalfTour;

            _exporter =
                Global
                .ContainerDaySim.GetInstance <IPersistenceFactory <IPartialHalfTour> >()
                .Exporter;

            // relations properties

            Household    = householdDayWrapper.Household;
            HouseholdDay = householdDayWrapper;
        }
Example #14
0
        public JointTourWrapper(IJointTour jointTour, IHouseholdDayWrapper householdDayWrapper)
        {
            _jointTour = jointTour;

            _exporter =
                Global
                .ContainerDaySim.GetInstance <IPersistenceFactory <IJointTour> >()
                .Exporter;

            // relations properties

            Household    = householdDayWrapper.Household;
            HouseholdDay = householdDayWrapper;
        }
Example #15
0
        public JointTourWrapper(IJointTour jointTour, IHouseholdDayWrapper householdDayWrapper)
        {
            _jointTour = jointTour;

            _exporter =
                Global
                .Kernel
                .Get <IPersistenceFactory <IJointTour> >()
                .Exporter;

            // relations properties

            Household    = householdDayWrapper.Household;
            HouseholdDay = householdDayWrapper;
        }
        public FullHalfTourWrapper(IFullHalfTour fullHalfTour, IHouseholdDayWrapper householdDayWrapper)
        {
            _fullHalfTour = fullHalfTour;

            _exporter =
                Global
                .Kernel
                .Get <IPersistenceFactory <IFullHalfTour> >()
                .Exporter;

            // relations properties

            Household    = householdDayWrapper.Household;
            HouseholdDay = householdDayWrapper;
        }
Example #17
0
        public PersonDayWrapper(IPersonDay personDay, IPersonWrapper personWrapper, IHouseholdDayWrapper householdDayWrapper)
        {
            _personDay = personDay;

            _exporter =
                Global
                .Kernel
                .Get <IPersistenceFactory <IPersonDay> >()
                .Exporter;

            // person day fields

            _personDayCreator =
                Global
                .Kernel
                .Get <IWrapperFactory <IPersonDayCreator> >()
                .Creator;

            // tour fields

            _tourReader =
                Global
                .Kernel
                .Get <IPersistenceFactory <ITour> >()
                .Reader;

            _tourCreator =
                Global
                .Kernel
                .Get <IWrapperFactory <ITourCreator> >()
                .Creator;

            // relations properties

            Household    = personWrapper.Household;
            Person       = personWrapper;
            HouseholdDay = householdDayWrapper;

            // domain model properies

            SetExpansionFactor();

            // flags/choice model/etc. properties

            TimeWindow = new TimeWindow();
        }
Example #18
0
        public int GetRandomDepartureTime(IHouseholdDayWrapper householdDay, ITourWrapper tour)
        {
            if (tour == null)
            {
                throw new ArgumentNullException("trip");
            }

            var timeWindow = tour.GetRelevantTimeWindow(householdDay);

            var departureTime = timeWindow.GetAvailableMinute(tour.Household.RandomUtility, DeparturePeriod.Start, DeparturePeriod.End);

            //if (departureTime == Constants.DEFAULT_VALUE) {
            //	throw new InvalidDepartureTimeException();
            //}

            return(departureTime);
        }
Example #19
0
        public ChoiceProbabilityCalculator.Alternative RunNested(ITourWrapper tour, IParcelWrapper destinationParcel, int householdCars, double transitDiscountFraction)
        {
            if (Global.Configuration.AvoidDisaggregateModeChoiceLogsums)
            {
                return(null);
            }
            var choiceProbabilityCalculator = _helpers[ParallelUtility.GetBatchFromThreadId()].GetNestedChoiceProbabilityCalculator();

            IHouseholdDayWrapper householdDay = (tour.PersonDay == null) ? null : tour.PersonDay.HouseholdDay;

            int constrainedMode          = 0;
            int constrainedArrivalTime   = (Global.Configuration.ConstrainTimesForModeChoiceLogsums) ? tour.DestinationArrivalTime : 0;
            int constrainedDepartureTime = (Global.Configuration.ConstrainTimesForModeChoiceLogsums) ? tour.DestinationDepartureTime : 0;

            tour.DestinationParcel = destinationParcel;
            HTourModeTime.SetModeTimeImpedances(householdDay, tour, constrainedMode, constrainedArrivalTime, constrainedDepartureTime, -1, -1.0);

            RunModel(choiceProbabilityCalculator, householdDay, tour, destinationParcel, householdCars, constrainedMode, constrainedArrivalTime, constrainedDepartureTime);

            return(choiceProbabilityCalculator.SimulateChoice(tour.Household.RandomUtility));
        }
        public int Run(ITripWrapper trip, IHouseholdDayWrapper householdDay, int choice)
        {
            if (trip == null)
            {
                throw new ArgumentNullException("trip");
            }

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

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

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

            if (_helpers[ParallelUtility.threadLocalAssignedIndex.Value].ModelIsInEstimationMode)
            {
                if (trip.OriginParcel == null)
                {
                    return(Constants.DEFAULT_VALUE);
                }
                RunModel(choiceProbabilityCalculator, trip, householdDay, choice);

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

                var chosenAlternative = choiceProbabilityCalculator.SimulateChoice(trip.Household.RandomUtility);
                choice = (int)chosenAlternative.Choice;
            }

            return(choice);
        }
Example #21
0
        public ChoiceProbabilityCalculator.Alternative RunNested(ITourWrapper tour, IParcelWrapper destinationParcel, int householdCars, double transitDiscountFraction)
        {
            if (Global.Configuration.AvoidDisaggregateModeChoiceLogsums)
            {
                return(null);
            }
            ChoiceProbabilityCalculator choiceProbabilityCalculator = _helpers[ParallelUtility.threadLocalAssignedIndex.Value].GetNestedChoiceProbabilityCalculator();

            IHouseholdDayWrapper householdDay = (tour.PersonDay == null) ? null : tour.PersonDay.HouseholdDay;

            int constrainedMode          = 0;
            int constrainedArrivalTime   = (Global.Configuration.ConstrainTimesForModeChoiceLogsums) ? tour.DestinationArrivalTime : 0;
            int constrainedDepartureTime = (Global.Configuration.ConstrainTimesForModeChoiceLogsums) ? tour.DestinationDepartureTime : 0;

            tour.DestinationParcel = destinationParcel;
            //using tour.DestinationParcel as a temporary value, may want to make destinationParcel another call parameter below instead
            HTourModeTime.SetModeTimeImpedances(householdDay, tour, constrainedMode, constrainedArrivalTime, constrainedDepartureTime, householdCars, transitDiscountFraction);


            RunModel(choiceProbabilityCalculator, householdDay, tour, destinationParcel, householdCars, constrainedMode, constrainedArrivalTime, constrainedDepartureTime);

            return(choiceProbabilityCalculator.SimulateChoice(tour.Household.RandomUtility));
        }
        public void Run(ITourWrapper tour, IHouseholdDayWrapper householdDay, int sampleSize)
        {
            if (tour == null)
            {
                throw new ArgumentNullException("tour");
            }
            //timesStarted++;

            tour.PersonDay.ResetRandom(20 + tour.Sequence - 1);

            if (Global.Configuration.IsInEstimationMode)
            {
                if (Global.Configuration.EstimationModel != CHOICE_MODEL_NAME)
                {
                    return;
                }
                if (tour.DestinationParcel == null || tour.OriginParcel == null ||
                    tour.Mode < Global.Settings.Modes.Walk || tour.Mode > Global.Settings.Modes.Transit)
                {
                    return;
                }
                // JLB 20140421 add the following to keep from estimatign twice for the same tour
                //if (tour.DestinationModeAndTimeHaveBeenSimulated) {
                //    return;
                //}
            }

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

            if (_helpers[ParallelUtility.threadLocalAssignedIndex.Value].ModelIsInEstimationMode)
            {
                RunModel(choiceProbabilityCalculator, tour, householdDay, sampleSize, tour.DestinationParcel);

                choiceProbabilityCalculator.WriteObservation();
            }
        }
Example #23
0
 public PersonDayWrapper(IPersonDay personDay, IPersonWrapper personWrapper, IHouseholdDayWrapper householdDayWrapper)
     : base(personDay, personWrapper, householdDayWrapper)
 {
     _personDay = (IActumPersonDay)personDay;
 }
Example #24
0
        private void RunModel(ChoiceProbabilityCalculator choiceProbabilityCalculator, IPersonDayWrapper personDay, IHouseholdDayWrapper householdDay, int choice = Constants.DEFAULT_VALUE)
        {
            IHouseholdWrapper household = personDay.Household;
            IPersonWrapper    person    = personDay.Person;

            IEnumerable <PersonDayWrapper> orderedPersonDays = householdDay.PersonDays.OrderBy(p => p.GetJointTourParticipationPriority()).ToList().Cast <PersonDayWrapper>();

            int countMandatory    = (from personDayHH in orderedPersonDays where personDayHH.PatternType == 1 select personDayHH.PatternType).Count();
            int countNonMandatory = (from personDayHH in orderedPersonDays where personDayHH.PatternType == 2 select personDayHH.PatternType).Count();
            int countAtHome       = (from personDayHH in orderedPersonDays where personDayHH.PatternType == 3 select personDayHH.PatternType).Count();

            int carOwnership =
                household.VehiclesAvailable == 0
                            ? Global.Settings.CarOwnerships.NoCars
                            : household.VehiclesAvailable < household.HouseholdTotals.DrivingAgeMembers
                                ? Global.Settings.CarOwnerships.LtOneCarPerAdult
                                : Global.Settings.CarOwnerships.OneOrMoreCarsPerAdult;

            int noCarsFlag         = FlagUtility.GetNoCarsFlag(carOwnership);
            int carCompetitionFlag = FlagUtility.GetCarCompetitionFlag(carOwnership);

            double workTourLogsum    = 0;
            double schoolPclUniStu   = 0;
            double schoolPclStudents = 0;
            int    noUsualWorkZone   = 1;


            if (personDay.Person.UsualWorkParcelId != Constants.DEFAULT_VALUE && personDay.Person.UsualWorkParcelId != Global.Settings.OutOfRegionParcelId)
            {
                if (personDay.Person.UsualDeparturePeriodFromWork != Constants.DEFAULT_VALUE && personDay.Person.UsualArrivalPeriodToWork != Constants.DEFAULT_VALUE)
                {
                    ChoiceProbabilityCalculator.Alternative nestedAlternative = Global.ChoiceModelSession.Get <WorkTourModeTimeModel>().RunNested(personDay, personDay.Person.Household.ResidenceParcel, personDay.Person.UsualWorkParcel, (int)personDay.Person.UsualArrivalPeriodToWork, (int)personDay.Person.UsualDeparturePeriodFromWork, personDay.Person.Household.HouseholdTotals.DrivingAgeMembers);
                    workTourLogsum = nestedAlternative == null ? 0 : nestedAlternative.ComputeLogsum();
                }
                else
                {
                    ChoiceProbabilityCalculator.Alternative nestedAlternative = Global.ChoiceModelSession.Get <WorkTourModeTimeModel>().RunNested(personDay, personDay.Person.Household.ResidenceParcel, personDay.Person.UsualWorkParcel, Global.Settings.Times.EightAM, Global.Settings.Times.FivePM, personDay.Person.Household.HouseholdTotals.DrivingAgeMembers);
                    workTourLogsum = nestedAlternative == null ? 0 : nestedAlternative.ComputeLogsum();
                }

                noUsualWorkZone = 0;
            }

            if (personDay.Person.UsualSchoolParcelId != 0 && personDay.Person.UsualSchoolParcelId != -1 && personDay.Person.UsualSchoolParcelId != Global.Settings.OutOfRegionParcelId)
            {
                schoolPclUniStu = Math.Log(1 + (personDay.Person.UsualSchoolParcel.StudentsUniversityBuffer2)) / 10;
                ChoiceProbabilityCalculator.Alternative schoolNestedAlternative = Global.ChoiceModelSession.Get <SchoolTourModeTimeModel>().RunNested(personDay, personDay.Person.Household.ResidenceParcel, personDay.Person.UsualSchoolParcel, Global.Settings.Times.EightAM, Global.Settings.Times.TwoPM, personDay.Person.Household.HouseholdTotals.DrivingAgeMembers);
                schoolPclStudents = Math.Log(1 + (personDay.Person.UsualSchoolParcel.GetStudentsK12())) / 10;
            }


            // No mandatory stops
            ChoiceProbabilityCalculator.Alternative alternative = choiceProbabilityCalculator.GetAlternative(0, true, choice == 0);
            alternative.Choice = 0;

            // Work stop(s)
            alternative        = choiceProbabilityCalculator.GetAlternative(1, personDay.Person.IsWorker, choice == 1);
            alternative.Choice = 1;
            alternative.AddUtilityTerm(21, 1);
            alternative.AddUtilityTerm(22, (personDay.WorkTours + personDay.SchoolTours > 1).ToFlag());
            alternative.AddUtilityTerm(24, workTourLogsum);
            alternative.AddUtilityTerm(26, household.Has0To25KIncome.ToFlag());
            alternative.AddUtilityTerm(27, (person.Age < 30).ToFlag());
            alternative.AddUtilityTerm(29, noUsualWorkZone);
            alternative.AddUtilityTerm(30, countMandatory);
            alternative.AddUtilityTerm(31, countAtHome);
            alternative.AddUtilityTerm(33, person.IsPartTimeWorker.ToFlag());
            alternative.AddUtilityTerm(34, person.IsUniversityStudent.ToFlag());
            alternative.AddUtilityTerm(35, household.Has100KPlusIncome.ToFlag());

            // School stop(s)
            alternative        = choiceProbabilityCalculator.GetAlternative(2, personDay.Person.IsStudent, choice == 2);
            alternative.Choice = 2;
            alternative.AddUtilityTerm(41, 1);
            alternative.AddUtilityTerm(42, (personDay.SchoolTours == 0).ToFlag());
            alternative.AddUtilityTerm(45, person.IsChildUnder5.ToFlag());
            alternative.AddUtilityTerm(46, person.IsUniversityStudent.ToFlag());
            alternative.AddUtilityTerm(49, (household.HouseholdTotals.AllWorkers >= 2).ToFlag());
            alternative.AddUtilityTerm(50, carCompetitionFlag + noCarsFlag);
            alternative.AddUtilityTerm(53, (household.HouseholdTotals.ChildrenUnder16 > 2).ToFlag());
            alternative.AddUtilityTerm(54, schoolPclStudents);
            alternative.AddUtilityTerm(55, schoolPclUniStu);
            alternative.AddUtilityTerm(56, (person.Age > 25).ToFlag());
            alternative.AddUtilityTerm(59, personDay.Person.Household.ResidenceParcel.C34RatioBuffer1());


            // Work and school stops
            alternative        = choiceProbabilityCalculator.GetAlternative(3, (personDay.Person.IsWorker && personDay.Person.IsStudent), choice == 3);
            alternative.Choice = 3;
            alternative.AddUtilityTerm(61, 1);
        }
        public int Run(IPersonDayWrapper personDay, IHouseholdDayWrapper householdDay, int nCallsForTour, int[] simulatedMandatoryTours, int choice)
        {
            // to know what the last choice was for a person on the previous step


            if (personDay == null)
            {
                throw new ArgumentNullException("personDay");
            }

            personDay.Person.ResetRandom(904 + nCallsForTour);

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

            var choiceProbabilityCalculator = _helpers[ParallelUtility.threadLocalAssignedIndex.Value].GetChoiceProbabilityCalculator(((personDay.Person.Id * 10 + personDay.Day) * 397) ^ nCallsForTour);

            if (_helpers[ParallelUtility.threadLocalAssignedIndex.Value].ModelIsInEstimationMode)
            {
                RunModel(choiceProbabilityCalculator, personDay, householdDay, nCallsForTour, simulatedMandatoryTours, choice);
                choiceProbabilityCalculator.WriteObservation();
            }
            else if (Global.Configuration.TestEstimationModelInApplicationMode)
            {
                Global.Configuration.IsInEstimationMode = false;
                RunModel(choiceProbabilityCalculator, personDay, householdDay, nCallsForTour, simulatedMandatoryTours);
                var observedChoice  = choice;
                var simulatedChoice = choiceProbabilityCalculator.SimulateChoice(personDay.Household.RandomUtility, personDay.Id, choice);
                Global.Configuration.IsInEstimationMode = true;
            }

            //                else if (Global.Configuration.TestEstimationModelInApplicationMode==true){

            //                Global.Configuration.IsInEstimationMode = false;

            //                if (householdDay.Household.Id == 2015) {
            //                    bool testbreak = true;
            //                }
            //                RunModel(choiceProbabilityCalculator, personDay, householdDay, nCallsForTour, simulatedMandatoryTours);

            // need to determine the choice on this particular simulated tour
            //                int[] totalMandatoryTours = new int[4];

            //                totalMandatoryTours[1] = personDay.UsualWorkplaceTours;
            //                totalMandatoryTours[2] = personDay.WorkTours - totalMandatoryTours[1];
            //                totalMandatoryTours[3] = personDay.SchoolTours;
            //                totalMandatoryTours[0] = totalMandatoryTours[1] + totalMandatoryTours[2] + totalMandatoryTours[3];
            //                if (personDay.UsualWorkplaceTours + personDay.SchoolTours > 0) {
            //                            personDay.HasMandatoryTourToUsualLocation = true;
            //                        }

            //using nCallsForTour - 1 will give the choice
            //                if (nCallsForTour - 1 < totalMandatoryTours[1]) { choice = 1; }
            //                else if (nCallsForTour - 1 < totalMandatoryTours[1] + totalMandatoryTours[2]) { choice = 2; }
            //                else if (nCallsForTour - 1 < totalMandatoryTours[0]) { choice = 3; }
            //                else { choice = 0; }

            //                var observedChoice = choice ;
            //                var simulatedChoice =choiceProbabilityCalculator.SimulateChoice(personDay.Household.RandomUtility, personDay.Id, observedChoice);

            //                int tourPurpose =0;

            //                    if ( simulatedChoice!= null)
            //                    {
            //                    tourPurpose = (int) simulatedChoice.Choice;
            //                    }

            //                choice = tourPurpose;

            //                Global.Configuration.IsInEstimationMode = true;
            //            }

            else
            {
                if (householdDay.Household.Id == 2015)
                {
                    bool testbreak = true;
                }
                RunModel(choiceProbabilityCalculator, personDay, householdDay, nCallsForTour, simulatedMandatoryTours);
                var chosenAlternative = choiceProbabilityCalculator.SimulateChoice(personDay.Household.RandomUtility);
                int tourPurpose       = (int)chosenAlternative.Choice;
                if (tourPurpose == 1)
                {
                    personDay.UsualWorkplaceTours++;
                    personDay.WorkTours++;
                }
                else if (tourPurpose == 2)
                {
                    personDay.WorkTours++;
                }
                else if (tourPurpose == 3)
                {
                    personDay.SchoolTours++;
                }
                choice = tourPurpose;
            }

            return(choice);
        }
 public int Run(IPersonDayWrapper personDay, IHouseholdDayWrapper householdDay, int nCallsForTour, int[] simulatedMandatoryTours)
 {
     return(Run(personDay, householdDay, nCallsForTour, simulatedMandatoryTours, Global.Settings.Purposes.NoneOrHome));
 }
        private void RunModel(ChoiceProbabilityCalculator choiceProbabilityCalculator, IPersonDayWrapper personDay, IHouseholdDayWrapper householdDay, int nCallsForTour, int[] simulatedMandatoryTours, int choice = Constants.DEFAULT_VALUE)
        {
            var household = personDay.Household;

            IEnumerable <PersonDayWrapper> orderedPersonDays = householdDay.PersonDays.OrderBy(p => p.GetJointTourParticipationPriority()).ToList().Cast <PersonDayWrapper>();


            var carOwnership =
                household.VehiclesAvailable == 0
                                 ? Global.Settings.CarOwnerships.NoCars
                                 : household.VehiclesAvailable < household.HouseholdTotals.DrivingAgeMembers
                                      ? Global.Settings.CarOwnerships.LtOneCarPerAdult
                                      : Global.Settings.CarOwnerships.OneOrMoreCarsPerAdult;

            var noCarsFlag         = FlagUtility.GetNoCarsFlag(carOwnership);
            var carCompetitionFlag = FlagUtility.GetCarCompetitionFlag(carOwnership);

            var votALSegment         = household.GetVotALSegment();
            var transitAccessSegment = household.ResidenceParcel.TransitAccessSegment();

            Double workTourLogsum    = 0;
            Double schoolTourLogsum  = 0;
            Double schoolPclUniStu   = 0;
            Double schoolPclStudents = 0;
            Double schoolIntrDens    = 0;
            Double workPclWrkrs      = 0;
            Double workIntrDens      = 0;
            int    noUsualWorkZone   = 1;


            if (personDay.Person.UsualWorkParcelId != Constants.DEFAULT_VALUE && personDay.Person.UsualWorkParcelId != Global.Settings.OutOfRegionParcelId)
            {
                if (personDay.Person.UsualDeparturePeriodFromWork != Constants.DEFAULT_VALUE && personDay.Person.UsualArrivalPeriodToWork != Constants.DEFAULT_VALUE)
                {
                    var nestedAlternative = Global.ChoiceModelSession.Get <WorkTourModeTimeModel>().RunNested(personDay, personDay.Person.Household.ResidenceParcel, personDay.Person.UsualWorkParcel, (int)personDay.Person.UsualArrivalPeriodToWork, (int)personDay.Person.UsualDeparturePeriodFromWork, personDay.Person.Household.HouseholdTotals.DrivingAgeMembers);
                    workTourLogsum = nestedAlternative == null ? 0 : nestedAlternative.ComputeLogsum();
                    workPclWrkrs   = Math.Log(1 + (personDay.Person.UsualWorkParcel.EmploymentTotalBuffer2)) / 10;
                    workIntrDens   = Math.Log(1 + personDay.Person.UsualWorkParcel.C34RatioBuffer1());
                }
                else
                {
                    var nestedAlternative = Global.ChoiceModelSession.Get <WorkTourModeTimeModel>().RunNested(personDay, personDay.Person.Household.ResidenceParcel, personDay.Person.UsualWorkParcel, Global.Settings.Times.EightAM, Global.Settings.Times.FivePM, personDay.Person.Household.HouseholdTotals.DrivingAgeMembers);
                    workTourLogsum = nestedAlternative == null ? 0 : nestedAlternative.ComputeLogsum();
                }

                noUsualWorkZone = 0;
            }


            if (personDay.Person.UsualSchoolParcelId != 0 && personDay.Person.UsualSchoolParcelId != -1 && personDay.Person.UsualSchoolParcelId != Global.Settings.OutOfRegionParcelId)
            {
                schoolPclUniStu = Math.Log(1 + (personDay.Person.UsualSchoolParcel.StudentsUniversityBuffer2)) / 10;
                var schoolNestedAlternative = Global.ChoiceModelSession.Get <SchoolTourModeTimeModel>().RunNested(personDay, personDay.Person.Household.ResidenceParcel, personDay.Person.UsualSchoolParcel, Global.Settings.Times.EightAM, Global.Settings.Times.TwoPM, personDay.Person.Household.HouseholdTotals.DrivingAgeMembers);
                schoolTourLogsum = schoolNestedAlternative == null ? 0 : schoolNestedAlternative.ComputeLogsum();
            }


            int countNonMandatory = (from personDayHH in orderedPersonDays where personDayHH.PatternType == 2 select personDayHH.PatternType).Count();

            bool schoolAvailableFlag = true;

            if (!personDay.Person.IsStudent || (!Global.Configuration.IsInEstimationMode && personDay.Person.UsualSchoolParcel == null))
            {
                schoolAvailableFlag = false;
            }

            // NONE_OR_HOME

            var alternative = choiceProbabilityCalculator.GetAlternative(Global.Settings.Purposes.NoneOrHome, nCallsForTour > 1, choice == Global.Settings.Purposes.NoneOrHome);

            alternative.Choice = Global.Settings.Purposes.NoneOrHome;
            alternative.AddUtilityTerm(3, (nCallsForTour > 2).ToFlag());


            // USUAL WORK
            alternative        = choiceProbabilityCalculator.GetAlternative(1, (personDay.Person.UsualWorkParcelId > 0 && simulatedMandatoryTours[2] == 0 && simulatedMandatoryTours[3] == 0), choice == 1);
            alternative.Choice = 1;
            alternative.AddUtilityTerm(21, 1);
            alternative.AddUtilityTerm(23, workTourLogsum);
            alternative.AddUtilityTerm(25, (personDay.Person.IsPartTimeWorker).ToFlag());
            alternative.AddUtilityTerm(26, (personDay.Person.IsUniversityStudent).ToFlag());
            alternative.AddUtilityTerm(28, (personDay.Person.Household.Has100KPlusIncome).ToFlag());
            alternative.AddUtilityTerm(29, personDay.Person.Household.ResidenceParcel.MixedUse2Index1());
            alternative.AddUtilityTerm(30, (personDay.Person.Age <= 30).ToFlag());
            alternative.AddUtilityTerm(31, workPclWrkrs);
            alternative.AddUtilityTerm(32, ((simulatedMandatoryTours[1] > 0).ToFlag()));
            alternative.AddUtilityTerm(33, workIntrDens);
            alternative.AddUtilityTerm(36, (personDay.WorksAtHomeFlag));
            alternative.AddUtilityTerm(38, (personDay.Person.Household.ResidenceParcel.GetDistanceToTransit() > 1).ToFlag());

            // OTHER WORK
            alternative        = choiceProbabilityCalculator.GetAlternative(2, (personDay.Person.IsWorker && simulatedMandatoryTours[3] == 0), choice == 2);
            alternative.Choice = 2;
            alternative.AddUtilityTerm(41, 1);
            alternative.AddUtilityTerm(42, (personDay.Person.IsPartTimeWorker).ToFlag());
            alternative.AddUtilityTerm(43, (personDay.Person.IsUniversityStudent).ToFlag());
            alternative.AddUtilityTerm(45, personDay.Person.Household.ResidenceParcel.MixedUse2Index1());
            alternative.AddUtilityTerm(47, (personDay.Person.Age <= 30).ToFlag());
            alternative.AddUtilityTerm(48, noUsualWorkZone);
            alternative.AddUtilityTerm(49, workIntrDens);
            alternative.AddUtilityTerm(50, workPclWrkrs);
            alternative.AddUtilityTerm(51, countNonMandatory);
            alternative.AddUtilityTerm(52, ((simulatedMandatoryTours[2] > 0).ToFlag()));
            alternative.AddUtilityTerm(53, (household.HouseholdTotals.AllWorkers == 1).ToFlag());
            alternative.AddUtilityTerm(55, noCarsFlag + carCompetitionFlag);
            alternative.AddUtilityTerm(56, (personDay.Person.Household.ResidenceParcel.GetDistanceToTransit() > 1).ToFlag());
            alternative.AddUtilityTerm(57, (personDay.Person.Household.Has0To25KIncome).ToFlag());

            // SCHOOL
            alternative        = choiceProbabilityCalculator.GetAlternative(3, schoolAvailableFlag, choice == 3);
            alternative.Choice = 3;
            alternative.AddUtilityTerm(61, 1);
            alternative.AddUtilityTerm(62, schoolTourLogsum);
            alternative.AddUtilityTerm(63, noCarsFlag + carCompetitionFlag);
            alternative.AddUtilityTerm(64, personDay.Person.Household.ResidenceParcel.MixedUse2Index1());
            alternative.AddUtilityTerm(65, (personDay.Person.IsChildUnder5).ToFlag());
            alternative.AddUtilityTerm(66, (personDay.Person.IsUniversityStudent).ToFlag());
            alternative.AddUtilityTerm(67, (personDay.Person.IsDrivingAgeStudent).ToFlag());
            alternative.AddUtilityTerm(68, schoolPclUniStu);
            alternative.AddUtilityTerm(69, schoolPclStudents);
            alternative.AddUtilityTerm(71, ((simulatedMandatoryTours[3] > 0).ToFlag()));
            alternative.AddUtilityTerm(72, schoolIntrDens);
            alternative.AddUtilityTerm(73, (personDay.Person.Age > 25).ToFlag());
            alternative.AddUtilityTerm(74, (personDay.Person.Household.ResidenceParcel.GetDistanceToTransit() > 1).ToFlag());
        }
        public void Run(IHouseholdDayWrapper householdDay, ITourWrapper tour,
                        int constrainedMode, int constrainedArrivalTime, int constrainedDepartureTime)
        {
            if (tour == null)
            {
                throw new ArgumentNullException("tour");
            }

            //HTourModeTime.InitializeTourModeTimes();

            tour.PersonDay.ResetRandom(50 + tour.Sequence - 1);

            if (Global.Configuration.IsInEstimationMode)
            {
                if (Global.Configuration.EstimationModel != CHOICE_MODEL_NAME)
                {
                    return;
                }
                // JLB 20140421 add the following to keep from estimatign twice for the same tour
                if (tour.DestinationModeAndTimeHaveBeenSimulated)
                {
                    return;
                }
                if (tour.DestinationParcel == null || tour.OriginParcel == null || tour.Mode < Global.Settings.Modes.Walk || tour.Mode > Global.Settings.Modes.SchoolBus)
                {
                    return;
                }
            }

            // set remaining inputs

            HTourModeTime.SetModeTimeImpedances(householdDay, tour, constrainedMode, constrainedArrivalTime, constrainedDepartureTime, -1, -1.0);

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

            if (_helpers[ParallelUtility.threadLocalAssignedIndex.Value].ModelIsInEstimationMode)
            {
                HTourModeTime observedChoice = new HTourModeTime(tour.Mode, tour.DestinationArrivalTime, tour.DestinationDepartureTime);

                RunModel(choiceProbabilityCalculator, householdDay, tour, tour.DestinationParcel, tour.Household.VehiclesAvailable,
                         constrainedMode, constrainedArrivalTime, constrainedDepartureTime,
                         observedChoice);

                choiceProbabilityCalculator.WriteObservation();
            }
            else if (Global.Configuration.TestEstimationModelInApplicationMode)
            {
                Global.Configuration.IsInEstimationMode = false;

                RunModel(choiceProbabilityCalculator, householdDay, tour, tour.DestinationParcel, tour.Household.VehiclesAvailable,
                         constrainedMode, constrainedArrivalTime, constrainedDepartureTime);

                HTourModeTime observedChoice = new HTourModeTime(tour.Mode, tour.DestinationArrivalTime, tour.DestinationDepartureTime);

                ChoiceProbabilityCalculator.Alternative simulatedChoice = choiceProbabilityCalculator.SimulateChoice(tour.Household.RandomUtility, tour.Id, observedChoice.Index);

                Global.Configuration.IsInEstimationMode = true;
            }
            else
            {
                HTourModeTime choice;

                if (constrainedMode > 0 && constrainedArrivalTime > 0 && constrainedDepartureTime > 0)
                {
                    choice = new HTourModeTime(constrainedMode, constrainedArrivalTime, constrainedDepartureTime);
                }
                else
                {
                    RunModel(choiceProbabilityCalculator, householdDay, tour, tour.DestinationParcel, tour.Household.VehiclesAvailable,
                             constrainedMode, constrainedArrivalTime, constrainedDepartureTime);
                    ChoiceProbabilityCalculator.Alternative simulatedChoice = choiceProbabilityCalculator.SimulateChoice(tour.Household.RandomUtility);

                    if (simulatedChoice == null)
                    {
                        Global.PrintFile.WriteNoAlternativesAvailableWarning(CHOICE_MODEL_NAME, "Run", tour.PersonDay.Id);
                        if (!Global.Configuration.IsInEstimationMode)
                        {
                            tour.PersonDay.IsValid = false;
                            tour.PersonDay.HouseholdDay.IsValid = false;
                        }
                        return;
                    }
                    choice = (HTourModeTime)simulatedChoice.Choice;
                }

                tour.Mode = choice.Mode;
                MinuteSpan arrivalPeriod   = choice.ArrivalPeriod;
                MinuteSpan departurePeriod = choice.DeparturePeriod;
                //use constrained times to set temporary arrival and departure times with minimum duration of stay for time window calculations
                if (constrainedArrivalTime > 0 || constrainedDepartureTime > 0)
                {
                    if (constrainedArrivalTime > 0)
                    {
                        tour.DestinationArrivalTime = constrainedArrivalTime;
                    }
                    else
                    {
                        tour.DestinationArrivalTime = Math.Min(arrivalPeriod.End, constrainedDepartureTime - Global.Settings.Times.MinimumActivityDuration);
                    }
                    if (constrainedDepartureTime > 0)
                    {
                        tour.DestinationDepartureTime = constrainedDepartureTime;
                    }
                    else
                    {
                        tour.DestinationDepartureTime = Math.Max(departurePeriod.Start, constrainedArrivalTime + Global.Settings.Times.MinimumActivityDuration);
                    }
                }
                //or if times aren't constrained use periods to set temporary arrival and departure times with minimum duration of stay for time window calculations
                else if (arrivalPeriod == departurePeriod)
                {
                    int departureTime = Math.Max(choice.GetRandomDepartureTime(householdDay, tour), departurePeriod.Start + Global.Settings.Times.MinimumActivityDuration);
                    tour.DestinationArrivalTime   = departureTime - Global.Settings.Times.MinimumActivityDuration;
                    tour.DestinationDepartureTime = departureTime;
                }
                else if (arrivalPeriod.End == departurePeriod.Start - 1)
                {
                    tour.DestinationArrivalTime   = arrivalPeriod.End;
                    tour.DestinationDepartureTime = arrivalPeriod.End + Global.Settings.Times.MinimumActivityDuration;
                }
                else
                {
                    tour.DestinationArrivalTime   = arrivalPeriod.End;
                    tour.DestinationDepartureTime = departurePeriod.Start;
                }
            }
        }
        private void RunModel(ChoiceProbabilityCalculator choiceProbabilityCalculator, IHouseholdDayWrapper householdDay, ITourWrapper tour,
                              IParcelWrapper destinationParcel, int householdCars,
                              int constrainedMode, int constrainedArrivalTime, int constrainedDepartureTime, HTourModeTime choice = null)
        {
            IHouseholdWrapper household = tour.Household;
            IPersonWrapper    person    = tour.Person;
            IPersonDayWrapper personDay = tour.PersonDay;

            Framework.DomainModels.Models.IHouseholdTotals householdTotals = household.HouseholdTotals;

            // household inputs
            int childrenUnder5         = householdTotals.ChildrenUnder5;
            int childrenAge5Through15  = householdTotals.ChildrenAge5Through15;
            int nonworkingAdults       = householdTotals.NonworkingAdults;
            int retiredAdults          = householdTotals.RetiredAdults;
            int onePersonHouseholdFlag = household.IsOnePersonHousehold.ToFlag();
            int twoPersonHouseholdFlag = household.IsTwoPersonHousehold.ToFlag();
            //var householdCars = household.VehiclesAvailable; MABADD now an input parameter
            int noCarsInHouseholdFlag   = household.GetFlagForNoCarsInHousehold(householdCars);
            int carsLessThanDriversFlag = household.GetFlagForCarsLessThanDrivers(householdCars);
            int carsLessThanWorkersFlag = household.GetFlagForCarsLessThanWorkers(householdCars);
            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();
            int maleFlag              = person.IsMale.ToFlag();
            int ageUnder30Flag        = person.AgeIsLessThan30.ToFlag();
            int ageBetween51And98Flag = person.AgeIsBetween51And98.ToFlag();
            int adultFlag             = person.IsAdult.ToFlag();

            // person-day inputs
            int homeBasedToursOnlyFlag          = (personDay == null) ? 1 : personDay.OnlyHomeBasedToursExist().ToFlag();
            int firstSimulatedHomeBasedTourFlag = (personDay == null) ? 1 : personDay.IsFirstSimulatedHomeBasedTour().ToFlag();
            int laterSimulatedHomeBasedTourFlag = (personDay == null) ? 0 : personDay.IsLaterSimulatedHomeBasedTour().ToFlag();
            int totalStops              = (personDay == null) ? 0 : personDay.GetTotalStops();
            int totalSimulatedStops     = (personDay == null) ? 0 : personDay.GetTotalSimulatedStops();
            int escortStops             = (personDay == null) ? 0 : personDay.EscortStops;
            int homeBasedTours          = (personDay == null) ? 1 : personDay.HomeBasedTours;
            int simulatedHomeBasedTours = (personDay == null) ? 0 : 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            recreationTourFlag       = tour.IsRecreationPurpose().ToFlag();
            int            medicalTourFlag          = tour.IsMedicalPurpose().ToFlag();
            IParcelWrapper originParcel             = tour.OriginParcel;
            //var destinationParcel = tour.DestinationParcel; MABADD now an input parameter
            int jointTourFlag        = (tour.JointTourSequence > 0) ? 1 : 0;
            int partialHalfTour1Flag = (tour.PartialHalfTour1Sequence > 0) ? 1 : 0;
            int partialHalfTour2Flag = (tour.PartialHalfTour2Sequence > 0) ? 1 : 0;
            int fullHalfTour1Flag    = (tour.FullHalfTour1Sequence > 0) ? 1 : 0;
            int fullHalfTour2Flag    = (tour.FullHalfTour2Sequence > 0) ? 1 : 0;
            int parentTourMode       = tour.ParentTour == null ? 0 : tour.ParentTour.Mode;


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

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

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

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

            ITimeWindow timeWindow = (householdDay == null) ? new TimeWindow() : tour.GetRelevantTimeWindow(householdDay);
            int         totalMinutesAvailableInDay = timeWindow.TotalAvailableMinutes(1, 1440);


            int bigPeriodCount = DayPeriod.H_BIG_DAY_PERIOD_TOTAL_TOUR_TIMES;
            int nPeriodCombs   = bigPeriodCount * (bigPeriodCount + 1) / 2;


            //set components
            int componentIndex = 0;
            int periodComb     = -1;

            bool useTimeComponents = Global.Configuration.IsInEstimationMode || constrainedArrivalTime == 0 || constrainedDepartureTime == 0;

            if (useTimeComponents)
            {
                for (int arrivalPeriodIndex = 0; arrivalPeriodIndex < bigPeriodCount; arrivalPeriodIndex++)
                {
                    MinuteSpan arrivalPeriod = DayPeriod.HBigDayPeriods[arrivalPeriodIndex];
                    int        arrivalPeriodAvailableMinutes = timeWindow.TotalAvailableMinutes(arrivalPeriod.Start, arrivalPeriod.End);

                    for (int departurePeriodIndex = arrivalPeriodIndex; departurePeriodIndex < bigPeriodCount; departurePeriodIndex++)
                    {
                        MinuteSpan departurePeriod = DayPeriod.HBigDayPeriods[departurePeriodIndex];
                        int        departurePeriodAvailableMinutes = timeWindow.TotalAvailableMinutes(departurePeriod.Start, departurePeriod.End);

                        if (arrivalPeriod == departurePeriod)
                        {
                            componentIndex = arrivalPeriodIndex;
                            choiceProbabilityCalculator.CreateUtilityComponent(componentIndex);
                            ChoiceProbabilityCalculator.Component arrivalComponent = choiceProbabilityCalculator.GetUtilityComponent(componentIndex);

                            if (arrivalPeriodAvailableMinutes > 0)
                            {
                                double hoursArrival = arrivalPeriod.Middle / 60.0;
                                int    firstCoef    = 300;
                                arrivalComponent.AddUtilityTerm(300, Math.Log(arrivalPeriodAvailableMinutes));
                                //arrival shift variables
                                arrivalComponent.AddUtilityTerm(firstCoef + 2, partTimeWorkerFlag * hoursArrival);
                                arrivalComponent.AddUtilityTerm(firstCoef + 3, nonworkingAdultFlag * hoursArrival);
                                arrivalComponent.AddUtilityTerm(firstCoef + 4, universityStudentFlag * hoursArrival);
                                arrivalComponent.AddUtilityTerm(firstCoef + 5, retiredAdultFlag * hoursArrival);
                                arrivalComponent.AddUtilityTerm(firstCoef + 6, drivingAgeStudentFlag * hoursArrival);
                                arrivalComponent.AddUtilityTerm(firstCoef + 7, childAge5Through15Flag * hoursArrival);
                                arrivalComponent.AddUtilityTerm(firstCoef + 8, childUnder5Flag * hoursArrival);
                                arrivalComponent.AddUtilityTerm(firstCoef + 9, escortTourFlag * hoursArrival);
                                arrivalComponent.AddUtilityTerm(firstCoef + 10, shoppingTourFlag * hoursArrival);
                                arrivalComponent.AddUtilityTerm(firstCoef + 11, mealTourFlag * hoursArrival);
                                arrivalComponent.AddUtilityTerm(firstCoef + 12, socialTourFlag * hoursArrival);
                                arrivalComponent.AddUtilityTerm(firstCoef + 13, personalBusinessTourFlag * hoursArrival);
                                arrivalComponent.AddUtilityTerm(firstCoef + 14, recreationTourFlag * hoursArrival);
                                arrivalComponent.AddUtilityTerm(firstCoef + 15, medicalTourFlag * hoursArrival);
                                arrivalComponent.AddUtilityTerm(firstCoef + 16, income0To25KFlag * hoursArrival);
                                arrivalComponent.AddUtilityTerm(firstCoef + 17, income100KPlusFlag * hoursArrival);
                                arrivalComponent.AddUtilityTerm(firstCoef + 18, highPrioritySameFlag * hoursArrival);
                                arrivalComponent.AddUtilityTerm(firstCoef + 19, lowPrioritySameFlag * hoursArrival);
                                arrivalComponent.AddUtilityTerm(firstCoef + 20, highPriorityDifferentFlag * hoursArrival);
                                arrivalComponent.AddUtilityTerm(firstCoef + 21, lowPriorityDifferentFlag * hoursArrival);
                                arrivalComponent.AddUtilityTerm(firstCoef + 22, jointTourFlag * hoursArrival);
                                arrivalComponent.AddUtilityTerm(firstCoef + 23, partialHalfTour1Flag * hoursArrival);
                                arrivalComponent.AddUtilityTerm(firstCoef + 24, fullHalfTour1Flag * hoursArrival);
                                arrivalComponent.AddUtilityTerm(firstCoef + 25, partialHalfTour2Flag * hoursArrival);
                                arrivalComponent.AddUtilityTerm(firstCoef + 26, fullHalfTour2Flag * hoursArrival);
                            }

                            componentIndex = bigPeriodCount + departurePeriodIndex;
                            choiceProbabilityCalculator.CreateUtilityComponent(componentIndex);
                            ChoiceProbabilityCalculator.Component departureComponent = choiceProbabilityCalculator.GetUtilityComponent(componentIndex);


                            if (departurePeriodAvailableMinutes > 0)
                            {
                                departureComponent.AddUtilityTerm(300, Math.Log(departurePeriodAvailableMinutes));
                            }
                        }
                        // set period combination component
                        periodComb++;
                        componentIndex = 2 * bigPeriodCount + periodComb;
                        choiceProbabilityCalculator.CreateUtilityComponent(componentIndex);
                        ChoiceProbabilityCalculator.Component combinationComponent = choiceProbabilityCalculator.GetUtilityComponent(componentIndex);

                        if (arrivalPeriodAvailableMinutes > 0 && departurePeriodAvailableMinutes > 0)
                        {
                            double hoursDuration = (departurePeriod.Middle - arrivalPeriod.Middle) / 60.0;

                            int firstCoef = 700;
                            //combination constants
                            combinationComponent.AddUtilityTerm(firstCoef + periodComb, 1.0);
                            // duration shift variables
                            combinationComponent.AddUtilityTerm(firstCoef + 31, escortTourFlag * hoursDuration);
                            combinationComponent.AddUtilityTerm(firstCoef + 32, shoppingTourFlag * hoursDuration);
                            combinationComponent.AddUtilityTerm(firstCoef + 33, mealTourFlag * hoursDuration);
                            combinationComponent.AddUtilityTerm(firstCoef + 34, socialTourFlag * hoursDuration);
                            combinationComponent.AddUtilityTerm(firstCoef + 35, personalBusinessTourFlag * hoursDuration);
                            combinationComponent.AddUtilityTerm(firstCoef + 36, recreationTourFlag * hoursDuration);
                            combinationComponent.AddUtilityTerm(firstCoef + 37, medicalTourFlag * hoursDuration);
                            combinationComponent.AddUtilityTerm(firstCoef + 38, highPrioritySameFlag * hoursDuration);
                            combinationComponent.AddUtilityTerm(firstCoef + 39, lowPrioritySameFlag * hoursDuration);
                            combinationComponent.AddUtilityTerm(firstCoef + 40, highPriorityDifferentFlag * hoursDuration);
                            combinationComponent.AddUtilityTerm(firstCoef + 41, lowPriorityDifferentFlag * hoursDuration);
                            combinationComponent.AddUtilityTerm(firstCoef + 42, partTimeWorkerFlag * hoursDuration);
                            combinationComponent.AddUtilityTerm(firstCoef + 43, jointTourFlag * hoursDuration);
                            combinationComponent.AddUtilityTerm(firstCoef + 44, partialHalfTour1Flag * hoursDuration);
                            combinationComponent.AddUtilityTerm(firstCoef + 45, fullHalfTour1Flag * hoursDuration);
                            combinationComponent.AddUtilityTerm(firstCoef + 46, partialHalfTour2Flag * hoursDuration);
                            combinationComponent.AddUtilityTerm(firstCoef + 47, fullHalfTour2Flag * hoursDuration);
                            // peak-to-peak variables
                            if (arrivalPeriod.Index == DayPeriod.AM_PEAK && departurePeriod.Index == DayPeriod.PM_PEAK)
                            {
                                combinationComponent.AddUtilityTerm(firstCoef + 48, fulltimeWorkerFlag);
                                combinationComponent.AddUtilityTerm(firstCoef + 49, income0To25KFlag);
                                combinationComponent.AddUtilityTerm(firstCoef + 50, income100KPlusFlag);
                            }
                        }
                    }
                }
            }

            for (int mode = Global.Settings.Modes.Walk; mode <= Global.Settings.Modes.SchoolBus; mode++)
            {
                componentIndex = 2 * bigPeriodCount + nPeriodCombs + mode - 1;
                choiceProbabilityCalculator.CreateUtilityComponent(componentIndex);
                ChoiceProbabilityCalculator.Component modeComponent = choiceProbabilityCalculator.GetUtilityComponent(componentIndex);

                if (mode == Global.Settings.Modes.SchoolBus)
                {
                    modeComponent.AddUtilityTerm(10, 1);
                    modeComponent.AddUtilityTerm(11, childUnder5Flag);
                    modeComponent.AddUtilityTerm(12, adultFlag);
                }
                else if (mode == Global.Settings.Modes.ParkAndRide)
                {
                    modeComponent.AddUtilityTerm(10, 1);
                    modeComponent.AddUtilityTerm(16, noCarsInHouseholdFlag);
                    modeComponent.AddUtilityTerm(17, carsLessThanWorkersFlag);
                    modeComponent.AddUtilityTerm(129, destinationParcel.MixedUse2Index1());
                    modeComponent.AddUtilityTerm(129, destinationParcel.TotalEmploymentDensity1() / 5000.0);
                    modeComponent.AddUtilityTerm(129, destinationParcel.NetIntersectionDensity1() / 50.0);
                    //modeComponent.AddUtilityTerm(123, Math.Log(destinationParcel.StopsTransitBuffer1 + 1));
                }
                else if (mode == Global.Settings.Modes.Transit)
                {
                    modeComponent.AddUtilityTerm(20, 1);
                    //        modeComponent.AddUtilityTerm(21, maleFlag);
                    modeComponent.AddUtilityTerm(22, ageUnder30Flag);
                    //    modeComponent.AddUtilityTerm(23, ageBetween51And98Flag);
                    modeComponent.AddUtilityTerm(24, income0To25KFlag);
                    //    modeComponent.AddUtilityTerm(25, income100KPlusFlag);
                    modeComponent.AddUtilityTerm(26, noCarsInHouseholdFlag);
                    modeComponent.AddUtilityTerm(27, carsLessThanDriversFlag);
                    modeComponent.AddUtilityTerm(129, destinationParcel.MixedUse2Index1());
                    modeComponent.AddUtilityTerm(129, destinationParcel.TotalEmploymentDensity1() / 5000.0);
                    modeComponent.AddUtilityTerm(129, destinationParcel.NetIntersectionDensity1() / 50.0);
                    //    modeComponent.AddUtilityTerm(124, originParcel.NetIntersectionDensity1()/50.0);
                    //    modeComponent.AddUtilityTerm(124, originParcel.HouseholdDensity1()/1000.0);
                    //    modeComponent.AddUtilityTerm(124, originParcel.MixedUse2Index1());
                    //modeComponent.AddUtilityTerm(123, Math.Log(destinationParcel.StopsTransitBuffer1 + 1));
                    //modeComponent.AddUtilityTerm(122, Math.Log(originParcel.StopsTransitBuffer1 + 1));
                }
                else if (mode == Global.Settings.Modes.Hov3)
                {
                    modeComponent.AddUtilityTerm(30, 1);
                    modeComponent.AddUtilityTerm(31, childrenUnder5);
                    modeComponent.AddUtilityTerm(32, childrenAge5Through15);
                    modeComponent.AddUtilityTerm(34, nonworkingAdults + retiredAdults);
                    modeComponent.AddUtilityTerm(38, onePersonHouseholdFlag);
                    modeComponent.AddUtilityTerm(39, twoPersonHouseholdFlag);
                    modeComponent.AddUtilityTerm(36, noCarsInHouseholdFlag);
                    modeComponent.AddUtilityTerm(37, carsLessThanDriversFlag);
                }
                else if (mode == Global.Settings.Modes.Hov2)
                {
                    modeComponent.AddUtilityTerm(31, childrenUnder5);
                    modeComponent.AddUtilityTerm(32, childrenAge5Through15);
                    modeComponent.AddUtilityTerm(34, nonworkingAdults + retiredAdults);
                    modeComponent.AddUtilityTerm(36, noCarsInHouseholdFlag);
                    modeComponent.AddUtilityTerm(37, carsLessThanDriversFlag);
                    modeComponent.AddUtilityTerm(40, 1);
                    modeComponent.AddUtilityTerm(41, onePersonHouseholdFlag);
                }
                else if (mode == Global.Settings.Modes.Sov)
                {
                    //    modeComponent.AddUtilityTerm(50, 1);
                    //    modeComponent.AddUtilityTerm(54, income0To25KFlag);
                    modeComponent.AddUtilityTerm(55, income100KPlusFlag);
                    modeComponent.AddUtilityTerm(57, carsLessThanWorkersFlag);
                }
                else if (mode == Global.Settings.Modes.Bike)
                {
                    modeComponent.AddUtilityTerm(60, 1);
                    modeComponent.AddUtilityTerm(61, maleFlag);
                    modeComponent.AddUtilityTerm(62, ageUnder30Flag);
                    modeComponent.AddUtilityTerm(63, ageBetween51And98Flag);
                    //        modeComponent.AddUtilityTerm(64, income0To25KFlag);
                    //      modeComponent.AddUtilityTerm(65, income100KPlusFlag);
                    modeComponent.AddUtilityTerm(66, noCarsInHouseholdFlag);
                    modeComponent.AddUtilityTerm(67, carsLessThanDriversFlag);
                    modeComponent.AddUtilityTerm(169, destinationParcel.MixedUse4Index2());
                    modeComponent.AddUtilityTerm(169, destinationParcel.TotalEmploymentDensity2() / 20000.0);
                    modeComponent.AddUtilityTerm(169, destinationParcel.NetIntersectionDensity2() / 200.0);
                    modeComponent.AddUtilityTerm(164, originParcel.NetIntersectionDensity2() / 200.0);
                    modeComponent.AddUtilityTerm(164, originParcel.HouseholdDensity2() / 4000.0);
                    modeComponent.AddUtilityTerm(164, originParcel.MixedUse4Index2());
                }
                else if (mode == Global.Settings.Modes.Walk)
                {
                    modeComponent.AddUtilityTerm(70, 1.0);
                    modeComponent.AddUtilityTerm(71, maleFlag);
                    modeComponent.AddUtilityTerm(72, ageUnder30Flag);
                    //        modeComponent.AddUtilityTerm(73, ageBetween51And98Flag);
                    //        modeComponent.AddUtilityTerm(74, income0To25KFlag);
                    modeComponent.AddUtilityTerm(75, income100KPlusFlag);
                    //        modeComponent.AddUtilityTerm(76, noCarsInHouseholdFlag);
                    modeComponent.AddUtilityTerm(77, carsLessThanDriversFlag);
                    modeComponent.AddUtilityTerm(179, destinationParcel.MixedUse4Index1());
                    modeComponent.AddUtilityTerm(179, destinationParcel.TotalEmploymentDensity1() / 5000.0);
                    modeComponent.AddUtilityTerm(179, destinationParcel.NetIntersectionDensity1() / 50.0);
                    modeComponent.AddUtilityTerm(179, originParcel.NetIntersectionDensity1() / 50.0);
                    modeComponent.AddUtilityTerm(179, originParcel.HouseholdDensity1() / 1000.0);
                    modeComponent.AddUtilityTerm(179, originParcel.MixedUse4Index1());
                }

                if (mode == Global.Settings.Modes.Walk || mode == Global.Settings.Modes.Bike || mode == Global.Settings.Modes.Hov2 ||
                    mode == Global.Settings.Modes.Hov3 || mode == Global.Settings.Modes.Transit)
                {
                    int firstCoef = 200 + 10 * mode;
                    //modeComponent.AddUtilityTerm(firstCoef + 0, escortTourFlag);
                    //modeComponent.AddUtilityTerm(firstCoef + 1, shoppingTourFlag);
                    //modeComponent.AddUtilityTerm(firstCoef + 2, mealTourFlag);
                    //modeComponent.AddUtilityTerm(firstCoef + 3, socialTourFlag);
                    //modeComponent.AddUtilityTerm(firstCoef + 4, personalBusinessTourFlag);
                    //modeComponent.AddUtilityTerm(firstCoef + 5, recreationTourFlag);
                    //    modeComponent.AddUtilityTerm(firstCoef + 6, medicalTourFlag);
                    //modeComponent.AddUtilityTerm(firstCoef + 7, jointTourFlag);
                    modeComponent.AddUtilityTerm(firstCoef + 8, Math.Min(partialHalfTour1Flag + partialHalfTour2Flag, 1.0));
                    modeComponent.AddUtilityTerm(firstCoef + 9, Math.Min(fullHalfTour1Flag + fullHalfTour2Flag, 1.0));

                    modeComponent.AddUtilityTerm(290 + mode, mode == parentTourMode ? 1 : 0);
                }
                modeComponent.AddUtilityTerm(298, mode >= Global.Settings.Modes.Sov && mode <= Global.Settings.Modes.Hov3 && parentTourMode == Global.Settings.Modes.Sov ? 1 : 0);
                modeComponent.AddUtilityTerm(299, mode >= Global.Settings.Modes.Sov && mode <= Global.Settings.Modes.Hov3 && parentTourMode >= Global.Settings.Modes.Hov2 && parentTourMode <= Global.Settings.Modes.Hov3 ? 1 : 0);
            }



            //loop on all alternatives, using modeTimes objects
            {
                foreach (HTourModeTime modeTimes in HTourModeTime.ModeTimes[ParallelUtility.threadLocalAssignedIndex.Value])
                {
                    MinuteSpan arrivalPeriod = modeTimes.ArrivalPeriod;
                    int        arrivalPeriodAvailableMinutes = timeWindow.TotalAvailableMinutes(arrivalPeriod.Start, arrivalPeriod.End);

                    MinuteSpan departurePeriod = modeTimes.DeparturePeriod;
                    int        departurePeriodAvailableMinutes = timeWindow.TotalAvailableMinutes(departurePeriod.Start, departurePeriod.End);
                    periodComb = modeTimes.PeriodCombinationIndex;

                    int mode = modeTimes.Mode;

                    int altIndex = modeTimes.Index;

                    //set availabillity based on time window variables and any constrained choices
                    bool available = (modeTimes.LongestFeasibleWindow != null) && (mode > 0) &&
                                     (mode != Global.Settings.Modes.Sov || (tour.Person.IsDrivingAge && tour.Household.VehiclesAvailable > 0)) &&
                                     (constrainedMode <= 0 || constrainedMode == mode) &&
                                     (constrainedArrivalTime <= 0 || (constrainedArrivalTime >= arrivalPeriod.Start && constrainedArrivalTime <= arrivalPeriod.End)) &&
                                     (constrainedDepartureTime <= 0 || (constrainedDepartureTime >= departurePeriod.Start && constrainedDepartureTime <= departurePeriod.End));


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

                    alternative.Choice = modeTimes; // JLB added 20130420

                    //alternative.AddNestedAlternative(HTourModeTime.TOTAL_TOUR_MODE_TIMES + periodComb + 1, periodComb, THETA_PARAMETER);

                    if (Global.Configuration.IsInEstimationMode && choice != null && altIndex == choice.Index)
                    {
                        Global.PrintFile.WriteLine("Aper Dper Mode {0} {1} {2} Travel Times {3} {4} Window {5} {6}",
                                                   arrivalPeriod.Index, departurePeriod.Index, mode,
                                                   modeTimes.ModeAvailableToDestination ? modeTimes.TravelTimeToDestination : -1,
                                                   modeTimes.ModeAvailableFromDestination ? modeTimes.TravelTimeFromDestination : -1,
                                                   modeTimes.LongestFeasibleWindow != null ? modeTimes.LongestFeasibleWindow.Start : -1,
                                                   modeTimes.LongestFeasibleWindow != null ? modeTimes.LongestFeasibleWindow.End : -1);
                    }

                    /*                if (altIndex == 0)
                     *                  {
                     *                      alternative.AddUtilityTerm(991, tour.Household.Id);
                     *                      alternative.AddUtilityTerm(992, tour.Person.Id);
                     *                      alternative.AddUtilityTerm(993, tour.PersonDay.Day);
                     *                      alternative.AddUtilityTerm(994, tour.Sequence);
                     *                      alternative.AddUtilityTerm(995, constrainedMode);
                     *                      alternative.AddUtilityTerm(996, constrainedArrivalTime);
                     *                      alternative.AddUtilityTerm(997, constrainedDepartureTime);
                     *                      alternative.AddUtilityTerm(998, tour.DestinationPurpose);
                     *                      alternative.AddUtilityTerm(999, (tour.ParentTour == null) ? 0 : 1);
                     *                  }
                     */
                    //if in application mode and combination is not available, can skip the rest
                    if (!Global.Configuration.IsInEstimationMode && !alternative.Available)
                    {
                        continue;
                    }
                    if (useTimeComponents)
                    {
                        // arrival period utility component
                        alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(arrivalPeriod.Index));

                        // departure period utility component
                        alternative.AddUtilityComponent(
                            choiceProbabilityCalculator.GetUtilityComponent(bigPeriodCount + departurePeriod.Index));

                        // period combination utility component
                        alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(2 * bigPeriodCount + periodComb));
                    }
                    // mode utility component
                    alternative.AddUtilityComponent(
                        choiceProbabilityCalculator.GetUtilityComponent(2 * bigPeriodCount + nPeriodCombs + mode - 1));

                    //even in estimation mode, do not need the rest of the code if not available
                    if (!alternative.Available)
                    {
                        continue;
                    }

                    // set parking cost for period combination
                    double parkingDuration = (departurePeriod == arrivalPeriod
                                               ? (arrivalPeriod.End - arrivalPeriod.Start) / 2.0
                                               : departurePeriod.Middle - arrivalPeriod.Middle) / 60.0;

                    // parking at work is free if no paid parking at work and tour goes to usual workplace
                    double destinationParkingCost = (!Global.Configuration.IsInEstimationMode &&
                                                     Global.Configuration.ShouldRunPayToParkAtWorkplaceModel &&
                                                     tour.Person.UsualWorkParcel != null &&
                                                     destinationParcel == tour.Person.UsualWorkParcel &&
                                                     person.PaidParkingAtWorkplace == 0)
                                                     ? 0.0
                                                     : destinationParcel.ParkingCostBuffer1(parkingDuration);
                    double parkingCostFraction = (mode == Global.Settings.Modes.Sov)
                                                  ? 1.0
                                                  : (mode == Global.Settings.Modes.Hov2)
                                                        ? 1.0 / Global.Configuration.Coefficients_HOV2CostDivisor_Work
                                                        : (mode == Global.Settings.Modes.Hov3)
                                                              ? 1.0 / Global.Configuration.Coefficients_HOV3CostDivisor_Work
                                                              : 0.0;


                    double minimumTimeNeeded = modeTimes.TravelTimeToDestination + modeTimes.TravelTimeFromDestination +
                                               Global.Settings.Times.MinimumActivityDuration;

                    alternative.AddUtilityTerm(1, modeTimes.GeneralizedTimeToDestination + modeTimes.GeneralizedTimeFromDestination);
                    //alternative.AddUtilityTerm(2, destinationParkingCost*parkingCostFraction);
                    //alternative.AddUtilityTerm(3,
                    //                           Math.Log(Math.Min(1140, modeTimes.LongestFeasibleWindow.End - modeTimes.LongestFeasibleWindow.Start -
                    //                                                     minimumTimeNeeded + 1.0 )));
                    // JLB 20140204 replaced coeff 3 with a different time window formulation:  time pressure
                    //    instead of having positive utility for increasing time window, have negative utility for decreasing time window
                    alternative.AddUtilityTerm(3,
                                               Math.Log(Math.Max(Constants.EPSILON, 1 -
                                                                 Math.Pow(minimumTimeNeeded / (Math.Min(1140, modeTimes.LongestFeasibleWindow.End - modeTimes.LongestFeasibleWindow.Start)), 0.3)
                                                                 )));

                    //alternative.AddUtilityTerm(4, Math.Log((totalMinutesAvailableInDay + 1.0)/(minimumTimeNeeded + 1.0)));
                    //alternative.AddUtilityTerm(4,
                    //                    Math.Log(Math.Max(Constants.EPSILON, 1 - minimumTimeNeeded/(Math.Min(1140, totalMinutesAvailableInDay)))));

                    //alternative.AddUtilityTerm(5,
                    //                           (maleFlag == 0 && mode == Global.Settings.Modes.Walk &&
                    //                            arrivalPeriod.Index >= DayPeriod.EVENING)
                    //                                   ? 1
                    //                                   : 0);
                    //    alternative.AddUtilityTerm(5,
                    //                               (maleFlag == 0 && mode == Global.Settings.Modes.Walk &&
                    //                                departurePeriod.Index >= DayPeriod.EVENING)
                    //                                   ? 1
                    //                                   : 0);
                }
            }
        }
Example #30
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)));
            }
        }