예제 #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;
             *          }
             */

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

            {
                foreach (HTourModeTime modeTimes in ModeTimes[ParallelUtility.threadLocalAssignedIndex.Value])
                {
                    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);
                    }
                }
            }
        }
예제 #2
0
파일: TourTime.cs 프로젝트: sfcta/DaySim
        public IMinuteSpan GetDestinationTimes(ITourWrapper tour)
        {
            if (tour == null)
            {
                throw new ArgumentNullException("tour");
            }

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

            return(timeWindow.GetMinuteSpan(tour.Household.RandomUtility, ArrivalPeriod.Start, ArrivalPeriod.End, DeparturePeriod.Start, DeparturePeriod.End));
        }
예제 #3
0
        public int GetRandomFeasibleMinute(ITripWrapper trip, HTripTime time)
        {
            if (trip == null || time == null)
            {
                throw new ArgumentNullException("trip time");
            }

            ITimeWindow timeWindow    = trip.Tour.ParentTour == null ? trip.Tour.PersonDay.TimeWindow : trip.Tour.ParentTour.TimeWindow;
            int         departureTime = timeWindow.GetAvailableMinute(trip.Household.RandomUtility, time.EarliestFeasibleDepatureTime, time.LatestFeasibleDepartureTime);

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

            return(departureTime);
        }
예제 #4
0
파일: TripTime.cs 프로젝트: sfcta/DaySim
        public int GetDepartureTime(ITripWrapper trip)
        {
            if (trip == null)
            {
                throw new ArgumentNullException("trip");
            }

            ITimeWindow timeWindow    = trip.Tour.ParentTour == null ? trip.Tour.PersonDay.TimeWindow : trip.Tour.ParentTour.TimeWindow;
            int         departureTime = timeWindow.GetAvailableMinute(trip.Household.RandomUtility, DeparturePeriod.Start, DeparturePeriod.End);

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

            return(departureTime);
        }
예제 #5
0
        public int GetRandomDepartureTime(IHouseholdDayWrapper householdDay, ITourWrapper tour)
        {
            if (tour == null)
            {
                throw new ArgumentNullException("trip");
            }

            ITimeWindow timeWindow = tour.GetRelevantTimeWindow(householdDay);

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

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

            return(departureTime);
        }
예제 #6
0
파일: TimeWindow.cs 프로젝트: sdrewc/DaySim
        public ITimeWindow IncorporateAnotherTimeWindow(ITimeWindow aOtherTimeWindow)
        {
            if (ValidTimeWindow() == false)
            {
                bool testBreak = true;
            }

            //replace this with deep clone method
            //TimeWindow otherTimeWindow = aOtherTimeWindow as TimeWindow;
            var otherTimeWindow = (TimeWindow)aOtherTimeWindow.DeepCloneToANewWindow();

            //set non-duplicates Keep to true in this time window
            int i = 0;
            int j = 0;

            foreach (var busySpan in _busyMinutes)
            {
                i++;
                busySpan.Keep = true;
                foreach (var otherBusySpan in _busyMinutes)
                {
                    j++;
                    if (i > j && busySpan.Start == otherBusySpan.Start &&
                        busySpan.End == otherBusySpan.End)
                    {
                        busySpan.Keep = false;
                    }
                }
            }
            i = 0;
            j = 0;
            foreach (var availableSpan in _availableMinutes)
            {
                availableSpan.Keep = true;
                foreach (var otherAvailableSpan in _availableMinutes)
                {
                    if (i > j && availableSpan.Start == otherAvailableSpan.Start &&
                        availableSpan.End == otherAvailableSpan.End)
                    {
                        availableSpan.Keep = false;
                    }
                }
            }

            //set non-duplicates Keep to true in other time window
            i = 0;
            j = 0;
            foreach (var busySpan in otherTimeWindow._busyMinutes)
            {
                busySpan.Keep = true;
                foreach (var otherBusySpan in _busyMinutes)
                {
                    if (i > j && busySpan.Start == otherBusySpan.Start &&
                        busySpan.End == otherBusySpan.End)
                    {
                        busySpan.Keep = false;
                    }
                }
            }
            i = 0;
            j = 0;
            foreach (var availableSpan in otherTimeWindow._availableMinutes)
            {
                availableSpan.Keep = true;
                foreach (var otherAvailableSpan in _availableMinutes)
                {
                    if (i > j && availableSpan.Start == otherAvailableSpan.Start &&
                        availableSpan.End == otherAvailableSpan.End)
                    {
                        availableSpan.Keep = false;
                    }
                }
            }

            //first, compare each pair of busy spans and don't keep ones that are completely surrounded by the other
            foreach (var newBusySpan in otherTimeWindow._busyMinutes)
            {
                //newBusySpan.Keep = true;

                foreach (var busySpan in _busyMinutes)
                {
                    if (busySpan.Keep)
                    {
                        if (newBusySpan.Start <= busySpan.Start && newBusySpan.End >= busySpan.End)
                        {
                            busySpan.Keep = false;
                        }
                        else if (newBusySpan.Start >= busySpan.Start && newBusySpan.End <= busySpan.End)
                        {
                            newBusySpan.Keep = false;
                        }
                    }
                }
            }

            // next compare again and combine those that partially overlap or are adjacent
            foreach (var newBusySpan in otherTimeWindow._busyMinutes)
            {
                foreach (var busySpan in _busyMinutes)
                {
                    if (newBusySpan.Keep && busySpan.Keep)
                    {
                        if (busySpan.Start >= newBusySpan.Start && busySpan.Start <= newBusySpan.End + 1)
                        {
                            busySpan.Start   = newBusySpan.Start;
                            newBusySpan.Keep = false;
                        }
                        else if (busySpan.End >= newBusySpan.Start - 1 && busySpan.End <= newBusySpan.End)
                        {
                            busySpan.End     = newBusySpan.End;
                            newBusySpan.Keep = false;
                        }
                    }
                }
            }
            // keep only newBusySpans that don't overlap (or completely surround) existing ones
            // check remaining existing ones for overlap, now that they may have been extended

            foreach (var busySpan in _busyMinutes)
            {
                foreach (var laterBusySpan in _busyMinutes.Where(s => s != busySpan && s.Keep && s.Start >= busySpan.Start))
                {
                    if (laterBusySpan.Start <= busySpan.End)
                    {
                        busySpan.End       = laterBusySpan.End;
                        laterBusySpan.Keep = false;
                    }
                }
            }

            _busyMinutes.RemoveAll(s => !s.Keep);

            foreach (var newBusySpan in otherTimeWindow._busyMinutes.Where(s => s.Keep))
            {
                _busyMinutes.Add(newBusySpan);
            }

            _busyMinutes = _busyMinutes.OrderBy(x => x.Start).ToList();

            _availableMinutes = GetAvailableMinutes();

            /* old code
             * int firstBusy = 0;
             * int nextAvailable = 0;
             * for (var i = 1; i <= Global.Settings.Times.MinutesInADay; i++) {
             *  if (otherTimeWindow.IsBusy(i) && firstBusy == 0) {
             *      firstBusy = i;
             *  }
             *  if (!otherTimeWindow.IsBusy(i) && i > firstBusy && firstBusy > 0 && nextAvailable == 0) {
             *      nextAvailable = i;
             *  }
             *  if (firstBusy > 0 && nextAvailable > firstBusy) {
             *      //thisTimeWindow.SetBusyMinutes (firstBusy, nextAvailable - 1);
             *      SetBusyMinutes(firstBusy, nextAvailable - 1);
             *      firstBusy = 0;
             *      nextAvailable = 0;
             *  }
             * }
             * if (firstBusy > 0) {
             *  SetBusyMinutes(firstBusy, Global.Settings.Times.MinutesInADay);
             */

            if (ValidTimeWindow() == false)
            {
                bool testBreak = true;
            }

            return(this);
        }
예제 #7
0
        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);
                }
            }
        }
예제 #8
0
        private void RunModel(ChoiceProbabilityCalculator choiceProbabilityCalculator, ITripWrapper trip, TripTime choice = null)
        {
            IPersonWrapper    person    = trip.Person;
            IPersonDayWrapper personDay = trip.PersonDay;
            ITourWrapper      tour      = trip.Tour;

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

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

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

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

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

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

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

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

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

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

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

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

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

                    available = available && departurePeriodFraction > 0;

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

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

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

                    if (!alternative.Available)
                    {
                        continue;
                    }

                    alternative.Choice = time;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                alternative.Choice = time;

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

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

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

                alternative.AddUtilityTerm(97, Math.Min(0.3, (homeBasedTours - simulatedHomeBasedTours) / (1.0 + arrivalImpedance.TotalMinutesBefore + departureImpedance.TotalMinutesAfter)));
                alternative.AddUtilityTerm(98, Math.Min(0.3, (homeBasedTours - simulatedHomeBasedTours) / (1.0 + Math.Max(arrivalImpedance.MaxMinutesBefore, departureImpedance.MaxMinutesAfter))));
            }
        }
예제 #10
0
        public static void SetImpedanceAndWindow(ITimeWindow timeWindow, ITourWrapper tour, HTourModeTime modeTimes, int constrainedHouseholdCars, double constrainedTransitDiscountFraction, IParcelWrapper alternativeDestination = null)
        {
            {
                var alternativeIndex  = modeTimes.Index;
                var arrivalPeriod     = modeTimes.ArrivalPeriod;
                var departurePeriod   = modeTimes.DeparturePeriod;
                var mode              = modeTimes.Mode;
                var destinationParcel = (alternativeDestination != null) ? alternativeDestination : tour.DestinationParcel;

                var arrivalPeriodAvailableMinutes   = timeWindow.TotalAvailableMinutes(arrivalPeriod.Start, arrivalPeriod.End);
                var departurePeriodAvailableMinutes = timeWindow.TotalAvailableMinutes(departurePeriod.Start, departurePeriod.End);
                var householdCars           = constrainedHouseholdCars >= 0 ? constrainedHouseholdCars : tour.Household.VehiclesAvailable;
                var transitDiscountFraction = constrainedTransitDiscountFraction >= 0 ? constrainedTransitDiscountFraction : tour.Person.GetTransitFareDiscountFraction();


                // set round trip mode LOS and mode availability
                if (arrivalPeriodAvailableMinutes <= 0 || departurePeriodAvailableMinutes <= 0 ||
                    (mode == Global.Settings.Modes.ParkAndRide && tour.DestinationPurpose != Global.Settings.Purposes.Work) ||
                    (mode == Global.Settings.Modes.SchoolBus && tour.DestinationPurpose != Global.Settings.Purposes.School) ||
                    (Global.Configuration.IsInEstimationMode && destinationParcel == null))
                {
                    modeTimes.ModeAvailableToDestination   = false;
                    modeTimes.ModeAvailableFromDestination = false;
                }
                //ACTUM must also use round trip path type to preserve the tour-based nonlinear gamma utility functions
                //else if (mode == Global.Settings.Modes.ParkAndRide) {
                else if (mode == Global.Settings.Modes.ParkAndRide || Global.Configuration.PathImpedance_UtilityForm_Auto == 1 ||
                         Global.Configuration.PathImpedance_UtilityForm_Transit == 1)
                {
                    // park and ride has to use round-trip path type, approximate each half
                    IEnumerable <dynamic> pathTypeModels =
                        PathTypeModelFactory.Model.Run(
                            tour.Household.RandomUtility,
                            tour.OriginParcel,
                            destinationParcel,
                            arrivalPeriod.Middle,
                            departurePeriod.Middle,
                            tour.DestinationPurpose,
                            tour.CostCoefficient,
                            tour.TimeCoefficient,
                            tour.Person.IsDrivingAge,
                            householdCars,
                            tour.Person.TransitPassOwnership,
                            tour.Household.OwnsAutomatedVehicles > 0,
                            transitDiscountFraction,
                            false,
                            mode);

                    var pathTypeModel = pathTypeModels.First(x => x.Mode == mode);

                    modeTimes.ModeAvailableToDestination   = pathTypeModel.Available;
                    modeTimes.ModeAvailableFromDestination = pathTypeModel.Available;

                    if (pathTypeModel.Available)
                    {
                        modeTimes.TravelTimeToDestination           = pathTypeModel.PathTime / 2.0;
                        modeTimes.GeneralizedTimeToDestination      = pathTypeModel.GeneralizedTimeLogsum / 2.0;
                        modeTimes.TravelTimeFromDestination         = pathTypeModel.PathTime / 2.0;
                        modeTimes.GeneralizedTimeFromDestination    = pathTypeModel.GeneralizedTimeLogsum / 2.0;
                        modeTimes.ParkAndRideOriginStopAreaKey      = pathTypeModel.PathOriginStopAreaKey;
                        modeTimes.ParkAndRideDestinationStopAreaKey = pathTypeModel.PathDestinationStopAreaKey;
                        modeTimes.TransitTime            = pathTypeModel.PathTransitTime;
                        modeTimes.TransitDistance        = pathTypeModel.PathTransitDistance;
                        modeTimes.TransitCost            = pathTypeModel.PathTransitCost;
                        modeTimes.TransitGeneralizedTime = pathTypeModel.PathTransitGeneralizedTime;
                        modeTimes.WalkTime                  = pathTypeModel.PathWalkTime;
                        modeTimes.WalkDistance              = pathTypeModel.PathWalkDistance;
                        modeTimes.BikeTime                  = pathTypeModel.PathBikeTime;
                        modeTimes.BikeDistance              = pathTypeModel.PathBikeDistance;
                        modeTimes.BikeCost                  = pathTypeModel.PathBikeCost;
                        modeTimes.OriginAccessMode          = pathTypeModel.PathOriginAccessMode;
                        modeTimes.OriginAccessTime          = pathTypeModel.PathOriginAccessTime;
                        modeTimes.OriginAccessDistance      = pathTypeModel.PathOriginAccessDistance;
                        modeTimes.OriginAccessCost          = pathTypeModel.PathOriginAccessCost;
                        modeTimes.DestinationAccessMode     = pathTypeModel.PathDestinationAccessMode;
                        modeTimes.DestinationAccessTime     = pathTypeModel.PathDestinationAccessTime;
                        modeTimes.DestinationAccessDistance = pathTypeModel.PathDestinationAccessDistance;
                        modeTimes.DestinationAccessCost     = pathTypeModel.PathDestinationAccessCost;
                        modeTimes.PathDistance              = pathTypeModel.PathDistance;
                        modeTimes.PathCost                  = pathTypeModel.PathCost;
                    }
                }
                else
                {
                    // get times for each half tour separately, using HOV3 for school bus
                    var pathMode = (mode == Global.Settings.Modes.SchoolBus) ? Global.Settings.Modes.Hov3 : mode;

                    //if (tour.Household.Id == 80205 && tour.PersonDay.HouseholdDay.AttemptedSimulations == 9 && (pathMode == 1 || pathMode == 5)) {
                    if (tour.Person.IsDrivingAge == true && tour.Household.VehiclesAvailable > 0 && pathMode == 3)
                    {
                        bool testbreak = true;
                    }
                    IEnumerable <dynamic> pathTypeModels =
                        PathTypeModelFactory.Model.Run(
                            tour.Household.RandomUtility,
                            tour.OriginParcel,
                            destinationParcel,
                            arrivalPeriod.Middle,
                            0,
                            tour.DestinationPurpose,
                            tour.CostCoefficient,
                            tour.TimeCoefficient,
                            tour.Person.IsDrivingAge,
                            householdCars,
                            tour.Person.TransitPassOwnership,
                            tour.Household.OwnsAutomatedVehicles > 0,
                            transitDiscountFraction,
                            false,
                            pathMode);

                    var pathTypeModel = pathTypeModels.First(x => x.Mode == pathMode);

                    modeTimes.ModeAvailableToDestination = pathTypeModel.Available;

                    if (pathTypeModel.Available)
                    {
                        modeTimes.TravelTimeToDestination      = pathTypeModel.PathTime;
                        modeTimes.GeneralizedTimeToDestination = pathTypeModel.GeneralizedTimeLogsum;
                    }

                    pathTypeModels =
                        PathTypeModelFactory.Model.Run(
                            tour.Household.RandomUtility,
                            destinationParcel,
                            tour.OriginParcel,
                            departurePeriod.Middle,
                            0,
                            tour.DestinationPurpose,
                            tour.CostCoefficient,
                            tour.TimeCoefficient,
                            tour.Person.IsDrivingAge,
                            householdCars,
                            tour.Person.TransitPassOwnership,
                            tour.Household.OwnsAutomatedVehicles > 0,
                            transitDiscountFraction,
                            false,
                            pathMode);

                    pathTypeModel = pathTypeModels.First(x => x.Mode == pathMode);

                    modeTimes.ModeAvailableFromDestination = pathTypeModel.Available;

                    if (pathTypeModel.Available)
                    {
                        modeTimes.TravelTimeFromDestination      = pathTypeModel.PathTime;
                        modeTimes.GeneralizedTimeFromDestination = pathTypeModel.GeneralizedTimeLogsum;
                    }
                }
                if (tour.Household.Id == 2138 && tour.Person.Sequence == 1 && tour.Sequence == 1)
                {
                    bool testbreak = true;
                }

                if (modeTimes.ModeAvailableToDestination == false)
                {
                }
                if (modeTimes.ModeAvailableFromDestination == false)
                {
                }


                if (modeTimes.ModeAvailableToDestination && modeTimes.ModeAvailableFromDestination)
                {
                    modeTimes.LongestFeasibleWindow = timeWindow.LongestAvailableFeasibleWindow(arrivalPeriod.End,
                                                                                                departurePeriod.Start,
                                                                                                modeTimes.TravelTimeToDestination,
                                                                                                modeTimes.TravelTimeFromDestination,
                                                                                                Global.Settings.Times.MinimumActivityDuration);
                }
            }
        }
예제 #11
0
        private void RunModel(ChoiceProbabilityCalculator choiceProbabilityCalculator, HouseholdDayWrapper householdDay, TourWrapper tour,
                              IParcelWrapper destinationParcel, int householdCars,
                              int constrainedMode, int constrainedArrivalTime, int constrainedDepartureTime, HTourModeTime choice = null)
        {
            //private void RunModel(ChoiceProbabilityCalculator choiceProbabilityCalculator, HouseholdDayWrapper householdDay, TourWrapper tour,
            //			int constrainedMode, int constrainedArrivalTime, int constrainedDepartureTime, HTourModeTime choice = null) {

            IHouseholdWrapper household       = tour.Household;
            IPersonWrapper    person          = tour.Person;
            IPersonDayWrapper personDay       = tour.PersonDay;
            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;
            int noCarsInHouseholdFlag   = household.GetFlagForNoCarsInHousehold(householdCars);
            int carsLessThanDriversFlag = household.GetFlagForCarsLessThanDrivers(householdCars);
            int carsLessThanWorkersFlag = household.GetFlagForCarsLessThanWorkers(householdCars);

            int HHwithChildrenFlag      = household.HasChildren.ToFlag();
            int HHwithSmallChildrenFlag = household.HasChildrenUnder5.ToFlag();
            int HHwithLowIncomeFlag     = (household.Income >= 300000 && household.Income < 600000).ToFlag();
            int HHwithMidleIncomeFlag   = (household.Income >= 600000 && household.Income < 900000).ToFlag();
            int HHwithHighIncomeFlag    = (household.Income >= 900000).ToFlag();

            int primaryFamilyTimeFlag = (householdDay == null) ? 0 : householdDay.PrimaryPriorityTimeFlag;

            // person inputs
            int partTimeWorkerFlag     = person.IsPartTimeWorker.ToFlag();
            int nonworkingAdultFlag    = person.IsNonworkingAdult.ToFlag();
            int universityStudentFlag  = person.IsUniversityStudent.ToFlag();
            int retiredAdultFlag       = person.IsRetiredAdult.ToFlag();
            int fullTimeWorkerFlag     = person.IsFulltimeWorker.ToFlag();
            int childAge5Through15Flag = person.IsChildAge5Through15.ToFlag();
            int childUnder5Flag        = person.IsChildUnder5.ToFlag();
            int adultFlag = person.IsAdult.ToFlag();

            int maleFlag   = person.IsMale.ToFlag();
            int femaleFlag = person.IsFemale.ToFlag();

            int PTpass = person.TransitPassOwnership;

            // person-day inputs
            int homeBasedToursOnlyFlag          = 1;
            int firstSimulatedHomeBasedTourFlag = 1;
            int laterSimulatedHomeBasedTourFlag = 0;
            int totalStops              = 0;
            int totalSimulatedStops     = 0;
            int escortStops             = 0;
            int homeBasedTours          = 1;
            int simulatedHomeBasedTours = 0;

            if (!(personDay == null))
            {
                homeBasedToursOnlyFlag          = personDay.OnlyHomeBasedToursExist().ToFlag();
                firstSimulatedHomeBasedTourFlag = personDay.IsFirstSimulatedHomeBasedTour().ToFlag();
                laterSimulatedHomeBasedTourFlag = personDay.IsLaterSimulatedHomeBasedTour().ToFlag();
                totalStops              = personDay.GetTotalStops();
                totalSimulatedStops     = personDay.GetTotalSimulatedStops();
                escortStops             = personDay.EscortStops;
                homeBasedTours          = personDay.HomeBasedTours;
                simulatedHomeBasedTours = personDay.SimulatedHomeBasedTours;
            }

            // tour inputs
            int escortTourFlag           = tour.IsEscortPurpose().ToFlag();
            int shoppingTourFlag         = tour.IsShoppingPurpose().ToFlag();
            int socialTourFlag           = tour.IsSocialPurpose().ToFlag();
            int personalBusinessTourFlag = tour.IsPersonalBusinessPurpose().ToFlag();
            int workTourFlag             = tour.IsWorkPurpose().ToFlag();
            int educationTourFlag        = tour.IsSchoolPurpose().ToFlag();
            int businessTourFlag         = tour.IsBusinessPurpose().ToFlag();

            IParcelWrapper originParcel = tour.OriginParcel;
            //var destinationParcel = tour.DestinationParcel;
            int  jointTourFlag        = (tour.JointTourSequence > 0) ? 1 : 0;
            int  partialHalfTour1Flag = (tour.PartialHalfTour1Sequence > 0) ? 1 : 0;
            int  partialHalfTour2Flag = (tour.PartialHalfTour2Sequence > 0) ? 1 : 0;
            bool partialHalfTour      = (tour.PartialHalfTour1Sequence > 0 || tour.PartialHalfTour2Sequence > 0);
            int  fullHalfTour1Flag    = (tour.FullHalfTour1Sequence > 0) ? 1 : 0;
            int  fullHalfTour2Flag    = (tour.FullHalfTour2Sequence > 0) ? 1 : 0;


            // remaining inputs

            //Initialize a few variables in case personDay is null
            // Higher priority tour of 2+ tours for the same purpose
            int highPrioritySameFlag = 0;
            // Lower priority tour(s) of 2+ tours for the same purpose
            int lowPrioritySameFlag = 0;
            // Higher priority tour of 2+ tours for different purposes
            int highPriorityDifferentFlag = 0;
            // Lower priority tour of 2+ tours for different purposes
            int lowPriorityDifferentFlag = 0;

            if (!(personDay == null))
            {
                // Higher priority tour of 2+ tours for the same purpose
                highPrioritySameFlag = (tour.GetTotalToursByPurpose() > tour.GetTotalSimulatedToursByPurpose() && tour.GetTotalSimulatedToursByPurpose() == 1).ToFlag();
                // Lower priority tour(s) of 2+ tours for the same purpose
                lowPrioritySameFlag = (tour.GetTotalSimulatedToursByPurpose() > 1).ToFlag();
                // Higher priority tour of 2+ tours for different purposes
                highPriorityDifferentFlag = (personDay.IsFirstSimulatedHomeBasedTour() && personDay.HomeBasedToursExist()).ToFlag() * (1 - highPrioritySameFlag);
                // Lower priority tour of 2+ tours for different purposes
                lowPriorityDifferentFlag = (personDay.IsLaterSimulatedHomeBasedTour() && personDay.HomeBasedToursExist()).ToFlag() * (1 - lowPrioritySameFlag);
            }

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

            if (totalMinutesAvailableInDay < 0)
            {
                if (!Global.Configuration.IsInEstimationMode)
                {
                    householdDay.IsValid = false;
                }
                totalMinutesAvailableInDay = 0;
            }

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

            bool useTimeComponents = Global.Configuration.IsInEstimationMode || constrainedArrivalTime == 0 || constrainedDepartureTime == 0;
            int  componentIndex    = 0;
            int  periodComb        = -1;

            //set components
            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, childAge5Through15Flag * hoursArrival);
                                arrivalComponent.AddUtilityTerm(firstCoef + 7, childUnder5Flag * hoursArrival);

                                arrivalComponent.AddUtilityTerm(firstCoef + 8, educationTourFlag * hoursArrival);
                                arrivalComponent.AddUtilityTerm(firstCoef + 9, escortTourFlag * hoursArrival);
                                arrivalComponent.AddUtilityTerm(firstCoef + 10, shoppingTourFlag * hoursArrival);
                                arrivalComponent.AddUtilityTerm(firstCoef + 11, businessTourFlag * hoursArrival);
                                arrivalComponent.AddUtilityTerm(firstCoef + 12, personalBusinessTourFlag * hoursArrival);
                                arrivalComponent.AddUtilityTerm(firstCoef + 13, socialTourFlag * hoursArrival);
                                arrivalComponent.AddUtilityTerm(firstCoef + 14, workTourFlag * hoursArrival);

                                arrivalComponent.AddUtilityTerm(firstCoef + 15, primaryFamilyTimeFlag * hoursArrival);

                                arrivalComponent.AddUtilityTerm(firstCoef + 16, HHwithLowIncomeFlag * hoursArrival);
                                arrivalComponent.AddUtilityTerm(firstCoef + 17, HHwithMidleIncomeFlag * hoursArrival);
                                arrivalComponent.AddUtilityTerm(firstCoef + 18, HHwithHighIncomeFlag * hoursArrival);

                                arrivalComponent.AddUtilityTerm(firstCoef + 19, highPrioritySameFlag * hoursArrival);
                                arrivalComponent.AddUtilityTerm(firstCoef + 20, lowPrioritySameFlag * hoursArrival);
                                arrivalComponent.AddUtilityTerm(firstCoef + 21, highPriorityDifferentFlag * hoursArrival);
                                arrivalComponent.AddUtilityTerm(firstCoef + 22, lowPriorityDifferentFlag * hoursArrival);
                                arrivalComponent.AddUtilityTerm(firstCoef + 23, jointTourFlag * hoursArrival);
                                arrivalComponent.AddUtilityTerm(firstCoef + 24, partialHalfTour1Flag * hoursArrival);
                                arrivalComponent.AddUtilityTerm(firstCoef + 25, fullHalfTour1Flag * hoursArrival);
                                arrivalComponent.AddUtilityTerm(firstCoef + 26, partialHalfTour2Flag * hoursArrival);
                                arrivalComponent.AddUtilityTerm(firstCoef + 27, 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 + 30, primaryFamilyTimeFlag * hoursDuration);

                            combinationComponent.AddUtilityTerm(firstCoef + 31, escortTourFlag * hoursDuration);
                            combinationComponent.AddUtilityTerm(firstCoef + 32, shoppingTourFlag * hoursDuration);
                            combinationComponent.AddUtilityTerm(firstCoef + 33, educationTourFlag * hoursDuration);
                            combinationComponent.AddUtilityTerm(firstCoef + 34, socialTourFlag * hoursDuration);
                            combinationComponent.AddUtilityTerm(firstCoef + 35, personalBusinessTourFlag * hoursDuration);
                            combinationComponent.AddUtilityTerm(firstCoef + 36, businessTourFlag * hoursDuration);
                            combinationComponent.AddUtilityTerm(firstCoef + 37, workTourFlag * 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, partTimeWorkerFlag);
                                combinationComponent.AddUtilityTerm(firstCoef + 50, maleFlag);
                            }
                        }
                    }
                }
            }
            //for (var mode = Global.Settings.Modes.Walk; mode <= Global.Settings.Modes.WalkRideBike; mode++) {  replaced 20171120 JLB
            for (int mode = Global.Settings.Modes.Walk; mode <= Global.Settings.Modes.PaidRideShare; 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);
                //}
                if (mode == Global.Settings.Modes.Transit)
                {
                    modeComponent.AddUtilityTerm(20, 1);
                    modeComponent.AddUtilityTerm(21, femaleFlag);
                    //modeComponent.AddUtilityTerm(22, retiredAdultFlag);

                    modeComponent.AddUtilityTerm(22, PTpass);

                    //GV: one person HH; 8. juni 2016
                    //modeComponent.AddUtilityTerm(23, onePersonHouseholdFlag);

                    //GV: income effect is not with a correct sign
                    //modeComponent.AddUtilityTerm(23, HHwithLowIncomeFlag);
                    //modeComponent.AddUtilityTerm(24, HHwithMidleIncomeFlag);
                    //modeComponent.AddUtilityTerm(25, HHwithHighIncomeFlag);

                    //GV: not significant
                    //modeComponent.AddUtilityTerm(26, childrenUnder5);
                    //modeComponent.AddUtilityTerm(27, childrenAge5Through15);

                    modeComponent.AddUtilityTerm(28, nonworkingAdults + retiredAdults);

                    //modeComponent.AddUtilityTerm(26, noCarsInHouseholdFlag);
                    modeComponent.AddUtilityTerm(29, carsLessThanDriversFlag);
                }
                else if (mode == Global.Settings.Modes.Hov3)
                {
                    modeComponent.AddUtilityTerm(30, 1);
                    modeComponent.AddUtilityTerm(31, childrenUnder5);
                    modeComponent.AddUtilityTerm(32, childrenAge5Through15);
                    modeComponent.AddUtilityTerm(33, nonworkingAdults + retiredAdults);
                    modeComponent.AddUtilityTerm(34, femaleFlag);

                    //modeComponent.AddUtilityTerm(38, onePersonHouseholdFlag);
                    modeComponent.AddUtilityTerm(36, twoPersonHouseholdFlag);

                    //GV: commented out 7. june 2016
                    //modeComponent.AddUtilityTerm(37, noCarsInHouseholdFlag);
                    modeComponent.AddUtilityTerm(38, carsLessThanDriversFlag);
                }
                else if (mode == Global.Settings.Modes.Hov2)
                {
                    modeComponent.AddUtilityTerm(40, 1);
                    modeComponent.AddUtilityTerm(41, maleFlag);
                    //modeComponent.AddUtilityTerm(41, onePersonHouseholdFlag);

                    //GV: Testing coeff. 42-44 again, 26. may 2016, coeff. numbering changed
                    modeComponent.AddUtilityTerm(42, childrenUnder5);
                    modeComponent.AddUtilityTerm(43, childrenAge5Through15);
                    modeComponent.AddUtilityTerm(44, nonworkingAdults + retiredAdults);

                    //GV: these are significant and plus; 8. juni 2016
                    //modeComponent.AddUtilityTerm(45, HHwithLowIncomeFlag);
                    //modeComponent.AddUtilityTerm(46, HHwithMidleIncomeFlag);
                    //modeComponent.AddUtilityTerm(47, HHwithHighIncomeFlag);

                    //GV coeff. numbering changed; 8. june 2016 - not significant
                    //modeComponent.AddUtilityTerm(48, noCarsInHouseholdFlag);
                    //modeComponent.AddUtilityTerm(49, carsLessThanDriversFlag);
                }
                else if (mode == Global.Settings.Modes.Sov)
                {
                    modeComponent.AddUtilityTerm(50, 1);
                    //not significant: modeComponent.AddUtilityTerm(51, maleFlag);
                    modeComponent.AddUtilityTerm(52, fullTimeWorkerFlag);
                    modeComponent.AddUtilityTerm(53, partTimeWorkerFlag);
                    modeComponent.AddUtilityTerm(54, onePersonHouseholdFlag);

                    //GV: these are NOT significant
                    //modeComponent.AddUtilityTerm(55, HHwithLowIncomeFlag);
                    //modeComponent.AddUtilityTerm(56, HHwithMidleIncomeFlag);
                    //modeComponent.AddUtilityTerm(57, HHwithHighIncomeFlag);

                    //GV: coeff. numbering changed, 26. may 2016
                    modeComponent.AddUtilityTerm(58, carsLessThanWorkersFlag);
                }
                else if (mode == Global.Settings.Modes.Bike)
                {
                    modeComponent.AddUtilityTerm(60, 1);
                    modeComponent.AddUtilityTerm(61, femaleFlag);
                    //modeComponent.AddUtilityTerm(62, childrenUnder5);
                    //GV: changed small kids to retired; 3. june 2016
                    modeComponent.AddUtilityTerm(62, retiredAdults);
                    modeComponent.AddUtilityTerm(63, childAge5Through15Flag);

                    //GV: 3. june 2016 - added "no cars in HH" for full/part_time workers
                    modeComponent.AddUtilityTerm(64, fullTimeWorkerFlag + noCarsInHouseholdFlag);
                    modeComponent.AddUtilityTerm(65, partTimeWorkerFlag + noCarsInHouseholdFlag);

                    //modeComponent.AddUtilityTerm(66, noCarsInHouseholdFlag);
                    modeComponent.AddUtilityTerm(67, carsLessThanDriversFlag);

                    //GV: university students; 3. june 2016 - not significant
                    //modeComponent.AddUtilityTerm(68, universityStudentFlag);

                    //GV: one person HH; 8. juni 2016
                    modeComponent.AddUtilityTerm(69, onePersonHouseholdFlag);
                }
                else if (mode == Global.Settings.Modes.Walk)
                {
                    modeComponent.AddUtilityTerm(70, 1.0);
                    //GV: Testing female variable again; 26. may 2016 - not sign.
                    //modeComponent.AddUtilityTerm(71, femaleFlag);
                    modeComponent.AddUtilityTerm(72, nonworkingAdults);
                    //not sign.: modeComponent.AddUtilityTerm(73, retiredAdults);

                    //GV: one person HH
                    modeComponent.AddUtilityTerm(74, onePersonHouseholdFlag);

                    //GV: not significant
                    //modeComponent.AddUtilityTerm(76, noCarsInHouseholdFlag);
                    //modeComponent.AddUtilityTerm(77, carsLessThanDriversFlag);
                }
                else if (mode == Global.Settings.Modes.ParkAndRide)
                {
                    modeComponent.AddUtilityTerm(80, 1.0);
                }
                else if (mode == Global.Settings.Modes.CarKissRideWalk)
                {
                    modeComponent.AddUtilityTerm(90, 1.0);
                }
                else if (mode == Global.Settings.Modes.BikeParkRideWalk)
                {
                    modeComponent.AddUtilityTerm(100, 1.0);
                }
                else if (mode == Global.Settings.Modes.BikeParkRideBike)
                {
                    modeComponent.AddUtilityTerm(110, 1.0);
                }
                else if (mode == Global.Settings.Modes.BikeOnTransit)
                {
                    modeComponent.AddUtilityTerm(120, 1.0);
                }
                else if (mode == Global.Settings.Modes.CarParkRideBike)
                {
                    modeComponent.AddUtilityTerm(130, 1.0);
                }
                else if (mode == Global.Settings.Modes.WalkRideBike)
                {
                    modeComponent.AddUtilityTerm(140, 1.0);
                }
                else if (mode == Global.Settings.Modes.PaidRideShare)
                {
                    //modeComponent.AddUtilityTerm(150, 1.0);

                    double modeConstant = Global.Configuration.AV_PaidRideShareModeUsesAVs
                     ? Global.Configuration.AV_PaidRideShare_ModeConstant
                                          + Global.Configuration.AV_PaidRideShare_DensityCoefficient * Math.Min(originParcel.HouseholdsBuffer2 + originParcel.StudentsUniversityBuffer2 + originParcel.EmploymentTotalBuffer2, 6000)
                                          + Global.Configuration.AV_PaidRideShare_AVOwnerCoefficient * (household.OwnsAutomatedVehicles > 0).ToFlag()
                     : Global.Configuration.PaidRideShare_ModeConstant
                                          + Global.Configuration.PaidRideShare_DensityCoefficient * Math.Min(originParcel.HouseholdsBuffer2 + originParcel.StudentsUniversityBuffer2 + originParcel.EmploymentTotalBuffer2, 6000);

                    modeComponent.AddUtilityTerm(150, modeConstant);
                    modeComponent.AddUtilityTerm(150, Global.Configuration.PaidRideShare_Age26to35Coefficient * tour.Person.AgeIsBetween26And35.ToFlag());
                    modeComponent.AddUtilityTerm(150, Global.Configuration.PaidRideShare_Age18to25Coefficient * tour.Person.AgeIsBetween18And25.ToFlag());
                    modeComponent.AddUtilityTerm(150, Global.Configuration.PaidRideShare_AgeOver65Coefficient * (tour.Person.Age >= 65).ToFlag());
                }


                //GV: Estimation of importance of "purpose" per mode - SOV is zero-alt and Work is zero-alt
                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, educationTourFlag);
                    modeComponent.AddUtilityTerm(firstCoef + 3, socialTourFlag);
                    modeComponent.AddUtilityTerm(firstCoef + 4, personalBusinessTourFlag);
                    modeComponent.AddUtilityTerm(firstCoef + 5, businessTourFlag);
                    //modeComponent.AddUtilityTerm(firstCoef + 6, workTourFlag); //GV: "work" is zero alternative

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



            //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;



                    //limit availability based on mode and tour purpose
                    bool available = (mode == Global.Settings.Modes.BikeParkRideBike || mode == Global.Settings.Modes.CarParkRideBike || mode == Global.Settings.Modes.WalkRideBike) &&
                                     (!(tour.IsWorkPurpose() || tour.IsSchoolPurpose())) ? false : true;

                    //further limit availability on mode
                    if (mode == Global.Settings.Modes.PaidRideShare && !Global.Configuration.PaidRideShareModeIsAvailable)
                    {
                        available = false;
                    }

                    //further limit availability if tour includes joint travel
                    if ((tour.JointTourSequence > 0 ||
                         tour.FullHalfTour1Sequence > 0 || tour.FullHalfTour2Sequence > 0 ||
                         tour.PartialHalfTour1Sequence > 0 || tour.PartialHalfTour2Sequence > 0) &&
                        (mode > Global.Settings.Modes.Transit))
                    {
                        available = false;
                    }

                    //further limit availability:  kissAndRide and carParkRideBike are not supported
                    available = (available == true) && (mode != Global.Settings.Modes.CarKissRideWalk) && (mode != Global.Settings.Modes.CarParkRideBike);

                    //further limit availabillity based on time window variables and any constrained choices
                    available = (available == true) &&
                                (modeTimes.LongestFeasibleWindow != null) && (mode > 0)
                                //&& (mode <= Global.Settings.Modes.Transit)
                                && (person.Age >= 18 || (modeTimes.Mode != Global.Settings.Modes.Sov && modeTimes.Mode != Global.Settings.Modes.HovDriver)) &&
                                (constrainedMode > 0 || mode == Global.Settings.Modes.Walk || mode == Global.Settings.Modes.Bike || mode == Global.Settings.Modes.HovDriver || mode == Global.Settings.Modes.Transit || !partialHalfTour) &&
                                (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);
                    alternative.AddNestedAlternative(HTourModeTime.TotalTourModeTimes + mode, mode - 1, THETA_PARAMETER);

                    //if (Global.Configuration.IsInEstimationMode && 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);

                    //}
                    //Following code was used to test handling of partially joint half tours (JLB 20140603)
                    //if (partialHalfTour) {
                    //	Global.PrintFile.WriteLine("HH pers {0} {1} avail {2} Aper Dper Mode {3} {4} {5} Travel Times {6} {7} Window {8} {9}",
                    //	   household.Id, person.Sequence,
                    //    available,
                    //		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 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;
                    }

                    //GV and JB: the parking cost are handled as part of genaralised time

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

                    alternative.AddUtilityTerm(1, modeTimes.GeneralizedTimeToDestination + modeTimes.GeneralizedTimeFromDestination);

                    //alternative.AddUtilityTerm(3,
                    //                           Math.Log(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(840, modeTimes.LongestFeasibleWindow.End - modeTimes.LongestFeasibleWindow.Start)), 0.8)
                                                                 )));



                    alternative.AddUtilityTerm(4, Math.Log((totalMinutesAvailableInDay + 1.0) / (minimumTimeNeeded + 1.0)));

                    alternative.AddUtilityTerm(5,
                                               (maleFlag == 0 && mode == Global.Settings.Modes.Walk &&
                                                arrivalPeriod.Index >= DayPeriod.EVENING)
                                                  ? 1
                                                  : 0);

                    if (altIndex == 0)
                    {
                        alternative.AddUtilityTerm(998, tour.DestinationPurpose);
                        alternative.AddUtilityTerm(999, (tour.ParentTour == null) ? 0 : 1);
                    }
                }
            }
        }
예제 #12
0
 public void GoYear()
 {
     _timeWindow = _timeWindow.ToYearWindow();
 }
예제 #13
0
 public void GoMonth()
 {
     _timeWindow = _timeWindow.ToMonthWindow();
 }
예제 #14
0
 public void GoWeek()
 {
     _timeWindow = _timeWindow.ToWeekWindow();
 }
예제 #15
0
 public void GoDay()
 {
     _timeWindow = _timeWindow.ToDayWindow();
 }
예제 #16
0
 public TimeWindowCore(DateTime start)
 {
     _timeWindow = new DayTimeWindow(start);
 }