Esempio n. 1
0
        public void Run(IHouseholdWrapper household)
        {
            if (household == null)
            {
                throw new ArgumentNullException("household");
            }

            household.ResetRandom(4);

            if (Global.Configuration.IsInEstimationMode)
            {
                if (Global.Configuration.EstimationModel != CHOICE_MODEL_NAME)
                {
                    return;
                }
            }
            else if (Global.Configuration.AV_IncludeAutoTypeChoice)
            {
                ChoiceProbabilityCalculator AVchoiceProbabilityCalculator = _helpers[ParallelUtility.threadLocalAssignedIndex.Value].GetChoiceProbabilityCalculator(household.Id);
                RunAVModel(AVchoiceProbabilityCalculator, household);
                ChoiceProbabilityCalculator.Alternative chosenAlternative = AVchoiceProbabilityCalculator.SimulateChoice(household.RandomUtility);
                int choice = (int)chosenAlternative.Choice;

                household.OwnsAutomatedVehicles = choice;
            }


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

            if (household.VehiclesAvailable > 4)
            {
                household.VehiclesAvailable = 4;
            }

            if (_helpers[ParallelUtility.threadLocalAssignedIndex.Value].ModelIsInEstimationMode)
            {
                RunModel(choiceProbabilityCalculator, household, household.VehiclesAvailable);

                choiceProbabilityCalculator.WriteObservation();
            }
            else
            {
                RunModel(choiceProbabilityCalculator, household);

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

                household.VehiclesAvailable = choice;
            }
        }
Esempio n. 2
0
        private void RunModel(ChoiceProbabilityCalculator choiceProbabilityCalculator, IPersonWrapper person, int sampleSize, IParcelWrapper choice = null, bool choseHome = false)
        {
            int segment = Global.ContainerDaySim.GetInstance <SamplingWeightsSettingsFactory>().SamplingWeightsSettings.GetTourDestinationSegment(Global.Settings.Purposes.Work, Global.Settings.TourPriorities.HomeBasedTour, Global.Settings.Modes.Sov, person.PersonType);
            DestinationSampler destinationSampler      = new DestinationSampler(choiceProbabilityCalculator, segment, sampleSize, choice, person.Household.ResidenceParcel);
            int destinationArrivalTime                 = ChoiceModelUtility.GetDestinationArrivalTime(Global.Settings.Models.WorkTourModeModel);
            int destinationDepartureTime               = ChoiceModelUtility.GetDestinationDepartureTime(Global.Settings.Models.WorkTourModeModel);
            WorkLocationUtilities workLocationUtilites = new WorkLocationUtilities(this, person, sampleSize, destinationArrivalTime, destinationDepartureTime);

            destinationSampler.SampleTourDestinations(workLocationUtilites);

            //var alternative = choiceProbabilityCalculator.GetAlternative(countSampled, true);

            // JLB 20120329 added third call parameter to idenitfy whether this alt is chosen or not
            if (Global.Configuration.IsInEstimationMode && !ESTIMATE_NESTED_MODEL)
            {
                return;
            }
            ChoiceProbabilityCalculator.Alternative alternative = choiceProbabilityCalculator.GetAlternative(sampleSize, true, choseHome);

            alternative.Choice = person.Household.ResidenceParcel;

            alternative.AddUtilityTerm(41, 1);
            alternative.AddUtilityTerm(42, person.IsPartTimeWorker.ToFlag());
            alternative.AddUtilityTerm(43, person.IsStudentAge.ToFlag());
            alternative.AddUtilityTerm(44, person.IsFemale.ToFlag());
            alternative.AddUtilityTerm(89, 1);   //new dummy size variable for oddball alt
            alternative.AddUtilityTerm(90, 100); //old dummy size variable for oddball alt

            // OD shadow pricing - add for work at home
            if (Global.Configuration.ShouldUseODShadowPricing && Global.Configuration.UseODShadowPricingForWorkAtHomeAlternative)
            {
                int res = person.Household.ResidenceParcel.District;
                int des = person.Household.ResidenceParcel.District;
                //var first = res <= des? res : des;
                //var second = res <= des? des : res;
                double shadowPriceConfigurationParameter = res == des ? Global.Configuration.WorkLocationOOShadowPriceCoefficient : Global.Configuration.WorkLocationODShadowPriceCoefficient;
                int    odShadowPriceF12Value             = MAX_REGULAR_PARAMETER + Global.Configuration.NumberOfODShadowPricingDistricts * (res - 1) + des;
                alternative.AddUtilityTerm(odShadowPriceF12Value, shadowPriceConfigurationParameter);
            }

            // set shadow price depending on persontype and add it to utility
            // we are using the sampling adjustment factor assuming that it is 1
            if (Global.Configuration.ShouldUseShadowPricing && Global.Configuration.UseWorkShadowPricingForWorkAtHomeAlternative)
            {
                alternative.AddUtilityTerm(1, person.Household.ResidenceParcel.ShadowPriceForEmployment);
            }

            //make oddball alt unavailable and remove nesting for estimation of conditional MNL
            alternative.AddNestedAlternative(sampleSize + 3, 1, THETA_PARAMETER);
        }
Esempio n. 3
0
        public int Run(TourWrapper tour, HouseholdDayWrapper householdDay, int nCallsForTour, int choice)
        {
            if (tour == null)
            {
                throw new ArgumentNullException("tour");
            }

            tour.PersonDay.Person.ResetRandom(908 + (tour.Sequence - 1) * 3 + nCallsForTour);

            if (Global.Configuration.IsInEstimationMode)
            {
                if (!(choice == Global.Settings.Purposes.NoneOrHome)) // simplifying choice.  TODO:  will need to deal with personal business subtours distinctly from home based in tour models
                {
                    choice = Global.Settings.Purposes.PersonalBusiness;
                }
                if (Global.Configuration.EstimationModel != CHOICE_MODEL_NAME)
                {
                    return(choice);
                }
            }

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

            if (_helpers[ParallelUtility.threadLocalAssignedIndex.Value].ModelIsInEstimationMode)
            {
                if (tour.PersonDay.GetTotalStops() > 0)
                {
                    RunModel(choiceProbabilityCalculator, tour, householdDay, nCallsForTour, choice);

                    choiceProbabilityCalculator.WriteObservation();
                }
            }
            else
            {
                if (tour.PersonDay.GetTotalStops() > 0)
                {
                    RunModel(choiceProbabilityCalculator, tour, householdDay, nCallsForTour);

                    ChoiceProbabilityCalculator.Alternative chosenAlternative = choiceProbabilityCalculator.SimulateChoice(tour.Household.RandomUtility);
                    choice = (int)chosenAlternative.Choice;
                }
                else
                {
                    choice = Global.Settings.Purposes.NoneOrHome;
                }
            }

            return(choice);
        }
Esempio n. 4
0
        private void RunAVModel(ChoiceProbabilityCalculator choiceProbabilityCalculator, IHouseholdWrapper household, int choice = Constants.DEFAULT_VALUE)
        {
            int    ageOfHouseholdHead = 0;
            double totalCommuteTime   = 0;

            foreach (IPersonWrapper person in household.Persons)
            {
                if (person.Sequence == 1)
                {
                    ageOfHouseholdHead = person.Age;
                }
                if (person.IsWorker && person.UsualWorkParcel != null && person.UsualWorkParcelId != household.ResidenceParcelId)
                {
                    int destinationArrivalTime   = ChoiceModelUtility.GetDestinationArrivalTime(Global.Settings.Models.WorkTourModeModel);
                    int destinationDepartureTime = ChoiceModelUtility.GetDestinationDepartureTime(Global.Settings.Models.WorkTourModeModel);

                    totalCommuteTime += ImpedanceRoster.GetValue("ivtime", Global.Settings.Modes.Sov, Global.Settings.PathTypes.FullNetwork, Global.Configuration.VotHighVeryHigh - 0.5,
                                                                 destinationArrivalTime, household.ResidenceParcel, person.UsualWorkParcel).Variable;
                    totalCommuteTime += ImpedanceRoster.GetValue("ivtime", Global.Settings.Modes.Sov, Global.Settings.PathTypes.FullNetwork, Global.Configuration.VotHighVeryHigh - 0.5,
                                                                 destinationDepartureTime, person.UsualWorkParcel, household.ResidenceParcel).Variable;
                }
            }

            // 0 Conventional auotos

            ChoiceProbabilityCalculator.Alternative alternative = choiceProbabilityCalculator.GetAlternative(0, true, choice == 0);
            alternative.Choice = 0;
            //utility is 0

            // 1 AVs

            int lowIncome  = household.Income < 300000 ? 1 : 0;
            int highIncome = household.Income > 900000 ? 1 : 0;

            alternative        = choiceProbabilityCalculator.GetAlternative(1, true, choice == 1);
            alternative.Choice = 1;

            alternative.AddUtilityTerm(100, Global.Configuration.AV_AutoTypeConstant);
            alternative.AddUtilityTerm(100, Global.Configuration.AV_HHIncomeUnder50KCoefficient * lowIncome);
            alternative.AddUtilityTerm(100, Global.Configuration.AV_HHIncomeOver100KCoefficient * highIncome);
            alternative.AddUtilityTerm(100, Global.Configuration.AV_HHHeadUnder35Coefficient * (ageOfHouseholdHead < 35).ToFlag());
            alternative.AddUtilityTerm(100, Global.Configuration.AV_HHHeadOver65Coefficient * (ageOfHouseholdHead >= 65).ToFlag());
            alternative.AddUtilityTerm(100, Global.Configuration.AV_CoefficientPerHourCommuteTime * (totalCommuteTime / 60.0));

            // 2+ not available

            alternative        = choiceProbabilityCalculator.GetAlternative(2, false, choice == 2);
            alternative.Choice = 2;
        }
Esempio n. 5
0
        public DestinationSampler(ChoiceProbabilityCalculator choiceProbabilityCalculator, int segmentZonesIndex, int sampleSize, IParcel chosenParcel, IParcel originParcel, IParcel excludedParcel, IParcel usualParcel) : this(choiceProbabilityCalculator, segmentZonesIndex, sampleSize, chosenParcel, originParcel) {

            if (excludedParcel != null) {
                _excludedParcel = excludedParcel;
                _excludedSegmentZone = _segmentZones[excludedParcel.ZoneId];
            }

            if (usualParcel != null) {
                _usualParcel = usualParcel;
                _usualSegmentZone = _segmentZones[usualParcel.ZoneId];
            }
            if (_choiceProbabilityCalculator.ModelIsInEstimationMode && chosenParcel == null) {
                throw new ChosenParcelNotSetInEstimationModeException();
            }
        }
Esempio n. 6
0
        public DestinationSampler(ChoiceProbabilityCalculator choiceProbabilityCalculator, int segmentZonesIndex, int sampleSize, IParcel chosenParcel, IParcel originParcel) : this(choiceProbabilityCalculator, segmentZonesIndex, sampleSize, chosenParcel)
        {
            _originParcel      = originParcel;
            _originSegmentZone = _segmentZones[originParcel.ZoneId];

            if (chosenParcel != null)
            {
                _chosenParcel      = chosenParcel;
                _chosenSegmentZone = _segmentZones[chosenParcel.ZoneId];
            }
            //JLB 20120329 removed these lines because usual work location model doesn't set a sampled dest to chosen when it is the residence location
            //            if (_choiceProbabilityCalculator.ModelIsInEstimationMode && chosenParcel == null) {
            //                throw new ChosenParcelNotSetInEstimationModeException();
            //            }
        }
Esempio n. 7
0
        public DestinationSampler(ChoiceProbabilityCalculator choiceProbabilityCalculator, int segmentZonesIndex, int sampleSize, IParcel chosenParcel, ITourWrapper tour, ITripWrapper trip) : this(choiceProbabilityCalculator, segmentZonesIndex, sampleSize, chosenParcel) {
            _tourOriginParcel = tour.OriginParcel;
            _tourOriginSegmentZone = _segmentZones[_tourOriginParcel.ZoneId];

            _tripOriginParcel = trip.OriginParcel;
            _tripOriginSegmentZone = _segmentZones[_tripOriginParcel.ZoneId];

            if (_tourOriginParcel == null || _tripOriginSegmentZone == null) {

            }

            if (_choiceProbabilityCalculator.ModelIsInEstimationMode && chosenParcel == null) {
                throw new ChosenParcelNotSetInEstimationModeException();
            }
        }
Esempio n. 8
0
        public int Run(HouseholdDayWrapper householdDay, int nCallsForTour, int choice)
        {
            if (householdDay == null)
            {
                throw new ArgumentNullException("householdDay");
            }

            householdDay.ResetRandom(935 + nCallsForTour); // TODO:  fix the ResetRandom call parameter

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

            ChoiceProbabilityCalculator choiceProbabilityCalculator =
                _helpers[ParallelUtility.threadLocalAssignedIndex.Value].GetChoiceProbabilityCalculator(((householdDay.Household.Id * 10 + householdDay.Day) * 397) ^ nCallsForTour);

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

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

                //choice = Math.Min(personDay.BusinessStops, 1) + 2 * Math.Min(personDay.SchoolStops, 1);

                RunModel(choiceProbabilityCalculator, householdDay, nCallsForTour);

                ChoiceProbabilityCalculator.Alternative chosenAlternative = choiceProbabilityCalculator.SimulateChoice(householdDay.Household.RandomUtility, householdDay.Household.Id, choice);

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

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

            return(choice);
        }
Esempio n. 9
0
        public int Run(ITourWrapper tour, int nCallsForTour, int choice)
        {
            if (tour == null)
            {
                throw new ArgumentNullException("tour");
            }

            tour.PersonDay.ResetRandom(30 + tour.Sequence + nCallsForTour - 1);

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

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

            if (_helpers[ParallelUtility.threadLocalAssignedIndex.Value].ModelIsInEstimationMode)
            {
                if (tour.PersonDay.GetTotalStops() > 0)
                {
                    RunModel(choiceProbabilityCalculator, tour, nCallsForTour, choice);

                    choiceProbabilityCalculator.WriteObservation();
                }
            }
            else
            {
                if (tour.PersonDay.GetTotalStops() > 0)
                {
                    RunModel(choiceProbabilityCalculator, tour, nCallsForTour);

                    ChoiceProbabilityCalculator.Alternative chosenAlternative = choiceProbabilityCalculator.SimulateChoice(tour.Household.RandomUtility);
                    choice = (int)chosenAlternative.Choice;
                }
                else
                {
                    choice = Global.Settings.Purposes.NoneOrHome;
                }
            }

            return(choice);
        }
Esempio n. 10
0
        public int Run(PersonDayWrapper personDay, HouseholdDayWrapper householdDay, int maxPurpose, int choice)
        {
            if (householdDay == null)
            {
                throw new ArgumentNullException("householdDay");
            }

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

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

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

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

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

                RunModel(choiceProbabilityCalculator, personDay, householdDay, maxPurpose);

                ChoiceProbabilityCalculator.Alternative chosenAlternative = choiceProbabilityCalculator.SimulateChoice(householdDay.Household.RandomUtility, personDay.Id, choice);

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

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

            return(choice);
        }
Esempio n. 11
0
        public void Run(IPersonWrapper person)
        {
            if (person == null)
            {
                throw new ArgumentNullException("person");
            }

            person.ResetRandom(3);

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

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

            if (_helpers[ParallelUtility.threadLocalAssignedIndex.Value].ModelIsInEstimationMode)
            {
                if (person.TransitPassOwnership > 1)
                {
                    person.TransitPassOwnership = 1;
                }                                                                  //recoding to allow for multiple types of transit passes for codes >0
                if (person.TransitPassOwnership < 0 || person.TransitPassOwnership > 1)
                {
                    return;
                }

                RunModel(choiceProbabilityCalculator, person, person.TransitPassOwnership);

                choiceProbabilityCalculator.WriteObservation();
            }
            else
            {
                RunModel(choiceProbabilityCalculator, person);

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

                person.TransitPassOwnership = choice;
            }
        }
        public void Run(HouseholdDayWrapper householdDay)
        {
            if (householdDay == null)
            {
                throw new ArgumentNullException("householdDay");
            }

            householdDay.ResetRandom(962);

            if (Global.Configuration.IsInEstimationMode)
            {
                return;
            }

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



            //if (_helpers[ParallelUtility.threadLocalAssignedIndex.Value].ModelIsInEstimationMode) {

            //				// set choice variable here  (derive from available household properties)
            //				if (householdDay.SharedActivityHomeStays >= 1
            //					//&& householdDay.DurationMinutesSharedHomeStay >=60
            //					&& householdDay.AdultsInSharedHomeStay >= 1
            //					&& householdDay.NumberInLargestSharedHomeStay >= (householdDay.Household.Size)
            //                   )
            //				{
            //					householdDay.PrimaryPriorityTimeFlag = 1;
            //				}
            //				else    householdDay.PrimaryPriorityTimeFlag = 0;

            //RunModel(choiceProbabilityCalculator, householdDay, householdDay.PrimaryPriorityTimeFlag);

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

            ChoiceProbabilityCalculator.Alternative chosenAlternative = choiceProbabilityCalculator.SimulateChoice(householdDay.Household.RandomUtility);
            int[] choice = (int[])chosenAlternative.Choice;
            householdDay.StartingMinuteSharedHomeStay  = choice[1];
            householdDay.DurationMinutesSharedHomeStay = choice[2];
            //}
        }
Esempio n. 13
0
        public ChoiceProbabilityCalculator.Alternative RunNested(ITourWrapper tour, IParcelWrapper destinationParcel, int householdCars, double transitDiscountFraction)
        {
            if (Global.Configuration.AvoidDisaggregateModeChoiceLogsums)
            {
                return(null);
            }
            ChoiceProbabilityCalculator choiceProbabilityCalculator = _helpers[ParallelUtility.threadLocalAssignedIndex.Value].GetNestedChoiceProbabilityCalculator();

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

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

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

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

            return(choiceProbabilityCalculator.SimulateChoice(tour.Household.RandomUtility));
        }
Esempio n. 14
0
        public void Run(IPersonWrapper person)
        {
            if (person == null)
            {
                throw new ArgumentNullException("person");
            }

            person.ResetRandom(2);

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

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

            if (_helpers[ParallelUtility.threadLocalAssignedIndex.Value].ModelIsInEstimationMode)
            {
                if (person.PaidParkingAtWorkplace < 0 || person.PaidParkingAtWorkplace > 1)
                {
                    return;
                }

                RunModel(choiceProbabilityCalculator, person, person.PaidParkingAtWorkplace);

                choiceProbabilityCalculator.WriteObservation();
            }
            else
            {
                RunModel(choiceProbabilityCalculator, person);

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

                person.PaidParkingAtWorkplace = choice;
            }
        }
Esempio n. 15
0
        public int Run(HouseholdDayWrapper householdDay, int nCallsForTour, bool[] available, int type, int subType)
        {
            if (householdDay == null)
            {
                throw new ArgumentNullException("householdDay");
            }

            householdDay.ResetRandom(920 + nCallsForTour);

            int choice = 0;

            if (Global.Configuration.IsInEstimationMode)
            {
                choice = type == 0 ? 0 : (type - 1) * 3 + subType + 1;

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

            ChoiceProbabilityCalculator choiceProbabilityCalculator = _helpers[ParallelUtility.threadLocalAssignedIndex.Value].GetChoiceProbabilityCalculator(((householdDay.Household.Id * 10 + householdDay.Day) * 397) ^ nCallsForTour);

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

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

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

            return(choice);
        }
Esempio n. 16
0
        private void RunModel(ChoiceProbabilityCalculator choiceProbabilityCalculator, ITourWrapper tour, int sampleSize, IParcelWrapper choice = null)
        {
            var household = tour.Household;
            var person    = tour.Person;
            var personDay = tour.PersonDay;

//			var totalAvailableMinutes =
//				tour.ParentTour == null
//					? personDay.TimeWindow.TotalAvailableMinutes(1, Global.Settings.Times.MinutesInADay)
//					: tour.ParentTour.TimeWindow.TotalAvailableMinutes(1, Global.Settings.Times.MinutesInADay);

            var maxAvailableMinutes =
                tour.ParentTour == null
                                        ? personDay.TimeWindow.MaxAvailableMinutesAfter(121)
                                        : tour.ParentTour.DestinationDepartureTime - tour.ParentTour.DestinationArrivalTime;

//			var hoursAvailableInverse =
//				tour.IsHomeBasedTour
//					? (personDay.HomeBasedTours - personDay.SimulatedHomeBasedTours + 1) / (Math.Max(totalAvailableMinutes - 360, 30) / 60D)
//					: 1 / (Math.Max(totalAvailableMinutes, 1) / 60D);

            var fastestAvailableTimeOfDay =
                tour.IsHomeBasedTour || tour.ParentTour == null
                                        ? 1
                                        : tour.ParentTour.DestinationArrivalTime + (tour.ParentTour.DestinationDepartureTime - tour.ParentTour.DestinationArrivalTime) / 2;

            var tourCategory  = tour.GetTourCategory();
            var primaryFlag   = ChoiceModelUtility.GetPrimaryFlag(tourCategory);
            var secondaryFlag = ChoiceModelUtility.GetSecondaryFlag(tourCategory);

            ChoiceModelUtility.DrawRandomTourTimePeriods(tour, tourCategory);

            var segment                  = Global.Kernel.Get <SamplingWeightsSettingsFactory>().SamplingWeightsSettings.GetTourDestinationSegment(tour.DestinationPurpose, tour.IsHomeBasedTour ? Global.Settings.TourPriorities.HomeBasedTour : Global.Settings.TourPriorities.WorkBasedTour, Global.Settings.Modes.Sov, person.PersonType);
            var excludedParcel           = person.UsualWorkParcel == null || person.UsualWorkParcelId == household.ResidenceParcelId || tour.DestinationPurpose != Global.Settings.Purposes.Work || tour.GetTourCategory() == Global.Settings.TourCategories.WorkBased ? null : person.UsualWorkParcel;
            var destinationSampler       = new DestinationSampler(choiceProbabilityCalculator, segment, sampleSize, tour.OriginParcel, excludedParcel, excludedParcel, choice);
            var tourDestinationUtilities = new TourDestinationUtilities(tour, sampleSize, primaryFlag, secondaryFlag, fastestAvailableTimeOfDay, maxAvailableMinutes);

            destinationSampler.SampleTourDestinations(tourDestinationUtilities);
        }
Esempio n. 17
0
        public void Run(PersonDayWrapper personDay, HouseholdDayWrapper householdDay)
        {
            if (personDay == null)
            {
                throw new ArgumentNullException("personDay");
            }

            personDay.Person.ResetRandom(903);

            int choice = 0;

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

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

            if (_helpers[ParallelUtility.threadLocalAssignedIndex.Value].ModelIsInEstimationMode)
            {
                choice = personDay.PatternType;

                RunModel(choiceProbabilityCalculator, personDay, householdDay, choice);

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

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

                personDay.PatternType = choice;
            }
        }
Esempio n. 18
0
        public void Run(IPersonWrapper person)
        {
            if (person == null)
            {
                throw new ArgumentNullException("person");
            }

            person.ResetRandom(5);

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

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

                RunModel(choiceProbabilityCalculator, person);

                choiceProbabilityCalculator.WriteObservation();
            }
            else
            {
                ChoiceProbabilityCalculator choiceProbabilityCalculator = _helpers[ParallelUtility.threadLocalAssignedIndex.Value].GetChoiceProbabilityCalculator(person.Id);

                RunModel(choiceProbabilityCalculator, person);

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

                if (chosenAlternative == null)
                {
                    Global.PrintFile.WriteNoAlternativesAvailableWarning(CHOICE_MODEL_NAME, "Run", person.Id);
                    return;
                }

                int choice = (int)chosenAlternative.Choice;
            }
        }
        public int Run(ITripWrapper trip, int choice)
        {
            if (trip == null)
            {
                throw new ArgumentNullException("trip");
            }

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

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

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

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

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

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

            return(choice);
        }
Esempio n. 20
0
        private void RunModel(ChoiceProbabilityCalculator choiceProbabilityCalculator, ITourWrapper tour, int sampleSize, IParcelWrapper choice = null)
        {
            //            var household = tour.Household;
            var person    = tour.Person;
            var personDay = tour.PersonDay;

            //            var totalAvailableMinutes =
            //                tour.ParentTour == null
            //                    ? personDay.TimeWindow.TotalAvailableMinutes(1, Global.Settings.Times.MinutesInADay)
            //                    : tour.ParentTour.TimeWindow.TotalAvailableMinutes(1, Global.Settings.Times.MinutesInADay);

            var maxAvailableMinutes =
                tour.ParentTour == null
                    ? personDay.TimeWindow.MaxAvailableMinutesAfter(121)
                    : tour.ParentTour.DestinationDepartureTime - tour.ParentTour.DestinationArrivalTime;

            //            var hoursAvailableInverse =
            //                tour.IsHomeBasedTour
            //                    ? (personDay.HomeBasedTours - personDay.SimulatedHomeBasedTours + 1) / (Math.Max(totalAvailableMinutes - 360, 30) / 60D)
            //                    : 1 / (Math.Max(totalAvailableMinutes, 1) / 60D);

            var fastestAvailableTimeOfDay =
                tour.IsHomeBasedTour || tour.ParentTour == null
                    ? 1
                    : tour.ParentTour.DestinationArrivalTime + (tour.ParentTour.DestinationDepartureTime - tour.ParentTour.DestinationArrivalTime) / 2;

            var tourCategory = tour.GetTourCategory();
            //            var primaryFlag = ChoiceModelUtility.GetPrimaryFlag(tourCategory);
            var secondaryFlag = ChoiceModelUtility.GetSecondaryFlag(tourCategory);

            ChoiceModelUtility.DrawRandomTourTimePeriods(tour, tourCategory);

            var segment                  = Global.ContainerDaySim.GetInstance <SamplingWeightsSettingsFactory>().SamplingWeightsSettings.GetTourDestinationSegment(tour.DestinationPurpose, tour.IsHomeBasedTour ? Global.Settings.TourPriorities.HomeBasedTour : Global.Settings.TourPriorities.WorkBasedTour, Global.Settings.Modes.Sov, person.PersonType);
            var destinationSampler       = new DestinationSampler(choiceProbabilityCalculator, segment, sampleSize, choice, tour.OriginParcel);
            var tourDestinationUtilities = new TourDestinationUtilities(this, tour, sampleSize, secondaryFlag, personDay.GetIsWorkOrSchoolPattern().ToFlag(), personDay.GetIsOtherPattern().ToFlag(), fastestAvailableTimeOfDay, maxAvailableMinutes);

            destinationSampler.SampleTourDestinations(tourDestinationUtilities);
        }
        public void Run(ITourWrapper tour, IHouseholdDayWrapper householdDay, int sampleSize)
        {
            if (tour == null)
            {
                throw new ArgumentNullException("tour");
            }
            //timesStarted++;

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

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

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

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

                choiceProbabilityCalculator.WriteObservation();
            }
        }
Esempio n. 22
0
        private void RunModel(ChoiceProbabilityCalculator choiceProbabilityCalculator, IPersonDayWrapper personDay, IHouseholdDayWrapper householdDay, int choice = Constants.DEFAULT_VALUE)
        {
            IHouseholdWrapper household = personDay.Household;
            IPersonWrapper    person    = personDay.Person;

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

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

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

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

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


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

                noUsualWorkZone = 0;
            }

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


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

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

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


            // Work and school stops
            alternative        = choiceProbabilityCalculator.GetAlternative(3, (personDay.Person.IsWorker && personDay.Person.IsStudent), choice == 3);
            alternative.Choice = 3;
            alternative.AddUtilityTerm(61, 1);
        }
Esempio n. 23
0
        private void RunModel(ChoiceProbabilityCalculator choiceProbabilityCalculator, IHouseholdWrapper household, int choice = Constants.DEFAULT_VALUE)
        {
//			var distanceToTransitCappedUnderQtrMile = household.ResidenceParcel.DistanceToTransitCappedUnderQtrMile();
//			var distanceToTransitQtrToHalfMile = household.ResidenceParcel.DistanceToTransitQtrToHalfMile();
            var foodRetailServiceMedicalLogBuffer1 = household.ResidenceParcel.FoodRetailServiceMedicalLogBuffer1();

            var workTourLogsumDifference   = 0D;           // (full or part-time workers) full car ownership vs. no car ownership
            var schoolTourLogsumDifference = 0D;           // (school) full car ownership vs. no car ownership

//			const double workTourOtherLogsumDifference = 0D; // (other workers) full car ownership vs. no car ownership

            foreach (var person in household.Persons)
            {
                if (person.IsWorker && person.UsualWorkParcel != null && person.UsualWorkParcelId != household.ResidenceParcelId)
                {
                    var destinationArrivalTime   = ChoiceModelUtility.GetDestinationArrivalTime(Global.Settings.Models.WorkTourModeModel);
                    var destinationDepartureTime = ChoiceModelUtility.GetDestinationDepartureTime(Global.Settings.Models.WorkTourModeModel);

                    var nestedAlternative1 = Global.ChoiceModelSession.Get <WorkTourModeModel>().RunNested(person, household.ResidenceParcel, person.UsualWorkParcel, destinationArrivalTime, destinationDepartureTime, household.HouseholdTotals.DrivingAgeMembers);
                    var nestedAlternative2 = Global.ChoiceModelSession.Get <WorkTourModeModel>().RunNested(person, household.ResidenceParcel, person.UsualWorkParcel, destinationArrivalTime, destinationDepartureTime, 0);

                    workTourLogsumDifference += nestedAlternative1 == null ? 0 : nestedAlternative1.ComputeLogsum();
                    workTourLogsumDifference -= nestedAlternative2 == null ? 0 : nestedAlternative2.ComputeLogsum();
                }

                if (person.IsDrivingAgeStudent && person.UsualSchoolParcel != null && person.UsualSchoolParcelId != household.ResidenceParcelId)
                {
                    var destinationArrivalTime   = ChoiceModelUtility.GetDestinationArrivalTime(Global.Settings.Models.SchoolTourModeModel);
                    var destinationDepartureTime = ChoiceModelUtility.GetDestinationDepartureTime(Global.Settings.Models.SchoolTourModeModel);

                    var nestedAlternative1 = Global.ChoiceModelSession.Get <SchoolTourModeModel>().RunNested(person, household.ResidenceParcel, person.UsualSchoolParcel, destinationArrivalTime, destinationDepartureTime, household.HouseholdTotals.DrivingAgeMembers);
                    var nestedAlternative2 = Global.ChoiceModelSession.Get <SchoolTourModeModel>().RunNested(person, household.ResidenceParcel, person.UsualSchoolParcel, destinationArrivalTime, destinationDepartureTime, 0);

                    schoolTourLogsumDifference += nestedAlternative1 == null ? 0 : nestedAlternative1.ComputeLogsum();
                    schoolTourLogsumDifference -= nestedAlternative2 == null ? 0 : nestedAlternative2.ComputeLogsum();
                }
            }

            // var votSegment = household.VotALSegment;
            //var taSegment = household.ResidenceParcel.TransitAccessSegment();

            //var aggregateLogsumDifference = // full car ownership vs. no car ownership
            //	Global.AggregateLogsums[household.ResidenceZoneId][Global.Settings.Purposes.HomeBasedComposite][Global.Settings.CarOwnerships.OneOrMoreCarsPerAdult][votSegment][taSegment] -
            //	Global.AggregateLogsums[household.ResidenceZoneId][Global.Settings.Purposes.HomeBasedComposite][Global.Settings.CarOwnerships.NoCars][votSegment][taSegment];

            var distanceToStop
                = household.ResidenceParcel.GetDistanceToTransit() > 0
                                          ? Math.Min(household.ResidenceParcel.GetDistanceToTransit(), 2 * Global.Settings.DistanceUnitsPerMile)  // JLBscale
                                          : 2 * Global.Settings.DistanceUnitsPerMile;

            var ruralFlag = household.ResidenceParcel.RuralFlag();

            // 0 AUTOS

            var alternative = choiceProbabilityCalculator.GetAlternative(0, true, choice == 0);

            alternative.Choice = 0;

            alternative.AddUtilityTerm(1, household.Has1Driver.ToFlag());
            alternative.AddUtilityTerm(5, household.Has2Drivers.ToFlag());
            alternative.AddUtilityTerm(9, household.Has3Drivers.ToFlag());
            alternative.AddUtilityTerm(13, household.Has4OrMoreDrivers.ToFlag());
//			alternative.AddUtility(17, 0);
            alternative.AddUtilityTerm(18, household.HasNoFullOrPartTimeWorker.ToFlag());
            alternative.AddUtilityTerm(19, household.HouseholdTotals.PartTimeWorkersPerDrivingAgeMembers);
//			alternative.AddUtility(23, household.HouseholdTotals.RetiredAdultsPerDrivingAgeMembers);
//			alternative.AddUtility(27, household.HouseholdTotals.UniversityStudentsPerDrivingAgeMembers);
            alternative.AddUtilityTerm(31, household.HouseholdTotals.DrivingAgeStudentsPerDrivingAgeMembers);
            alternative.AddUtilityTerm(35, household.HouseholdTotals.HomeBasedPersonsPerDrivingAgeMembers);
//			alternative.AddUtility(39, household.HouseholdTotals.ChildrenUnder5PerDrivingAgeMembers);
            alternative.AddUtilityTerm(43, household.Has0To15KIncome.ToFlag());
            alternative.AddUtilityTerm(47, household.Has50To75KIncome.ToFlag());
            alternative.AddUtilityTerm(51, household.Has75KPlusIncome.ToFlag());
            alternative.AddUtilityTerm(55, household.HasMissingIncome.ToFlag());
            alternative.AddUtilityTerm(59, workTourLogsumDifference);
//			alternative.AddUtility(61, workTourOtherLogsumDifference);
            alternative.AddUtilityTerm(63, schoolTourLogsumDifference);
//			alternative.AddUtility(67, aggregateLogsumDifference);
            alternative.AddUtilityTerm(69, Math.Log(distanceToStop));
//			alternative.AddUtility(70, Math.Log(1+household.ResidenceParcel.StopsTransitBuffer1));
            alternative.AddUtilityTerm(73, household.ResidenceParcel.ParkingOffStreetPaidDailyPriceBuffer1);
            alternative.AddUtilityTerm(75, foodRetailServiceMedicalLogBuffer1);
            alternative.AddUtilityTerm(77, workTourLogsumDifference * ruralFlag);
//			alternative.AddUtility(78, workTourOtherLogsumDifference * ruralFlag);
//			alternative.AddUtility(79, aggregateLogsumDifference * ruralFlag);
//			alternative.AddUtility(80, Math.Log(distanceToStop)*ruralFlag);
//			alternative.AddUtility(81, Math.Log(1+household.ResidenceParcel.StopsTransitBuffer1)*ruralFlag);
//			alternative.AddUtility(82, foodRetailServiceMedicalQtrMileLog * ruralFlag);
            alternative.AddUtilityTerm(83, ruralFlag);

            // 1 AUTO

            alternative = choiceProbabilityCalculator.GetAlternative(1, true, choice == 1);

            alternative.Choice = 1;

            alternative.AddUtilityTerm(6, household.Has2Drivers.ToFlag());
            alternative.AddUtilityTerm(10, household.Has3Drivers.ToFlag());
            alternative.AddUtilityTerm(14, household.Has4OrMoreDrivers.ToFlag());
//			alternative.AddUtility(17, 1D / Math.Max(household.HouseholdTotals.DrivingAgeMembers, 1)); // ratio of 1 car per driving age members
            alternative.AddUtilityTerm(18, household.Has1OrLessFullOrPartTimeWorkers.ToFlag());
            alternative.AddUtilityTerm(20, household.HouseholdTotals.PartTimeWorkersPerDrivingAgeMembers);
            alternative.AddUtilityTerm(24, household.HouseholdTotals.RetiredAdultsPerDrivingAgeMembers);
            alternative.AddUtilityTerm(28, household.HouseholdTotals.UniversityStudentsPerDrivingAgeMembers);
            alternative.AddUtilityTerm(32, household.HouseholdTotals.DrivingAgeStudentsPerDrivingAgeMembers);
            alternative.AddUtilityTerm(36, household.HouseholdTotals.HomeBasedPersonsPerDrivingAgeMembers);
//			alternative.AddUtility(40, household.HouseholdTotals.ChildrenUnder5PerDrivingAgeMembers);
            alternative.AddUtilityTerm(44, household.Has0To15KIncome.ToFlag());
            alternative.AddUtilityTerm(48, household.Has50To75KIncome.ToFlag());
            alternative.AddUtilityTerm(52, household.Has75KPlusIncome.ToFlag());
            alternative.AddUtilityTerm(56, household.HasMissingIncome.ToFlag());
            alternative.AddUtilityTerm(60, workTourLogsumDifference * household.HasMoreDriversThan1.ToFlag());
//			alternative.AddUtility(62, workTourOtherLogsumDifference * household.HasMoreDriversThan1.ToFlag());
//			alternative.AddUtility(64, schoolTourLogsumDifference * household.HasMoreDriversThan1.ToFlag());
//			alternative.AddUtility(68, aggregateLogsumDifference * household.HasMoreDriversThan1.ToFlag());
            alternative.AddUtilityTerm(72, Math.Log(1 + household.ResidenceParcel.StopsTransitBuffer1) * household.HasMoreDriversThan1.ToFlag());
            //alternative.AddUtility(74, household.ResidenceParcel.ParkingOffStreetPaidDailyPriceBuffer1 * household.HasMoreDriversThan1.ToFlag());
            alternative.AddUtilityTerm(76, foodRetailServiceMedicalLogBuffer1 * household.HasMoreDriversThan1.ToFlag());

            // 2 AUTOS

            alternative = choiceProbabilityCalculator.GetAlternative(2, true, choice == 2);

            alternative.Choice = 2;

            alternative.AddUtilityTerm(2, household.Has1Driver.ToFlag());
            alternative.AddUtilityTerm(11, household.Has3Drivers.ToFlag());
            alternative.AddUtilityTerm(15, household.Has4OrMoreDrivers.ToFlag());
//			alternative.AddUtility(17, 2D / Math.Max(household.HouseholdTotals.DrivingAgeMembers, 1)); // ratio of 2 cars per driving age members
            alternative.AddUtilityTerm(18, household.Has2OrLessFullOrPartTimeWorkers.ToFlag());
            alternative.AddUtilityTerm(60, workTourLogsumDifference * household.HasMoreDriversThan2.ToFlag());
//			alternative.AddUtility(62, workTourOtherLogsumDifference * household.HasMoreDriversThan2.ToFlag());
//			alternative.AddUtility(64, schoolTourLogsumDifference * household.HasMoreDriversThan2.ToFlag());
//			alternative.AddUtility(68, aggregateLogsumDifference * household.HasMoreDriversThan2.ToFlag());
            alternative.AddUtilityTerm(72, Math.Log(1 + household.ResidenceParcel.StopsTransitBuffer1) * household.HasMoreDriversThan2.ToFlag());
//			alternative.AddUtility(74, household.ResidenceParcel.ParkingOffStreetPaidDailyPriceBuffer1 * household.HasMoreDriversThan2.ToFlag());
            alternative.AddUtilityTerm(76, foodRetailServiceMedicalLogBuffer1 * household.HasMoreDriversThan2.ToFlag());

            // 3 AUTOS

            alternative = choiceProbabilityCalculator.GetAlternative(3, true, choice == 3);

            alternative.Choice = 3;

            alternative.AddUtilityTerm(3, household.Has1Driver.ToFlag());
            alternative.AddUtilityTerm(7, household.Has2Drivers.ToFlag());
            alternative.AddUtilityTerm(16, household.Has4OrMoreDrivers.ToFlag());
//			alternative.AddUtility(17, 3D / Math.Max(household.HouseholdTotals.DrivingAgeMembers, 1)); // ratio of 3 cars per driving age members
            alternative.AddUtilityTerm(18, household.Has3OrLessFullOrPartTimeWorkers.ToFlag());
//			alternative.AddUtility(21, household.HouseholdTotals.PartTimeWorkersPerDrivingAgeMembers);
            alternative.AddUtilityTerm(25, household.HouseholdTotals.RetiredAdultsPerDrivingAgeMembers);
            alternative.AddUtilityTerm(29, household.HouseholdTotals.UniversityStudentsPerDrivingAgeMembers);
//			alternative.AddUtility(33, household.HouseholdTotals.DrivingAgeStudentsPerDrivingAgeMembers);
            alternative.AddUtilityTerm(37, household.HouseholdTotals.HomeBasedPersonsPerDrivingAgeMembers);
            alternative.AddUtilityTerm(41, household.HouseholdTotals.ChildrenUnder5PerDrivingAgeMembers);
            alternative.AddUtilityTerm(45, household.Has0To15KIncome.ToFlag());
            alternative.AddUtilityTerm(49, household.Has50To75KIncome.ToFlag());
            alternative.AddUtilityTerm(53, household.Has75KPlusIncome.ToFlag());
            alternative.AddUtilityTerm(57, household.HasMissingIncome.ToFlag());
            alternative.AddUtilityTerm(60, workTourLogsumDifference * household.HasMoreDriversThan3.ToFlag());
//			alternative.AddUtility(62, workTourOtherLogsumDifference * household.HasMoreDriversThan3.ToFlag());
//			alternative.AddUtility(64, schoolTourLogsumDifference * household.HasMoreDriversThan3.ToFlag());
//			alternative.AddUtility(68, aggregateLogsumDifference * household.HasMoreDriversThan3.ToFlag());
            alternative.AddUtilityTerm(72, Math.Log(1 + household.ResidenceParcel.StopsTransitBuffer1) * household.HasMoreDriversThan3.ToFlag());
//			alternative.AddUtility(74, household.ResidenceParcel.ParkingOffStreetPaidDailyPriceBuffer1 * household.HasMoreDriversThan3.ToFlag());
            alternative.AddUtilityTerm(76, foodRetailServiceMedicalLogBuffer1 * household.HasMoreDriversThan3.ToFlag());

            // 4+ AUTOS

            alternative = choiceProbabilityCalculator.GetAlternative(4, true, choice == 4);

            alternative.Choice = 4;

            alternative.AddUtilityTerm(4, household.Has1Driver.ToFlag());
            alternative.AddUtilityTerm(8, household.Has2Drivers.ToFlag());
            alternative.AddUtilityTerm(12, household.Has3Drivers.ToFlag());
//			alternative.AddUtility(17, 4D / Math.Max(household.HouseholdTotals.DrivingAgeMembers, 1)); // ratio of 4 cars per driving age members
            alternative.AddUtilityTerm(18, household.Has4OrLessFullOrPartTimeWorkers.ToFlag());
            alternative.AddUtilityTerm(22, household.HouseholdTotals.PartTimeWorkersPerDrivingAgeMembers);
            alternative.AddUtilityTerm(26, household.HouseholdTotals.RetiredAdultsPerDrivingAgeMembers);
//			alternative.AddUtility(30, household.HouseholdTotals.UniversityStudentsPerDrivingAgeMembers);
            alternative.AddUtilityTerm(34, household.HouseholdTotals.DrivingAgeStudentsPerDrivingAgeMembers);
            alternative.AddUtilityTerm(38, household.HouseholdTotals.HomeBasedPersonsPerDrivingAgeMembers);
            alternative.AddUtilityTerm(42, household.HouseholdTotals.ChildrenUnder5PerDrivingAgeMembers);
            alternative.AddUtilityTerm(46, household.Has0To15KIncome.ToFlag());
            alternative.AddUtilityTerm(50, household.Has50To75KIncome.ToFlag());
            alternative.AddUtilityTerm(54, household.Has75KPlusIncome.ToFlag());
            alternative.AddUtilityTerm(58, household.HasMissingIncome.ToFlag());
            alternative.AddUtilityTerm(60, workTourLogsumDifference * household.HasMoreDriversThan4.ToFlag());
//			alternative.AddUtility(62, workTourOtherLogsumDifference * household.HasMoreDriversThan4.ToFlag());
//			alternative.AddUtility(64, schoolTourLogsumDifference * household.HasMoreDriversThan4.ToFlag());
//			alternative.AddUtility(68, aggregateLogsumDifference * household.HasMoreDriversThan4.ToFlag());
            alternative.AddUtilityTerm(72, Math.Log(1 + household.ResidenceParcel.StopsTransitBuffer1) * household.HasMoreDriversThan4.ToFlag());
//			alternative.AddUtility(74, household.ResidenceParcel.ParkingOffStreetPaidDailyPriceBuffer1 * household.HasMoreDriversThan4.ToFlag());
            alternative.AddUtilityTerm(76, foodRetailServiceMedicalLogBuffer1 * household.HasMoreDriversThan4.ToFlag());
        }
        private void RunModel(ChoiceProbabilityCalculator choiceProbabilityCalculator, TourWrapper tour, int nCallsForTour, HouseholdDayWrapper householdDay, int choice = Constants.DEFAULT_VALUE)
        {
            IEnumerable <PersonDayWrapper> orderedPersonDays = householdDay.PersonDays.OrderBy(p => p.GetJointTourParticipationPriority()).ToList().Cast <PersonDayWrapper>();

            Framework.DomainModels.Wrappers.IPersonWrapper    person    = tour.Person;
            Framework.DomainModels.Wrappers.IPersonDayWrapper personDay = tour.PersonDay;

            int adultFemaleFlag    = person.IsAdultFemale.ToFlag();
            int partTimeWorkerFlag = person.IsPartTimeWorker.ToFlag();

            double foodBuffer2      = tour.DestinationParcel.EmploymentFoodBuffer2;
            double medBuffer2       = tour.DestinationParcel.EmploymentMedicalBuffer2;
            double intDensBuffer2   = tour.DestinationParcel.IntersectionDensity34Buffer2();
            double serviceBuffer2   = tour.DestinationParcel.EmploymentServiceBuffer2;
            double totEmpBuffer2    = tour.DestinationParcel.EmploymentTotalBuffer2;
            double totHHBuffer2     = tour.DestinationParcel.HouseholdsBuffer2;
            double openSpaceBuffer2 = tour.DestinationParcel.OpenSpaceType1Buffer2;
            double mixedUse         = tour.DestinationParcel.MixedUse2Index2();
            //var retailBuffer2 = tour.DestinationParcel.EmploymentRetailBuffer2;
            //var retailBuffer1 = tour.DestinationParcel.EmploymentRetailBuffer1;

            int carOwnership = person.GetCarOwnershipSegment();
            int noCarsFlag   = FlagUtility.GetNoCarsFlag(carOwnership);
            //var carCompetitionFlag = AggregateLogsumsCalculator.GetCarCompetitionFlag(carOwnership);

            int votALSegment = tour.GetVotALSegment();

            int    workTaSegment       = tour.DestinationParcel.TransitAccessSegment();
            double workAggregateLogsum = Global.AggregateLogsums[tour.DestinationParcel.ZoneId]
                                         [Global.Settings.Purposes.WorkBased][carOwnership][votALSegment][workTaSegment];
            double shopAggregateLogsum = Global.AggregateLogsums[tour.DestinationParcel.ZoneId]
                                         [Global.Settings.Purposes.Shopping][carOwnership][votALSegment][workTaSegment];
            //var mealAggregateLogsum = Global.AggregateLogsums[tour.DestinationParcel.ZoneId]
            //[Global.Settings.Purposes.Meal][carOwnership][votALSegment][workTaSegment];
            //var persBusAggregateLogsum = Global.AggregateLogsums[tour.DestinationParcel.ZoneId]
            //[Global.Settings.Purposes.PersonalBusiness][carOwnership][votALSegment][workTaSegment];
            //var socialAggregateLogsum = Global.AggregateLogsums[tour.DestinationParcel.ZoneId]
            //[Global.Settings.Purposes.Social][carOwnership][votALSegment][workTaSegment];

            int numStopPurposes = (personDay.SimulatedEscortStops > 1).ToFlag() + (personDay.SimulatedShoppingStops > 1).ToFlag() + (personDay.SimulatedMealStops > 1).ToFlag() +
                                  (personDay.SimulatedPersonalBusinessStops > 1).ToFlag() + (personDay.SimulatedSocialStops > 1).ToFlag() +
                                  (personDay.SimulatedRecreationStops > 1).ToFlag() + (personDay.SimulatedMedicalStops > 1).ToFlag();

            int    workDestinationArrivalTime   = ChoiceModelUtility.GetDestinationArrivalTime(Global.Settings.Models.WorkTourModeModel);
            int    workDestinationDepartureTime = ChoiceModelUtility.GetDestinationDepartureTime(Global.Settings.Models.WorkTourModeModel);
            double workLogsum = 0;

            ChoiceProbabilityCalculator.Alternative nestedAlternative = Global.ChoiceModelSession.Get <WorkTourModeTimeModel>().RunNested(personDay, person.Household.ResidenceParcel, person.UsualWorkParcel, workDestinationArrivalTime, workDestinationDepartureTime, person.Household.VehiclesAvailable);
            workLogsum = nestedAlternative == null ? 0 : nestedAlternative.ComputeLogsum();

            //double logTimeAtWork = Math.Log(1 + (workDestinationDepartureTime - workDestinationArrivalTime) / 60);

            //int countMandatoryKids = (from personDayHH in orderedPersonDays where personDayHH.PatternType == 1 && personDayHH.Person.Age < 12 select personDayHH.PatternType).Count();
            //int countNonMandatory = (from personDayHH in orderedPersonDays where personDayHH.PatternType == 2 select personDayHH.PatternType).Count();
            //int countAtHome = (from personDayHH in orderedPersonDays where personDayHH.PatternType == 3 select personDayHH.PatternType).Count();
            int countNonMandatoryKids = (from personDayHH in orderedPersonDays where personDayHH.PatternType == 2 && personDayHH.Person.Age < 12 select personDayHH.PatternType).Count();

            // NONE_OR_HOME

            ChoiceProbabilityCalculator.Alternative alternative = choiceProbabilityCalculator.GetAlternative(Global.Settings.Purposes.NoneOrHome, true, choice == Global.Settings.Purposes.NoneOrHome);

            alternative.Choice = Global.Settings.Purposes.NoneOrHome;

            alternative.AddUtilityTerm(1, (nCallsForTour > 1).ToFlag());
            alternative.AddUtilityTerm(3, personDay.TwoOrMoreWorkToursExist().ToFlag());
            alternative.AddUtilityTerm(4, noCarsFlag);
            //alternative.AddUtilityTerm(5, carCompetitionFlag);
            alternative.AddUtilityTerm(6, partTimeWorkerFlag);
            //alternative.AddUtilityTerm(8, (person.UsualModeToWork != Global.Settings.Modes.Sov).ToFlag());
            alternative.AddUtilityTerm(10, person.TransitPassOwnership);
            //alternative.AddUtilityTerm(15, logTimeAtWork);
            alternative.AddUtilityTerm(17, numStopPurposes);
            alternative.AddUtilityTerm(18, Math.Log(personDay.GetTotalCreatedTours() + 1));

            // WORK

            alternative = choiceProbabilityCalculator.GetAlternative(Global.Settings.Purposes.Work, personDay.WorkStops > 0, choice == Global.Settings.Purposes.Work);

            alternative.Choice = Global.Settings.Purposes.Work;

            alternative.AddUtilityTerm(21, 1);
            alternative.AddUtilityTerm(22, Math.Log(1 + totEmpBuffer2));
            //alternative.AddUtilityTerm(23, (person.Household.Income<30000).ToFlag());
            alternative.AddUtilityTerm(24, (person.Household.Has100KPlusIncome).ToFlag());
            alternative.AddUtilityTerm(25, workLogsum);

            // SCHOOL
            //no observations in the PSRC dataset
            alternative = choiceProbabilityCalculator.GetAlternative(Global.Settings.Purposes.School, false, choice == Global.Settings.Purposes.School);

            alternative.Choice = Global.Settings.Purposes.School;

            //alternative.AddUtilityTerm(3, 1);

            // ESCORT

            alternative = choiceProbabilityCalculator.GetAlternative(Global.Settings.Purposes.Escort, personDay.EscortStops > 0, choice == Global.Settings.Purposes.Escort);

            alternative.Choice = Global.Settings.Purposes.Escort;

            alternative.AddUtilityTerm(31, 1);
            //alternative.AddUtilityTerm(33, k8HighSchoolQtrMileLog);
            alternative.AddUtilityTerm(36, countNonMandatoryKids);
            alternative.AddUtilityTerm(37, adultFemaleFlag);
            //alternative.AddUtilityTerm(38, person.Household.Size);
            //alternative.AddUtilityTerm(39, householdDay.Household.HouseholdTotals.ChildrenAge5Through15);
            //alternative.AddUtilityTerm(40, partTimeWorkerFlag);
            alternative.AddUtilityTerm(39, workLogsum);

            // PERSONAL_BUSINESS

            alternative = choiceProbabilityCalculator.GetAlternative(Global.Settings.Purposes.PersonalBusiness, personDay.PersonalBusinessStops > 0, choice == Global.Settings.Purposes.PersonalBusiness);

            alternative.Choice = Global.Settings.Purposes.PersonalBusiness;

            alternative.AddUtilityTerm(41, 1);
            //alternative.AddUtilityTerm(43, persBusAggregateLogsum);
            alternative.AddUtilityTerm(45, Math.Log(1 + totEmpBuffer2));
            //alternative.AddUtilityTerm(48, (person.Household.Income>90000).ToFlag());
            alternative.AddUtilityTerm(49, (person.Household.HouseholdTotals.ChildrenUnder16));


            // SHOPPING

            alternative = choiceProbabilityCalculator.GetAlternative(Global.Settings.Purposes.Shopping, personDay.ShoppingStops > 0, choice == Global.Settings.Purposes.Shopping);

            alternative.Choice = Global.Settings.Purposes.Shopping;

            alternative.AddUtilityTerm(51, 1);
            //alternative.AddUtilityTerm(53, retailBuffer1);
            //alternative.AddUtilityTerm(54, partTimeWorkerFlag);
            alternative.AddUtilityTerm(55, (person.Household.Has100KPlusIncome).ToFlag());
            alternative.AddUtilityTerm(57, person.Household.HouseholdTotals.ChildrenUnder16);
            alternative.AddUtilityTerm(58, shopAggregateLogsum);
            //alternative.AddUtilityTerm(59, person.Household.Size);
            //alternative.AddUtilityTerm(59, (person.Household.Income<30000).ToFlag());


            // MEAL

            alternative = choiceProbabilityCalculator.GetAlternative(Global.Settings.Purposes.Meal, personDay.MealStops > 0, choice == Global.Settings.Purposes.Meal);

            alternative.Choice = Global.Settings.Purposes.Meal;

            alternative.AddUtilityTerm(71, 1);
            alternative.AddUtilityTerm(73, Math.Log(1 + foodBuffer2));
            alternative.AddUtilityTerm(74, mixedUse);
            alternative.AddUtilityTerm(75, intDensBuffer2);
            //alternative.AddUtilityTerm(76, (person.Household.Income<30000).ToFlag());
            //alternative.AddUtilityTerm(77, person.Household.HouseholdTotals.ChildrenUnder16);

            // SOCIAL

            alternative = choiceProbabilityCalculator.GetAlternative(Global.Settings.Purposes.Social, personDay.SocialStops > 0, choice == Global.Settings.Purposes.Social);

            alternative.Choice = Global.Settings.Purposes.Social;

            alternative.AddUtilityTerm(91, 1);
            alternative.AddUtilityTerm(93, person.Household.HouseholdTotals.ChildrenUnder16);
            alternative.AddUtilityTerm(94, (person.Age < 35).ToFlag());
            //alternative.AddUtilityTerm(115, workAggregateLogsum);
            alternative.AddUtilityTerm(96, Math.Log(1 + totHHBuffer2 + totEmpBuffer2));
            alternative.AddUtilityTerm(97, (person.Household.Income < 30000).ToFlag());
            //alternative.AddUtilityTerm(118, person.Household.Has100KPlusIncome.ToFlag());

            // RECREATION

            alternative = choiceProbabilityCalculator.GetAlternative(Global.Settings.Purposes.Recreation, personDay.RecreationStops > 0, choice == Global.Settings.Purposes.Recreation);

            alternative.Choice = Global.Settings.Purposes.Recreation;

            alternative.AddUtilityTerm(111, 1);
            alternative.AddUtilityTerm(113, person.Household.HouseholdTotals.ChildrenUnder16);
            alternative.AddUtilityTerm(114, (person.Age < 35).ToFlag());
            alternative.AddUtilityTerm(116, Math.Log(1 + totHHBuffer2 + totEmpBuffer2));
            alternative.AddUtilityTerm(117, (person.Household.Income < 30000).ToFlag());
            alternative.AddUtilityTerm(118, (person.Household.Income > 100000).ToFlag());
            alternative.AddUtilityTerm(119, Math.Log(1 + openSpaceBuffer2));

            // MEDICAL

            alternative = choiceProbabilityCalculator.GetAlternative(Global.Settings.Purposes.Medical, personDay.MedicalStops > 0, choice == Global.Settings.Purposes.Medical);

            alternative.Choice = Global.Settings.Purposes.Medical;

            alternative.AddUtilityTerm(121, 1);
            alternative.AddUtilityTerm(123, adultFemaleFlag);
            alternative.AddUtilityTerm(124, (person.Age > 65).ToFlag());
            alternative.AddUtilityTerm(125, Math.Log(1 + medBuffer2));
            //alternative.AddUtilityTerm(126, workAggregateLogsum);

            //alternative.AddNestedAlternative(12, 1, 60);
        }
Esempio n. 25
0
        private void RunModel(ChoiceProbabilityCalculator choiceProbabilityCalculator, PersonWrapper person, int choice = Constants.DEFAULT_VALUE)
        {
            Framework.DomainModels.Wrappers.IParcelWrapper homeParcel   = person.Household.ResidenceParcel;
            Framework.DomainModels.Wrappers.IParcelWrapper workParcel   = person.IsUniversityStudent ? person.UsualSchoolParcel : person.UsualWorkParcel;
            Framework.DomainModels.Wrappers.IParcelWrapper schoolParcel = person.IsUniversityStudent ? null : person.UsualSchoolParcel;

            bool workParcelMissing   = workParcel == null;
            bool schoolParcelMissing = schoolParcel == null;

            const double maxTranDist = 1.5;

            double homeTranDist = 99.0;

            if (homeParcel.GetDistanceToTransit() >= 0.0001 && homeParcel.GetDistanceToTransit() <= maxTranDist)
            {
                homeTranDist = homeParcel.GetDistanceToTransit();
            }

            double workTranDist = 99.0;

            if (!workParcelMissing && workParcel.GetDistanceToTransit() >= 0.0001 && workParcel.GetDistanceToTransit() <= maxTranDist)
            {
                workTranDist = workParcel.GetDistanceToTransit();
            }

            double schoolTranDist = 99.0;

            if (!schoolParcelMissing && schoolParcel.GetDistanceToTransit() >= 0.0001 && schoolParcel.GetDistanceToTransit() <= maxTranDist)
            {
                schoolTranDist = schoolParcel.GetDistanceToTransit();
            }

            double workGenTimeNoPass   = -99.0;
            double workGenTimeWithPass = -99.0;

            if (!workParcelMissing && workTranDist < maxTranDist && homeTranDist < maxTranDist)
            {
                IEnumerable <IPathTypeModel> pathTypeModels =
                    PathTypeModelFactory.Singleton.Run(
                        person.Household.RandomUtility,
                        homeParcel,
                        workParcel,
                        Global.Settings.Times.EightAM,
                        Global.Settings.Times.FivePM,
                        Global.Settings.Purposes.Work,
                        Global.Coefficients_BaseCostCoefficientPerMonetaryUnit,
                        Global.Configuration.Coefficients_MeanTimeCoefficient_Work,
                        true,
                        1,
                        0,
                        false,
                        0.0,
                        false,
                        Global.Settings.Modes.Transit);

                IPathTypeModel path = pathTypeModels.First();

                workGenTimeNoPass = path.GeneralizedTimeLogsum;

                // intermediate variable of type IEnumerable<dynamic> is needed to acquire First() method as extension
                pathTypeModels =
                    PathTypeModelFactory.Singleton.Run(
                        person.Household.RandomUtility,
                        homeParcel,
                        workParcel,
                        Global.Settings.Times.EightAM,
                        Global.Settings.Times.FivePM,
                        Global.Settings.Purposes.Work,
                        Global.Coefficients_BaseCostCoefficientPerMonetaryUnit,
                        Global.Configuration.Coefficients_MeanTimeCoefficient_Work,
                        /* isDrivingAge */ true,
                        /* householdCars */ 1,
                        /* transitPassOwnership */ 1,
                        /* carsAreAVs */ false,
                        /* transitDiscountFraction */ 1.0,
                        /* randomChoice */ false,
                        Global.Settings.Modes.Transit);

                path = pathTypeModels.First();

                workGenTimeWithPass = path.GeneralizedTimeLogsum;
            }

            //			double schoolGenTimeNoPass = -99.0;
            double schoolGenTimeWithPass = -99.0;

            if (!schoolParcelMissing && schoolTranDist < maxTranDist && homeTranDist < maxTranDist)
            {
                //				schoolGenTimeNoPass = path.GeneralizedTimeLogsum;

                IEnumerable <IPathTypeModel> pathTypeModels =
                    PathTypeModelFactory.Singleton.Run(
                        person.Household.RandomUtility,
                        homeParcel,
                        schoolParcel,
                        Global.Settings.Times.EightAM,
                        Global.Settings.Times.ThreePM,
                        Global.Settings.Purposes.School,
                        Global.Coefficients_BaseCostCoefficientPerMonetaryUnit,
                        Global.Configuration.Coefficients_MeanTimeCoefficient_Other,
                        true,
                        1,
                        1,
                        false,
                        1.0,
                        false,
                        Global.Settings.Modes.Transit);

                IPathTypeModel path = pathTypeModels.First();
                schoolGenTimeWithPass = path.GeneralizedTimeLogsum;
            }

            const double inflection = 0.50;

            double homeTranDist1 = Math.Pow(Math.Min(inflection, homeTranDist), 2.0);
            double homeTranDist2 = Math.Pow(Math.Max(homeTranDist - inflection, 0), 0.5);

            //			var workTranDist1 = Math.Pow(Math.Min(inflection, workTranDist),2.0);
            //			var workTranDist2 = Math.Pow(Math.Max(workTranDist - inflection, 0),0.5);

            const double minimumAggLogsum = -15.0;
            int          votSegment       = person.Household.GetVotALSegment();

            int    homeTaSegment            = homeParcel.TransitAccessSegment();
            double homeAggregateLogsumNoCar = Math.Max(minimumAggLogsum, Global.AggregateLogsums[homeParcel.ZoneId][Global.Settings.Purposes.HomeBasedComposite][Global.Settings.CarOwnerships.NoCars][votSegment][homeTaSegment]);

            int    workTaSegment            = workParcelMissing ? 0 : workParcel.TransitAccessSegment();
            double workAggregateLogsumNoCar =
                workParcelMissing
                    ? 0
                    : Math.Max(minimumAggLogsum, Global.AggregateLogsums[workParcel.ZoneId][Global.Settings.Purposes.WorkBased][Global.Settings.CarOwnerships.NoCars][votSegment][workTaSegment]);

            int    schoolTaSegment            = schoolParcelMissing ? 0 : schoolParcel.TransitAccessSegment();
            double schoolAggregateLogsumNoCar =
                schoolParcelMissing
                    ? 0
                    : Math.Max(minimumAggLogsum, Global.AggregateLogsums[schoolParcel.ZoneId][Global.Settings.Purposes.WorkBased][Global.Settings.CarOwnerships.NoCars][votSegment][schoolTaSegment]);

            double transitPassCostChange = !Global.Configuration.IsInEstimationMode ? Global.Configuration.PathImpedance_TransitPassCostPercentChangeVersusBase : 0;

            double workTourLogsumDifference   = 0D; // (full or part-time workers) full car ownership vs. no car ownership
            double schoolTourLogsumDifference = 0D; // (school) full car ownership vs. no car ownership

            Framework.DomainModels.Wrappers.IHouseholdWrapper household = person.Household;
            if (person.UsualWorkParcel != null && person.UsualWorkParcelId != household.ResidenceParcelId)
            {
                int destinationArrivalTime   = ChoiceModelUtility.GetDestinationArrivalTime(Global.Settings.Models.WorkTourModeModel);
                int destinationDepartureTime = ChoiceModelUtility.GetDestinationDepartureTime(Global.Settings.Models.WorkTourModeModel);
                //JLB 201602
                //var nestedAlternative1 = Global.ChoiceModelSession.Get<WorkTourModeTimeModel>().RunNested(person, household.ResidenceParcel, person.UsualWorkParcel, destinationArrivalTime, destinationDepartureTime, household.VehiclesAvailable, 1.0);
                //var nestedAlternative2 = Global.ChoiceModelSession.Get<WorkTourModeTimeModel>().RunNested(person, household.ResidenceParcel, person.UsualWorkParcel, destinationArrivalTime, destinationDepartureTime, household.VehiclesAvailable, 0.0);
                ChoiceProbabilityCalculator.Alternative nestedAlternative1 = Global.ChoiceModelSession.Get <TourModeTimeModel>().RunNested(person, household.ResidenceParcel, person.UsualWorkParcel, destinationArrivalTime, destinationDepartureTime, household.VehiclesAvailable, 1.0, Global.Settings.Purposes.Work);
                ChoiceProbabilityCalculator.Alternative nestedAlternative2 = Global.ChoiceModelSession.Get <TourModeTimeModel>().RunNested(person, household.ResidenceParcel, person.UsualWorkParcel, destinationArrivalTime, destinationDepartureTime, household.VehiclesAvailable, 0.0, Global.Settings.Purposes.Work);

                workTourLogsumDifference = nestedAlternative1 == null ? 0 : nestedAlternative1.ComputeLogsum();
                workTourLogsumDifference = nestedAlternative2 == null ? 0 : nestedAlternative2.ComputeLogsum();
            }

            if (person.UsualSchoolParcel != null && person.UsualSchoolParcelId != household.ResidenceParcelId)
            {
                int destinationArrivalTime   = ChoiceModelUtility.GetDestinationArrivalTime(Global.Settings.Models.SchoolTourModeModel);
                int destinationDepartureTime = ChoiceModelUtility.GetDestinationDepartureTime(Global.Settings.Models.SchoolTourModeModel);

                //JLB 201602
                //var nestedAlternative1 = Global.ChoiceModelSession.Get<SchoolTourModeTimeModel>().RunNested(person, household.ResidenceParcel, person.UsualSchoolParcel, destinationArrivalTime, destinationDepartureTime, household.VehiclesAvailable, 1.0);
                //var nestedAlternative2 = Global.ChoiceModelSession.Get<SchoolTourModeTimeModel>().RunNested(person, household.ResidenceParcel, person.UsualSchoolParcel, destinationArrivalTime, destinationDepartureTime, household.VehiclesAvailable, 0.0);
                ChoiceProbabilityCalculator.Alternative nestedAlternative1 = Global.ChoiceModelSession.Get <TourModeTimeModel>().RunNested(person, household.ResidenceParcel, person.UsualSchoolParcel, destinationArrivalTime, destinationDepartureTime, household.VehiclesAvailable, 1.0, Global.Settings.Purposes.School);
                ChoiceProbabilityCalculator.Alternative nestedAlternative2 = Global.ChoiceModelSession.Get <TourModeTimeModel>().RunNested(person, household.ResidenceParcel, person.UsualSchoolParcel, destinationArrivalTime, destinationDepartureTime, household.VehiclesAvailable, 0.0, Global.Settings.Purposes.School);

                schoolTourLogsumDifference = nestedAlternative1 == null ? 0 : nestedAlternative1.ComputeLogsum();
                schoolTourLogsumDifference = nestedAlternative2 == null ? 0 : nestedAlternative2.ComputeLogsum();
            }



            //Stefan variables
            double netIncomeNetCarOwnership = Math.Max(0, (person.Household.Income / 1000.0) / 2.0 - 2.441 * 15.0 * person.Household.VehiclesAvailable); //net income minus annual cost to use household's cars in 1000s of DKK
                                                                                                                                                         //set household characteristics here that depend on person characteristics
            int numberAdults   = 0;
            int numberChildren = 0;

            foreach (PersonWrapper p in person.Household.Persons)
            {
                if (p.Age >= 18)
                {
                    numberAdults++;
                }
                else
                {
                    numberChildren++;
                }
            }
            Framework.DomainModels.Wrappers.IParcelWrapper usualParcel = person.IsFullOrPartTimeWorker ? person.UsualWorkParcel : null;
            usualParcel = (usualParcel == null && person.UsualSchoolParcel != null) ? person.UsualSchoolParcel : null;
            int    parkingSearchTime = 0;
            double commuteDistance   = 0.0;
            int    parkingCost       = 0;
            int    model             = 3;

            if (usualParcel != null)
            {
                //parkingSearchTime = usualParcel.PSearchTime07_08; //uncomment when the new parcel attributes have been defined
                commuteDistance = ImpedanceRoster.GetValue("distance", Global.Settings.Modes.Sov, Global.Settings.PathTypes.FullNetwork, 1.0, Global.Settings.Times.EightAM, household.ResidenceParcel, usualParcel).Variable;
                //parkingCost = usualParcel.ParkingCostPerHour8_18;  //uncomment when the new parcel attributes have been defined
                if (person.IsFulltimeWorker && usualParcel == person.UsualWorkParcel)
                {
                    parkingCost = parkingCost * 8;
                    model       = 1;
                }
                else if (person.IsPartTimeWorker && usualParcel == person.UsualWorkParcel)
                {
                    parkingCost = parkingCost * 4;
                    model       = 1;
                }
                else
                {
                    parkingCost = parkingCost * 6; // parking for school
                    model       = 2;
                }
            }


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

            alternative.AddUtilityTerm(1, 0.0);

            // 1 Transit pass

            double stefanUtility = 0.0;

            alternative        = choiceProbabilityCalculator.GetAlternative(1, true, choice == 1);
            alternative.Choice = 1;

            if (model == 1 && person.Household.VehiclesAvailable == 0)
            {
                double beta001 = -0.33;
                double beta002 = -0.34;
                double beta003 = -1.15;
                double beta004 = -0.34;
                double beta005 = 0.0;
                double beta006 = 0.0;
                double beta007 = 0.0;
                double beta008 = 0.0;
                double beta009 = 0.0;
                double beta010 = 0.0;
                double beta011 = 0.0;
                double beta012 = 0.0;
                stefanUtility =
                    beta001 * 1.0 +
                    beta002 * numberChildren +
                    beta003 * netIncomeNetCarOwnership +
                    beta004 * person.IsMale.ToFlag() +
                    beta005 * (person.IsAdultFemale && numberAdults == 1).ToFlag() +
                    beta006 * (person.IsAdultFemale && numberAdults > 1).ToFlag() +
                    beta007 * person.Age +
                    beta008 * Math.Pow(person.Age, 2.0) +
                    beta009 * (person.Household.VehiclesAvailable >= 2).ToFlag() +
                    beta010 * (person.IsAdultMale && numberAdults == 1).ToFlag() +
                    beta011 * Math.Min(person.Household.ResidenceParcel.DistanceToLocalBus, 2.0) +
                    beta012 * Math.Min(5.0, person.Household.ResidenceParcel.DistanceToExpressBus) +
                    0.0;
                //Stefan utility
                //alternative.AddUtilityTerm(1, 1.0);
                //alternative.AddUtilityTerm(2, numberChildren);
                //alternative.AddUtilityTerm(3, netIncomeNetCarOwnership);
                //alternative.AddUtilityTerm(4, person.IsMale.ToFlag());
                //alternative.AddUtilityTerm(5, (person.IsAdultFemale && numberAdults == 1).ToFlag());
                //alternative.AddUtilityTerm(6, (person.IsAdultFemale && numberAdults > 1).ToFlag());
                //alternative.AddUtilityTerm(7, person.Age);
                //alternative.AddUtilityTerm(8, Math.Pow(person.Age, 2.0));
                //non-worker/non-student models only
                //alternative.AddUtilityTerm(9, (person.Household.VehiclesAvailable >= 2).ToFlag());
                //alternative.AddUtilityTerm(10, (person.IsAdultMale && numberAdults == 1).ToFlag());
                //alternative.AddUtilityTerm(11, Math.Min(person.Household.ResidenceParcel.DistanceToLocalBus, 2.0));
                //alternative.AddUtilityTerm(12, Math.Min(5.0, person.Household.ResidenceParcel.DistanceToExpressBus));
                alternative.AddUtilityTerm(1, stefanUtility); // this composite replaces terms *1-*12 above

                //Stefan impedance (try replacign these with logsums)
                alternative.AddUtilityTerm(13, Math.Min(person.Household.ResidenceParcel.DistanceToLocalBus, person.Household.ResidenceParcel.DistanceToExpressBus));
                alternative.AddUtilityTerm(14, (commuteDistance > 0 && commuteDistance < 3).ToFlag());
                alternative.AddUtilityTerm(15, (commuteDistance >= 7 && commuteDistance < 13).ToFlag());
                alternative.AddUtilityTerm(16, (commuteDistance >= 13).ToFlag());
                alternative.AddUtilityTerm(17, parkingCost);
                alternative.AddUtilityTerm(18, parkingSearchTime);
                //commute logsum difference variable (with and without transit pass)
                alternative.AddUtilityTerm(19, workTourLogsumDifference);
            }
            else if (model == 1 && person.Household.VehiclesAvailable == 1)
            {
                double beta101 = -1.16;
                int    beta102 = 0;
                int    beta103 = 0;
                int    beta104 = 0;
                int    beta105 = 0;
                double beta106 = 0.63;
                double beta107 = -0.76;
                double beta108 = 0.09;
                int    beta109 = 0;
                int    beta110 = 0;
                int    beta111 = 0;
                int    beta112 = 0;
                stefanUtility =
                    beta101 * 1.0 +
                    beta102 * numberChildren +
                    beta103 * netIncomeNetCarOwnership +
                    beta104 * person.IsMale.ToFlag() +
                    beta105 * (person.IsAdultFemale && numberAdults == 1).ToFlag() +
                    beta106 * (person.IsAdultFemale && numberAdults > 1).ToFlag() +
                    beta107 * person.Age +
                    beta108 * Math.Pow(person.Age, 2.0) +
                    beta109 * (person.Household.VehiclesAvailable >= 2).ToFlag() +
                    beta110 * (person.IsAdultMale && numberAdults == 1).ToFlag() +
                    beta111 * Math.Min(person.Household.ResidenceParcel.DistanceToLocalBus, 2.0) +
                    beta112 * Math.Min(5.0, person.Household.ResidenceParcel.DistanceToExpressBus) +
                    0.0;
                //Stefan utility
                //alternative.AddUtilityTerm(101, 1.0);
                //alternative.AddUtilityTerm(102, numberChildren);
                //alternative.AddUtilityTerm(103, netIncomeNetCarOwnership);
                //alternative.AddUtilityTerm(104, person.IsMale.ToFlag());
                //alternative.AddUtilityTerm(105, (person.IsAdultFemale && numberAdults == 1).ToFlag());
                //alternative.AddUtilityTerm(106, (person.IsAdultFemale && numberAdults > 1).ToFlag());
                //alternative.AddUtilityTerm(107, person.Age);
                //alternative.AddUtilityTerm(108, Math.Pow(person.Age, 2.0));
                ////non-worker/non-student models only
                //alternative.AddUtilityTerm(109, (person.Household.VehiclesAvailable >= 2).ToFlag());
                //alternative.AddUtilityTerm(110, (person.IsAdultMale && numberAdults == 1).ToFlag());
                //alternative.AddUtilityTerm(111, Math.Min(person.Household.ResidenceParcel.DistanceToLocalBus, 2.0));
                //alternative.AddUtilityTerm(112, Math.Min(5.0, person.Household.ResidenceParcel.DistanceToExpressBus));
                alternative.AddUtilityTerm(101, stefanUtility); // this composite replaces terms *1-*12 above
                                                                //Stefan impedance (try replacign these with logsums)
                alternative.AddUtilityTerm(113, Math.Min(person.Household.ResidenceParcel.DistanceToLocalBus, person.Household.ResidenceParcel.DistanceToExpressBus));
                alternative.AddUtilityTerm(114, (commuteDistance > 0 && commuteDistance < 3).ToFlag());
                alternative.AddUtilityTerm(115, (commuteDistance >= 7 && commuteDistance < 13).ToFlag());
                alternative.AddUtilityTerm(116, (commuteDistance >= 13).ToFlag());
                alternative.AddUtilityTerm(117, parkingCost);
                alternative.AddUtilityTerm(118, parkingSearchTime);
                //commute logsum difference variable (with and without transit pass)
                alternative.AddUtilityTerm(119, workTourLogsumDifference);
            }
            else if (model == 1 && person.Household.VehiclesAvailable >= 2)
            {
                double beta201 = -0.54;
                int    beta202 = 0;
                int    beta203 = 0;
                int    beta204 = 0;
                double beta205 = 1.35;
                double beta206 = 0.42;
                double beta207 = -1.5;
                double beta208 = 0.17;
                int    beta209 = 0;
                int    beta210 = 0;
                int    beta211 = 0;
                int    beta212 = 0;
                stefanUtility =
                    beta201 * 1.0 +
                    beta202 * numberChildren +
                    beta203 * netIncomeNetCarOwnership +
                    beta204 * person.IsMale.ToFlag() +
                    beta205 * (person.IsAdultFemale && numberAdults == 1).ToFlag() +
                    beta206 * (person.IsAdultFemale && numberAdults > 1).ToFlag() +
                    beta207 * person.Age +
                    beta208 * Math.Pow(person.Age, 2.0) +
                    beta209 * (person.Household.VehiclesAvailable >= 2).ToFlag() +
                    beta210 * (person.IsAdultMale && numberAdults == 1).ToFlag() +
                    beta211 * Math.Min(person.Household.ResidenceParcel.DistanceToLocalBus, 2.0) +
                    beta212 * Math.Min(5.0, person.Household.ResidenceParcel.DistanceToExpressBus) +
                    0.0;
                //Stefan utility
                //alternative.AddUtilityTerm(201, 1.0);
                //alternative.AddUtilityTerm(202, numberChildren);
                //alternative.AddUtilityTerm(203, netIncomeNetCarOwnership);
                //alternative.AddUtilityTerm(204, person.IsMale.ToFlag());
                //alternative.AddUtilityTerm(205, (person.IsAdultFemale && numberAdults == 1).ToFlag());
                //alternative.AddUtilityTerm(206, (person.IsAdultFemale && numberAdults > 1).ToFlag());
                //alternative.AddUtilityTerm(207, person.Age);
                //alternative.AddUtilityTerm(208, Math.Pow(person.Age, 2.0));
                //non-worker/non-student models only
                //alternative.AddUtilityTerm(209, (person.Household.VehiclesAvailable >= 2).ToFlag());
                //alternative.AddUtilityTerm(210, (person.IsAdultMale && numberAdults == 1).ToFlag());
                //alternative.AddUtilityTerm(211, Math.Min(person.Household.ResidenceParcel.DistanceToLocalBus, 2.0));
                //alternative.AddUtilityTerm(212, Math.Min(5.0, person.Household.ResidenceParcel.DistanceToExpressBus));
                alternative.AddUtilityTerm(201, stefanUtility); // this composite replaces terms *1-*12 above
                                                                //Stefan impedance (try replacign these with logsums)
                alternative.AddUtilityTerm(213, Math.Min(person.Household.ResidenceParcel.DistanceToLocalBus, person.Household.ResidenceParcel.DistanceToExpressBus));
                alternative.AddUtilityTerm(214, (commuteDistance > 0 && commuteDistance < 3).ToFlag());
                alternative.AddUtilityTerm(215, (commuteDistance >= 7 && commuteDistance < 13).ToFlag());
                alternative.AddUtilityTerm(216, (commuteDistance >= 13).ToFlag());
                alternative.AddUtilityTerm(217, parkingCost);
                alternative.AddUtilityTerm(218, parkingSearchTime);
                //commute logsum difference variable (with and without transit pass)
                alternative.AddUtilityTerm(219, workTourLogsumDifference);
            }
            else if (model == 2 && person.Household.VehiclesAvailable == 0)
            {
                double beta301 = 4.74;
                double beta302 = 0.39;
                int    beta303 = 0;
                int    beta304 = 0;
                int    beta305 = 0;
                int    beta306 = 0;
                double beta307 = -3.95;
                double beta308 = 0.62;
                int    beta309 = 0;
                int    beta310 = 0;
                int    beta311 = 0;
                int    beta312 = 0;
                stefanUtility =
                    beta301 * 1.0 +
                    beta302 * numberChildren +
                    beta303 * netIncomeNetCarOwnership +
                    beta304 * person.IsMale.ToFlag() +
                    beta305 * (person.IsAdultFemale && numberAdults == 1).ToFlag() +
                    beta306 * (person.IsAdultFemale && numberAdults > 1).ToFlag() +
                    beta307 * person.Age +
                    beta308 * Math.Pow(person.Age, 2.0) +
                    beta309 * (person.Household.VehiclesAvailable >= 2).ToFlag() +
                    beta310 * (person.IsAdultMale && numberAdults == 1).ToFlag() +
                    beta311 * Math.Min(person.Household.ResidenceParcel.DistanceToLocalBus, 2.0) +
                    beta312 * Math.Min(5.0, person.Household.ResidenceParcel.DistanceToExpressBus) +
                    0.0;
                //Stefan utility
                //alternative.AddUtilityTerm(301, 1.0);
                //alternative.AddUtilityTerm(302, numberChildren);
                //alternative.AddUtilityTerm(303, netIncomeNetCarOwnership);
                //alternative.AddUtilityTerm(304, person.IsMale.ToFlag());
                //alternative.AddUtilityTerm(305, (person.IsAdultFemale && numberAdults == 1).ToFlag());
                //alternative.AddUtilityTerm(306, (person.IsAdultFemale && numberAdults > 1).ToFlag());
                //alternative.AddUtilityTerm(307, person.Age);
                //alternative.AddUtilityTerm(308, Math.Pow(person.Age, 2.0));
                ////non-worker/non-student models only
                //alternative.AddUtilityTerm(309, (person.Household.VehiclesAvailable >= 2).ToFlag());
                //alternative.AddUtilityTerm(310, (person.IsAdultMale && numberAdults == 1).ToFlag());
                //alternative.AddUtilityTerm(311, Math.Min(person.Household.ResidenceParcel.DistanceToLocalBus, 2.0));
                //alternative.AddUtilityTerm(312, Math.Min(5.0, person.Household.ResidenceParcel.DistanceToExpressBus));
                alternative.AddUtilityTerm(301, stefanUtility); // this composite replaces terms *1-*12 above
                                                                //Stefan impedance (try replacign these with logsums)
                alternative.AddUtilityTerm(313, Math.Min(person.Household.ResidenceParcel.DistanceToLocalBus, person.Household.ResidenceParcel.DistanceToExpressBus));
                alternative.AddUtilityTerm(314, (commuteDistance > 0 && commuteDistance < 3).ToFlag());
                alternative.AddUtilityTerm(315, (commuteDistance >= 7 && commuteDistance < 13).ToFlag());
                alternative.AddUtilityTerm(316, (commuteDistance >= 13).ToFlag());
                alternative.AddUtilityTerm(317, parkingCost);
                alternative.AddUtilityTerm(318, parkingSearchTime);
                //commute logsum difference variable (with and without transit pass)
                alternative.AddUtilityTerm(319, schoolTourLogsumDifference);
            }
            else if (model == 2 && person.Household.VehiclesAvailable >= 1)
            {
                double beta401 = 3.75;
                int    beta402 = 0;
                int    beta403 = 0;
                int    beta404 = 0;
                int    beta405 = 0;
                int    beta406 = 0;
                double beta407 = 2.81;
                double beta408 = 0.33;
                int    beta409 = 0;
                int    beta410 = 0;
                int    beta411 = 0;
                int    beta412 = 0;
                stefanUtility =
                    beta401 * 1.0 +
                    beta402 * numberChildren +
                    beta403 * netIncomeNetCarOwnership +
                    beta404 * person.IsMale.ToFlag() +
                    beta405 * (person.IsAdultFemale && numberAdults == 1).ToFlag() +
                    beta406 * (person.IsAdultFemale && numberAdults > 1).ToFlag() +
                    beta407 * person.Age +
                    beta408 * Math.Pow(person.Age, 2.0) +
                    beta409 * (person.Household.VehiclesAvailable >= 2).ToFlag() +
                    beta410 * (person.IsAdultMale && numberAdults == 1).ToFlag() +
                    beta411 * Math.Min(person.Household.ResidenceParcel.DistanceToLocalBus, 2.0) +
                    beta412 * Math.Min(5.0, person.Household.ResidenceParcel.DistanceToExpressBus) +
                    0.0;
                //Stefan utility
                //alternative.AddUtilityTerm(401, 1.0);
                //alternative.AddUtilityTerm(402, numberChildren);
                //alternative.AddUtilityTerm(403, netIncomeNetCarOwnership);
                //alternative.AddUtilityTerm(404, person.IsMale.ToFlag());
                //alternative.AddUtilityTerm(405, (person.IsAdultFemale && numberAdults == 1).ToFlag());
                //alternative.AddUtilityTerm(406, (person.IsAdultFemale && numberAdults > 1).ToFlag());
                //alternative.AddUtilityTerm(407, person.Age);
                //alternative.AddUtilityTerm(408, Math.Pow(person.Age, 2.0));
                ////non-worker/non-student models only
                //alternative.AddUtilityTerm(409, (person.Household.VehiclesAvailable >= 2).ToFlag());
                //alternative.AddUtilityTerm(410, (person.IsAdultMale && numberAdults == 1).ToFlag());
                //alternative.AddUtilityTerm(411, Math.Min(person.Household.ResidenceParcel.DistanceToLocalBus, 2.0));
                //alternative.AddUtilityTerm(412, Math.Min(5.0, person.Household.ResidenceParcel.DistanceToExpressBus));
                alternative.AddUtilityTerm(401, stefanUtility); // this composite replaces terms *1-*12 above
                                                                //Stefan impedance (try replacign these with logsums)
                alternative.AddUtilityTerm(413, Math.Min(person.Household.ResidenceParcel.DistanceToLocalBus, person.Household.ResidenceParcel.DistanceToExpressBus));
                alternative.AddUtilityTerm(414, (commuteDistance > 0 && commuteDistance < 3).ToFlag());
                alternative.AddUtilityTerm(415, (commuteDistance >= 7 && commuteDistance < 13).ToFlag());
                alternative.AddUtilityTerm(416, (commuteDistance >= 13).ToFlag());
                alternative.AddUtilityTerm(417, parkingCost);
                alternative.AddUtilityTerm(418, parkingSearchTime);
                //commute logsum difference variable (with and without transit pass)
                alternative.AddUtilityTerm(419, schoolTourLogsumDifference);
            }
            else if (model == 3 && person.Household.VehiclesAvailable == 0)
            {
                double beta501 = 0.05;
                int    beta502 = 0;
                int    beta503 = 0;
                int    beta504 = 0;
                double beta505 = 0.56;
                double beta506 = 0.41;
                int    beta507 = 0;
                int    beta508 = 0;
                int    beta509 = 0;
                int    beta510 = 0;
                double beta511 = -0.45;
                int    beta512 = 0;
                stefanUtility =
                    beta501 * 1.0 +
                    beta502 * numberChildren +
                    beta503 * netIncomeNetCarOwnership +
                    beta504 * person.IsMale.ToFlag() +
                    beta505 * (person.IsAdultFemale && numberAdults == 1).ToFlag() +
                    beta506 * (person.IsAdultFemale && numberAdults > 1).ToFlag() +
                    beta507 * person.Age +
                    beta508 * Math.Pow(person.Age, 2.0) +
                    beta509 * (person.Household.VehiclesAvailable >= 2).ToFlag() +
                    beta510 * (person.IsAdultMale && numberAdults == 1).ToFlag() +
                    beta511 * Math.Min(person.Household.ResidenceParcel.DistanceToLocalBus, 2.0) +
                    beta512 * Math.Min(5.0, person.Household.ResidenceParcel.DistanceToExpressBus) +
                    0.0;
                //Stefan utility
                //alternative.AddUtilityTerm(501, 1.0);
                //alternative.AddUtilityTerm(502, numberChildren);
                //alternative.AddUtilityTerm(503, netIncomeNetCarOwnership);
                //alternative.AddUtilityTerm(504, person.IsMale.ToFlag());
                //alternative.AddUtilityTerm(505, (person.IsAdultFemale && numberAdults == 1).ToFlag());
                //alternative.AddUtilityTerm(506, (person.IsAdultFemale && numberAdults > 1).ToFlag());
                //alternative.AddUtilityTerm(507, person.Age);
                //alternative.AddUtilityTerm(508, Math.Pow(person.Age, 2.0));
                ////non-worker/non-student models only
                //alternative.AddUtilityTerm(509, (person.Household.VehiclesAvailable >= 2).ToFlag());
                //alternative.AddUtilityTerm(510, (person.IsAdultMale && numberAdults == 1).ToFlag());
                //alternative.AddUtilityTerm(511, Math.Min(person.Household.ResidenceParcel.DistanceToLocalBus, 2.0));
                //alternative.AddUtilityTerm(512, Math.Min(5.0, person.Household.ResidenceParcel.DistanceToExpressBus));
                alternative.AddUtilityTerm(501, stefanUtility); // this composite replaces terms *1-*12 above
            }
            else //(model == 3 && person.Household.VehiclesAvailable >= 1)
            {
                double beta601 = -1.7;
                int    beta602 = 0;
                double beta603 = 0.47;
                int    beta604 = 0;
                double beta605 = 0.63;
                double beta606 = 0.46;
                int    beta607 = 0;
                int    beta608 = 0;
                double beta609 = -0.32;
                double beta610 = 0.35;
                double beta611 = -0.37;
                double beta612 = -0.09;
                stefanUtility =
                    beta601 * 1.0 +
                    beta602 * numberChildren +
                    beta603 * netIncomeNetCarOwnership +
                    beta604 * person.IsMale.ToFlag() +
                    beta605 * (person.IsAdultFemale && numberAdults == 1).ToFlag() +
                    beta606 * (person.IsAdultFemale && numberAdults > 1).ToFlag() +
                    beta607 * person.Age +
                    beta608 * Math.Pow(person.Age, 2.0) +
                    beta609 * (person.Household.VehiclesAvailable >= 2).ToFlag() +
                    beta610 * (person.IsAdultMale && numberAdults == 1).ToFlag() +
                    beta611 * Math.Min(person.Household.ResidenceParcel.DistanceToLocalBus, 2.0) +
                    beta612 * Math.Min(5.0, person.Household.ResidenceParcel.DistanceToExpressBus) +
                    0.0;
                //Stefan utility
                //alternative.AddUtilityTerm(601, 1.0);
                //alternative.AddUtilityTerm(602, numberChildren);
                //alternative.AddUtilityTerm(603, netIncomeNetCarOwnership);
                //alternative.AddUtilityTerm(604, person.IsMale.ToFlag());
                //alternative.AddUtilityTerm(605, (person.IsAdultFemale && numberAdults == 1).ToFlag());
                //alternative.AddUtilityTerm(606, (person.IsAdultFemale && numberAdults > 1).ToFlag());
                //alternative.AddUtilityTerm(607, person.Age);
                //alternative.AddUtilityTerm(608, Math.Pow(person.Age, 2.0));
                //non-worker/non-student models only
                //alternative.AddUtilityTerm(609, (person.Household.VehiclesAvailable >= 2).ToFlag());
                //alternative.AddUtilityTerm(610, (person.IsAdultMale && numberAdults == 1).ToFlag());
                //alternative.AddUtilityTerm(611, Math.Min(person.Household.ResidenceParcel.DistanceToLocalBus, 2.0));
                //alternative.AddUtilityTerm(612, Math.Min(5.0, person.Household.ResidenceParcel.DistanceToExpressBus));
                alternative.AddUtilityTerm(601, stefanUtility); // this composite replaces terms *1-*12 above
            }

            //alternative.AddUtilityTerm(2, person.IsPartTimeWorker.ToFlag());
            //alternative.AddUtilityTerm(3, (person.IsWorker && person.IsNotFullOrPartTimeWorker).ToFlag());
            //alternative.AddUtilityTerm(4, person.IsUniversityStudent.ToFlag());
            //alternative.AddUtilityTerm(5, person.IsRetiredAdult.ToFlag());
            //alternative.AddUtilityTerm(6, person.IsNonworkingAdult.ToFlag());
            //alternative.AddUtilityTerm(7, person.IsDrivingAgeStudent.ToFlag());
            //alternative.AddUtilityTerm(8, person.IsChildUnder16.ToFlag());
            //alternative.AddUtilityTerm(9, Math.Log(Math.Max(1, person.Household.Income)));
            //alternative.AddUtilityTerm(10, person.Household.HasMissingIncome.ToFlag());
            //alternative.AddUtilityTerm(11, workParcelMissing.ToFlag());
            //alternative.AddUtilityTerm(12, schoolParcelMissing.ToFlag());
            //alternative.AddUtilityTerm(13, (homeTranDist < 90.0) ? homeTranDist1 : 0);
            //alternative.AddUtilityTerm(14, (homeTranDist < 90.0) ? homeTranDist2 : 0);
            //alternative.AddUtilityTerm(15, (homeTranDist > 90.0) ? 1 : 0);
            //			//alternative.AddUtility(16, (workTranDist < 90.0) ? workTranDist : 0);
            //			//alternative.AddUtility(17, (workTranDist < 90.0) ? workTranDist2 : 0);
            //			//alternative.AddUtility(18, (workTranDist > 90.0) ? 1 : 0);
            //			//alternative.AddUtility(19, (schoolTranDist < 90.0) ? schoolTranDist : 0);
            //			//alternative.AddUtility(20, (schoolTranDist > 90.0) ? 1 : 0);
            //			//alternative.AddUtility(21, (!workParcelMissing && workGenTimeWithPass > -90 ) ? workGenTimeWithPass : 0);
            //alternative.AddUtilityTerm(22, (!workParcelMissing && workGenTimeWithPass <= -90) ? 1 : 0);
            //alternative.AddUtilityTerm(23, (!workParcelMissing && workGenTimeWithPass > -90 && workGenTimeNoPass > -90) ? workGenTimeNoPass - workGenTimeWithPass : 0);
            //			//alternative.AddUtility(24, (!schoolParcelMissing && schoolGenTimeWithPass > -90 ) ? schoolGenTimeWithPass : 0);
            //alternative.AddUtilityTerm(25, (!schoolParcelMissing && schoolGenTimeWithPass <= -90) ? 1 : 0);
            //alternative.AddUtilityTerm(26, homeAggregateLogsumNoCar * (person.IsFullOrPartTimeWorker || person.IsUniversityStudent).ToFlag());
            //alternative.AddUtilityTerm(27, homeAggregateLogsumNoCar * (person.IsDrivingAgeStudent || person.IsChildUnder16).ToFlag());
            //alternative.AddUtilityTerm(28, homeAggregateLogsumNoCar * (person.IsNonworkingAdult).ToFlag());
            //alternative.AddUtilityTerm(29, homeAggregateLogsumNoCar * (person.IsRetiredAdult).ToFlag());
            //alternative.AddUtilityTerm(30, workParcelMissing ? 0 : workAggregateLogsumNoCar);
            //alternative.AddUtilityTerm(31, schoolParcelMissing ? 0 : schoolAggregateLogsumNoCar);
            //alternative.AddUtilityTerm(32, transitPassCostChange);
        }
        private void RunModel(ChoiceProbabilityCalculator choiceProbabilityCalculator, IPersonDayWrapper personDay, IHouseholdDayWrapper householdDay, int nCallsForTour, int[] simulatedMandatoryTours, int choice = Constants.DEFAULT_VALUE)
        {
            var household = personDay.Household;

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


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

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

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

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


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

                noUsualWorkZone = 0;
            }


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


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

            bool schoolAvailableFlag = true;

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

            // NONE_OR_HOME

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

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


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

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

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

            // array associating alternative with the participation of each HH person in the joint half tour
            //  also identifies minimum housheold size and number of participants for each alternative
            //[alt,p1,p2,p3,p4,p5,MinHHSize,numPart]
            int[][] altParticipants = new int[32][];
            altParticipants[0]  = new int[] { 0, 0, 0, 0, 0, 0, 2, 0 };
            altParticipants[1]  = new int[] { 1, 1, 0, 0, 0, 0, 2, 1 };
            altParticipants[2]  = new int[] { 2, 0, 1, 0, 0, 0, 2, 1 };
            altParticipants[3]  = new int[] { 3, 1, 1, 0, 0, 0, 2, 2 };
            altParticipants[4]  = new int[] { 4, 0, 0, 1, 0, 0, 3, 1 };
            altParticipants[5]  = new int[] { 5, 1, 0, 1, 0, 0, 3, 2 };
            altParticipants[6]  = new int[] { 6, 0, 1, 1, 0, 0, 3, 2 };
            altParticipants[7]  = new int[] { 7, 1, 1, 1, 0, 0, 3, 3 };
            altParticipants[8]  = new int[] { 8, 0, 0, 0, 1, 0, 4, 1 };
            altParticipants[9]  = new int[] { 9, 1, 0, 0, 1, 0, 4, 2 };
            altParticipants[10] = new int[] { 10, 0, 1, 0, 1, 0, 4, 2 };
            altParticipants[11] = new int[] { 11, 1, 1, 0, 1, 0, 4, 3 };
            altParticipants[12] = new int[] { 12, 0, 0, 1, 1, 0, 4, 2 };
            altParticipants[13] = new int[] { 13, 1, 0, 1, 1, 0, 4, 3 };
            altParticipants[14] = new int[] { 14, 0, 1, 1, 1, 0, 4, 3 };
            altParticipants[15] = new int[] { 15, 1, 1, 1, 1, 0, 4, 4 };
            altParticipants[16] = new int[] { 16, 0, 0, 0, 0, 1, 5, 1 };
            altParticipants[17] = new int[] { 17, 1, 0, 0, 0, 1, 5, 2 };
            altParticipants[18] = new int[] { 18, 0, 1, 0, 0, 1, 5, 2 };
            altParticipants[19] = new int[] { 19, 1, 1, 0, 0, 1, 5, 3 };
            altParticipants[20] = new int[] { 20, 0, 0, 1, 0, 1, 5, 2 };
            altParticipants[21] = new int[] { 21, 1, 0, 1, 0, 1, 5, 3 };
            altParticipants[22] = new int[] { 22, 0, 1, 1, 0, 1, 5, 3 };
            altParticipants[23] = new int[] { 23, 1, 1, 1, 0, 1, 5, 4 };
            altParticipants[24] = new int[] { 24, 0, 0, 0, 1, 1, 5, 2 };
            altParticipants[25] = new int[] { 25, 1, 0, 0, 1, 1, 5, 3 };
            altParticipants[26] = new int[] { 26, 0, 1, 0, 1, 1, 5, 3 };
            altParticipants[27] = new int[] { 27, 1, 1, 0, 1, 1, 5, 4 };
            altParticipants[28] = new int[] { 28, 0, 0, 1, 1, 1, 5, 3 };
            altParticipants[29] = new int[] { 29, 1, 0, 1, 1, 1, 5, 4 };
            altParticipants[30] = new int[] { 30, 0, 1, 1, 1, 1, 5, 4 };
            altParticipants[31] = new int[] { 31, 1, 1, 1, 1, 1, 5, 5 };

            householdDay.ResetRandom(925 + jHTSimulated);

            IEnumerable <PersonDayWrapper> orderedPersonDays = householdDay.PersonDays.OrderBy(p => p.GetJointHalfTourParticipationPriority()).ToList().Cast <PersonDayWrapper>();
            int choice = 0;

            if (Global.Configuration.IsInEstimationMode)
            {
                int i = 0;
                foreach (PersonDayWrapper personDay in orderedPersonDays)
                {
                    i++;
                    if (i <= 5)
                    {
                        choice = choice + (jHTParticipation[jHTSimulated, personDay.Person.Sequence] == true ? 1 : 0) * (int)Math.Pow(2, i - 1);
                    }
                }
                if (Global.Configuration.EstimationModel != CHOICE_MODEL_NAME)
                {
                    return(altParticipants[choice]);
                }
            }

            ChoiceProbabilityCalculator choiceProbabilityCalculator = _helpers[ParallelUtility.threadLocalAssignedIndex.Value].GetChoiceProbabilityCalculator(((householdDay.Household.Id * 10 + householdDay.Day) * 397) ^ jHTSimulated);

            if (_helpers[ParallelUtility.threadLocalAssignedIndex.Value].ModelIsInEstimationMode)
            {
                RunModel(choiceProbabilityCalculator, householdDay, jHTSimulated, genChoice, jHTAvailable, fHTAvailable, altParticipants, choice);

                choiceProbabilityCalculator.WriteObservation();

                return(altParticipants[choice]);
            }
            else if (Global.Configuration.TestEstimationModelInApplicationMode)
            {
                Global.Configuration.IsInEstimationMode = false;

                RunModel(choiceProbabilityCalculator, householdDay, jHTSimulated, genChoice, jHTAvailable, fHTAvailable, altParticipants);

                ChoiceProbabilityCalculator.Alternative chosenAlternative = choiceProbabilityCalculator.SimulateChoice(householdDay.Household.RandomUtility, householdDay.Household.Id, choice);

                Global.Configuration.IsInEstimationMode = true;

                return(altParticipants[choice]);
            }
            else
            {
                RunModel(choiceProbabilityCalculator, householdDay, jHTSimulated, genChoice, jHTAvailable, fHTAvailable, altParticipants);

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

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

                choice = (int)chosenAlternative.Choice;

                return(altParticipants[choice]);
            }
        }
        private void RunModel(ChoiceProbabilityCalculator choiceProbabilityCalculator, HouseholdDayWrapper householdDay, int jHTSimulated, int genChoice, bool[,] jHTAvailable, bool[] fHTAvailable, int[][] altParticipants, int choice = Constants.DEFAULT_VALUE)
        {
            IEnumerable <PersonDayWrapper> orderedPersonDays = householdDay.PersonDays.OrderBy(p => p.GetJointHalfTourParticipationPriority()).ToList().Cast <PersonDayWrapper>();

            PersonDayWrapper pPersonDay = null;

            // set household characteristics here that don't depend on person characteristics

            int hhsize = householdDay.Household.Size;

            int hhinc1 = householdDay.Household.Income <= 300000 ? 1 : 0;
            int hhinc2 = (householdDay.Household.Income > 300000 && householdDay.Household.Income <= 600000) ? 1 : 0;
            int hhinc3 = (householdDay.Household.Income > 600000 && householdDay.Household.Income <= 900000) ? 1 : 0;
            //int hhinc4 = (householdDay.Household.Income > 900000 && householdDay.Household.Income <= 1200000) ? 1 : 0;
            int hhinc4 = (householdDay.Household.Income > 900000) ? 1 : 0;

            IParcelWrapper[] pUsualLocation = new IParcelWrapper[6];
            int[]            pPatternType   = new int[6];
            int[]            pConstant      = new int[6];

            int[] pType9 = new int[6];
            int[] pType8 = new int[6];
            int[] pType7 = new int[6];
            int[] pType6 = new int[6];
            int[] pType5 = new int[6];
            int[] pType4 = new int[6];
            int[] pType3 = new int[6];
            int[] pType2 = new int[6];
            int[] pType1 = new int[6];
            int[] pAdult = new int[6];
            int[] pAdultWithChildrenUnder16 = new int[6];
            int[] pAdultFemale       = new int[6];
            int[] pAdultNonMandatory = new int[6];
            int[] pType7AgeUnder12   = new int[6];
            int[] pType7Age12Plus    = new int[6];
            int[] pAgeUnder12        = new int[6];

            int[] pType8Mandatory    = new int[6];
            int[] pType8NonMandatory = new int[6];

            int[] pType7Mandatory    = new int[6];
            int[] pType7NonMandatory = new int[6];

            int[] pAgeUnder16        = new int[6];
            int[] pYouthMandatory    = new int[6];
            int[] pYouthNonMandatory = new int[6];
            int[] pYouth             = new int[6];
            int[] pAdultMandatory    = new int[6];
            int[] pMandatory         = new int[6];
            int[] pNonMandatory      = new int[6];

            bool[] pHasMandatoryTourToUsualLocation = new bool[6];
            bool[] pIsDrivingAge = new bool[6];

            int count = 0;

            foreach (PersonDayWrapper personDay in orderedPersonDays)
            {
                count++;
                if (count <= 5)
                {
                    if (count == 1)
                    {
                        pPersonDay = personDay;
                    }

                    // set characteristics here that depend on person characteristics
                    if (personDay.Person.IsFullOrPartTimeWorker)
                    {
                        pUsualLocation[count] = personDay.Person.UsualWorkParcel;
                    }
                    else if (personDay.Person.IsStudent)
                    {
                        pUsualLocation[count] = personDay.Person.UsualSchoolParcel;
                    }
                    else if (personDay.Person.IsWorker && personDay.Person.IsNotFullOrPartTimeWorker)
                    {
                        pUsualLocation[count] = personDay.Person.UsualWorkParcel;
                    }
                    else
                    {
                        pUsualLocation[count] = personDay.Household.ResidenceParcel;
                    }

                    pPatternType[count] = personDay.PatternType;
                    pConstant[count]    = 1;

                    pType9[count] = personDay.Person.IsChildUnder16.ToFlag(); // not one og Type 1 to 8

                    pType8[count] = personDay.Person.IsChildUnder5.ToFlag();  // All ACTUM TU persons are one of Type 1 to 8
                    pType7[count] = personDay.Person.IsChildAge5Through15.ToFlag();
                    pType6[count] = personDay.Person.IsDrivingAgeStudent.ToFlag();
                    pType5[count] = personDay.Person.IsUniversityStudent.ToFlag();
                    pType4[count] = personDay.Person.IsNonworkingAdult.ToFlag();
                    pType3[count] = personDay.Person.IsRetiredAdult.ToFlag();
                    pType2[count] = personDay.Person.IsPartTimeWorker.ToFlag();
                    pType1[count] = personDay.Person.IsFulltimeWorker.ToFlag();
                    pAdult[count] = personDay.Person.IsAdult.ToFlag();
                    pAdultWithChildrenUnder16[count] = (personDay.Person.IsAdult && personDay.Household.HasChildrenUnder16).ToFlag(); // THIS person is adult and HH has child. under 16
                    pAdultFemale[count]       = personDay.Person.IsAdultFemale.ToFlag();
                    pAdultNonMandatory[count] = (personDay.Person.IsAdult && personDay.PatternType == Global.Settings.PatternTypes.Optional).ToFlag();
                    pType7AgeUnder12[count]   = (personDay.Person.IsChildAge5Through15 && personDay.Person.Age < 12).ToFlag(); // THIS person is both 5-15 AND below 12
                    pType7Age12Plus[count]    = (personDay.Person.IsChildAge5Through15 && personDay.Person.Age >= 12).ToFlag();
                    pAgeUnder12[count]        = (personDay.Person.Age < 12).ToFlag();
                    pAgeUnder16[count]        = (personDay.Person.Age < 16).ToFlag();

                    pType8Mandatory[count]    = (personDay.Person.IsChildUnder5 && personDay.PatternType == Global.Settings.PatternTypes.Mandatory).ToFlag();
                    pType8NonMandatory[count] = (personDay.Person.IsChildUnder5 && personDay.PatternType == Global.Settings.PatternTypes.Optional).ToFlag();

                    pType7Mandatory[count]    = (personDay.Person.IsChildAge5Through15 && personDay.PatternType == Global.Settings.PatternTypes.Mandatory).ToFlag();
                    pType7NonMandatory[count] = (personDay.Person.IsChildAge5Through15 && personDay.PatternType == Global.Settings.PatternTypes.Optional).ToFlag();

                    pYouthMandatory[count]    = (!personDay.Person.IsChildUnder5 && !personDay.Person.IsAdult && personDay.PatternType == Global.Settings.PatternTypes.Mandatory).ToFlag();
                    pYouthNonMandatory[count] = (!personDay.Person.IsChildUnder5 && !personDay.Person.IsAdult && personDay.PatternType == Global.Settings.PatternTypes.Optional).ToFlag();
                    pYouth[count]             = (!personDay.Person.IsChildUnder5 && !personDay.Person.IsAdult).ToFlag();

                    pAdultMandatory[count] = (personDay.Person.IsAdult && personDay.PatternType == Global.Settings.PatternTypes.Mandatory).ToFlag();

                    pMandatory[count]    = (personDay.PatternType == Global.Settings.PatternTypes.Mandatory).ToFlag();
                    pNonMandatory[count] = (personDay.PatternType == Global.Settings.PatternTypes.Optional).ToFlag();

                    pHasMandatoryTourToUsualLocation[count] = personDay.HasMandatoryTourToUsualLocation;
                    pIsDrivingAge[count] = personDay.Person.IsDrivingAge;
                }
            }

            int componentIndex = 0;

            //Create person utility components
            int[] componentPerson = new int[6];
            for (int p = 1; p <= 5; p++)
            {
                // create component for basic person-purposes
                componentIndex++;
                componentPerson[p] = componentIndex;
                choiceProbabilityCalculator.CreateUtilityComponent(componentPerson[p]);
                // these are dummies compared to base one, i.e. Type 5+6 in one.
                // OBS! - We apply "Adult Mandatory" as the base
                //choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(1, pAdultMandatory[p]); // impact of adult with mandatory travel
                choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(2, pAdultNonMandatory[p]); // impact of adult with non-mandatory travel

                choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(3, pType8Mandatory[p]);    // impact of child under 5 with mandatory travel
                                                                                                                              //GV: not significant, 14. june 2016
                                                                                                                              //choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(4, pType8NonMandatory[p]); // impact of child under 5 with non-mandatory travel

                //choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(04, pYouthMandatory[p]); // impact of youth with mandatory travel
                //choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(05, pYouthNonMandatory[p]); // impact of youth with non-mandatory travel
                choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(5, pType7Mandatory[p]); // impact of Child5-16 with mandatory travel

                //GV: not significant, 14. june 2016
                //choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(6, pType7NonMandatory[p]); // impact of Child5-16 with non-mandatory travel

                choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(7, pAdultFemale[p]); //female
            }

            //create two-way match interaction utility components
            int[,] componentMatch   = new int[6, 6];
            int[,] iMatchAgeUnder12 = new int[6, 6];
            int[,] iMatchAgeUnder16 = new int[6, 6];
            int[,] iMatchAgeUnder5  = new int[6, 6];
            int[,] iMatchAge5to16   = new int[6, 6];

            int[,] iMatchAdult = new int[6, 6];
            int[,] iMatchAdultWithChildrenUnder16 = new int[6, 6];
            int[,] iMatchAdultWithChildrenUnder5  = new int[6, 6];

            int[,] iMatchAdultMandatory    = new int[6, 6];
            int[,] iMatchAdultNonMandatory = new int[6, 6];

            int[,] iMatchMandatory    = new int[6, 6];
            int[,] iMatchNonMandatory = new int[6, 6];

            int[,] iMatchAdultMandatoryAndAdultMandatory       = new int[6, 6];
            int[,] iMatchAdultNonMandatoryAndAdultNonMandatory = new int[6, 6];

            for (int t2 = 1; t2 <= 5; t2++)
            {
                for (int t1 = 1; t1 < t2; t1++)
                {
                    // iMatch joints only persons of the same type
                    // lets the base alt, be adult*adult

                    iMatchAgeUnder12[t1, t2] = pAgeUnder12[t1] * pAgeUnder12[t2];                      // children under 12
                    iMatchAgeUnder16[t1, t2] = pAgeUnder16[t1] * pAgeUnder16[t2];                      // children under 16

                    iMatchAgeUnder5[t1, t2] = pType8[t1] * pType8[t2];                                 // children under 5
                    iMatchAge5to16[t1, t2]  = pType7[t1] * pType7[t2];                                 // children 5 to 16

                    iMatchAdult[t1, t2] = pAdult[t1] * pAdult[t2];                                     // two adults (very important but difficult to understand)

                    iMatchAdultMandatory[t1, t2]    = pAdultMandatory[t1] * pAdultMandatory[t2];       // two adults with mandatory travel
                    iMatchAdultNonMandatory[t1, t2] = pAdultNonMandatory[t1] * pAdultNonMandatory[t2]; // two adults with non-mandatory travel

                    iMatchMandatory[t1, t2]    = pMandatory[t1] * pMandatory[t2];                      //those with mandatory
                    iMatchNonMandatory[t1, t2] = pNonMandatory[t1] * pNonMandatory[t2];                //those tith non-mandatory

                    //iMatchAdultWithChildrenUnder16[t1, t2] = pAdultWithChildrenUnder16[t1] * pAdultWithChildrenUnder16[t2];

                    iMatchAdultWithChildrenUnder16[t1, t2] = pAdult[t1] * pType7[t2];                                      //adult plus child 5-16
                    iMatchAdultWithChildrenUnder5[t1, t2]  = pAdult[t1] * pType8[t2];                                      //adult plus child5

                    iMatchAdultMandatoryAndAdultMandatory[t1, t2]       = pAdultMandatory[t1] * pAdultMandatory[t2];       //2 adults with Mandatory
                    iMatchAdultNonMandatoryAndAdultNonMandatory[t1, t2] = pAdultNonMandatory[t1] * pAdultNonMandatory[t2]; //2 adults with Mandatory


                    //create and populate components
                    // OBS! - We apply "Adult * Adult" as the base
                    componentIndex++;
                    componentMatch[t1, t2] = componentIndex;
                    choiceProbabilityCalculator.CreateUtilityComponent(componentMatch[t1, t2]);
                    choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(21, iMatchAgeUnder5[t1, t2]);

                    //GV: 14. jine 2016, not sign.
                    //choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(22, iMatchAge5to16[t1, t2]);

                    //choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(23, iMatchAdultMandatoryAndAdultMandatory[t1, t2]);
                    //choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(24, iMatchAdultNonMandatoryAndAdultNonMandatory[t1, t2]);

                    //choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(23, iMatchAdult[t1, t2]);
                    //choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(24, iMatchAdultMandatory[t1, t2]);
                    //choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(25, iMatchAdultNonMandatory[t1, t2]);

                    // commented out 22nd, but they work well
                    //choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(26, iMatchMandatory[t1, t2]);
                    //choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(27, iMatchNonMandatory[t1, t2]);
                }
            }

            //create two-way cross interaction utility components

            int[,] componentCross = new int[6, 6];
            int[,] iCrossAgeUnderTwelveAndAdult             = new int[6, 6];
            int[,] iCrossAgeUnderTwelveAndAdultNonMandatory = new int[6, 6];
            int[,] iCrossAdultWithChildUnder5 = new int[6, 6];
            int[,] iCrossAdultWithChild5to16  = new int[6, 6];

            int[,] iCrossAdultFemaleWithChildUnder5 = new int[6, 6];
            int[,] iCrossAdultFemaleWithChild5to16  = new int[6, 6];

            int[,] iCrossAdultMandatoryAndAdultNonMandatory    = new int[6, 6];
            int[,] iCrossAdultMandatoryAndAdultMandatory       = new int[6, 6];
            int[,] iCrossAdultNonMandatoryAndAdultNonMandatory = new int[6, 6];

            int[,] iCrossYouthAndChildUnder5      = new int[6, 6];
            int[,] iCrossChild5to16AndChildUnder5 = new int[6, 6];

            for (int t2 = 1; t2 <= 5; t2++)
            {
                for (int t1 = 1; t1 <= 5; t1++)
                {
                    if (!(t1 == t2))
                    {
                        //populate cross variables
                        // again, one is base, all others are dummies

                        iCrossAdultWithChildUnder5[t1, t2] = pAdult[t1] * pType8[t2];             //adult plus child5
                        iCrossAdultWithChild5to16[t1, t2]  = pAdult[t1] * pType7[t2];             //adult plus child 5-16

                        iCrossAdultFemaleWithChildUnder5[t1, t2] = pAdultFemale[t1] * pType8[t2]; //adult mom plus child5
                        iCrossAdultFemaleWithChild5to16[t1, t2]  = pAdult[t1] * pType7[t2];       //adult mom plus child 5-16


                        iCrossAgeUnderTwelveAndAdult[t1, t2]             = pAgeUnder12[t1] * pAdult[t2];
                        iCrossAgeUnderTwelveAndAdultNonMandatory[t1, t2] = pAgeUnder12[t1] * pAdultNonMandatory[t2];

                        iCrossAdultMandatoryAndAdultNonMandatory[t1, t2]    = pAdultMandatory[t1] * pAdultNonMandatory[t2];
                        iCrossAdultMandatoryAndAdultMandatory[t1, t2]       = pAdultMandatory[t1] * pAdultMandatory[t2];
                        iCrossAdultNonMandatoryAndAdultNonMandatory[t1, t2] = pAdultNonMandatory[t1] * pAdultNonMandatory[t2];

                        iCrossYouthAndChildUnder5[t1, t2]      = pYouth[t1] * pType8[t2];
                        iCrossChild5to16AndChildUnder5[t1, t2] = pType7[t1] * pType8[t2];

                        //create and populate cross components
                        // OBS! - We apply "Adult Mandatory * Adult Non-mandatory" as the base
                        componentIndex++;
                        componentCross[t1, t2] = componentIndex;
                        choiceProbabilityCalculator.CreateUtilityComponent(componentCross[t1, t2]);

                        choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(41, iCrossAdultWithChildUnder5[t1, t2]);
                        choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(42, iCrossAdultWithChild5to16[t1, t2]);

                        //choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(43, iCrossAdultMandatoryAndAdultNonMandatory[t1, t2]);

                        //GV: 14. june 2016, not sign.
                        //choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(46, iCrossAdultFemaleWithChildUnder5[t1, t2]);

                        //choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(47, iCrossYouthAndChildUnder5[t1, t2]);
                        choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(47, iCrossChild5to16AndChildUnder5[t1, t2]);

                        //choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(45, iCrossAdultFemaleWithChild5to16[t1, t2]);

                        //choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(41, iCrossAgeUnderTwelveAndAdult[t1, t2]);
                        //choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(42, iCrossAgeUnderTwelveAndAdultNonMandatory[t1, t2]);
                    }
                }
            }

            //Generate utility funtions for the alternatives
            bool[] available = new bool[32];
            bool[] chosen    = new bool[32];

            bool[] threeParticipants    = new bool[32];
            bool[] fourPlusParticipants = new bool[32];

            for (int alt = 0; alt < 32; alt++)
            {
                available[alt] = false;
                chosen[alt]    = false;
                // set availability based on household size
                if (hhsize >= altParticipants[alt][6])
                {
                    available[alt] = true;
                }
                // restrict availability based on person unavailability
                for (int i = 1; i <= 5; i++)
                {
                    if (altParticipants[alt][i] == 1 && (jHTAvailable[genChoice - 1, i] == false || fHTAvailable[i] == false))
                    {
                        available[alt] = false;
                    }
                }
                // restrict availability to cases where all non-adult participants have same usual location
                // first determine first non-adult's usual location
                IParcelWrapper sameUsualLocation = householdDay.Household.ResidenceParcel;
                for (int i = 1; i <= 5; i++)
                {
                    if (altParticipants[alt][i] == 1 && pPatternType[i] == 1 && pUsualLocation[i] != null && pUsualLocation[i].Id > 0 && !(pAdult[i] == 1))
                    {
                        sameUsualLocation = pUsualLocation[i];
                        break;
                    }
                }

                // then make alt unavailable if any M-Usual participant has a different usualLocation
                for (int i = 1; i <= 5; i++)
                {
                    if (altParticipants[alt][i] == 1 && pHasMandatoryTourToUsualLocation[i] && !(pUsualLocation[i] == sameUsualLocation) && !(pAdult[i] == 1))
                    {
                        available[alt] = false;
                        break;
                    }
                }

                // restrict availability of alts that include less than 2 participants
                if (altParticipants[alt][7] < 2)
                {
                    available[alt] = false;
                }

                // restrict availability if 2+ participants lack tour to usual location
                int numberLackMandatoryTourToUsualLocation = 0;
                for (int i = 1; i <= 5; i++)
                {
                    if (altParticipants[alt][i] == 1 && !pHasMandatoryTourToUsualLocation[i])
                    {
                        numberLackMandatoryTourToUsualLocation++;
                    }
                }
                if (numberLackMandatoryTourToUsualLocation > 1)
                {
                    available[alt] = false;
                }

                // require at least one driving age (as chauffeur) //GV:out july 2013
                //int numberDrivingAge = 0;
                //for (int i = 1; i <= 5; i++) {
                //	if (altParticipants[alt][i] == 1 && pIsDrivingAge[i]) {
                //		numberDrivingAge++;
                //	}
                //}
                //if (numberDrivingAge == 0) {
                //	available[alt] = false;
                //}


                double tourLogsum;
                int    destinationArrivalTime   = ChoiceModelUtility.GetDestinationArrivalTime(Global.Settings.Models.WorkTourModeModel);
                int    destinationDepartureTime = ChoiceModelUtility.GetDestinationDepartureTime(Global.Settings.Models.WorkTourModeModel);
                //var nestedAlternative = ActumWorkTourModeModel.RunNested(pPersonDay, pPersonDay.Household.ResidenceParcel, sameUsualLocation, destinationArrivalTime, destinationDepartureTime, pPersonDay.Household.VehiclesAvailable);
                //var nestedAlternative = (Global.ChoiceModelDictionary.Get("ActumWorkTourModeModel") as ActumWorkTourModeModel).RunNested(personDay, residenceParcel, person.UsualWorkParcel, destinationArrivalTime, destinationDepartureTime, household.VehiclesAvailable);
                //JLB 201406
                //var nestedAlternative = Global.ChoiceModelSession.Get<WorkTourModeModel>().RunNested(pPersonDay, pPersonDay.Household.ResidenceParcel, sameUsualLocation, destinationArrivalTime, destinationDepartureTime, pPersonDay.Household.VehiclesAvailable);
                //JLB 201602
                //var nestedAlternative = Global.ChoiceModelSession.Get<WorkTourModeTimeModel>().RunNested(pPersonDay, pPersonDay.Household.ResidenceParcel, sameUsualLocation, destinationArrivalTime, destinationDepartureTime, pPersonDay.Household.VehiclesAvailable);
                ChoiceProbabilityCalculator.Alternative nestedAlternative = Global.ChoiceModelSession.Get <TourModeTimeModel>().RunNested(pPersonDay, pPersonDay.Household.ResidenceParcel, sameUsualLocation, destinationArrivalTime, destinationDepartureTime, pPersonDay.Household.VehiclesAvailable, Global.Settings.Purposes.Work);
                tourLogsum = nestedAlternative == null ? 0 : nestedAlternative.ComputeLogsum();


                // determine choice
                if (choice == alt)
                {
                    chosen[alt] = true;
                }

                //Get the alternative
                ChoiceProbabilityCalculator.Alternative alternative = choiceProbabilityCalculator.GetAlternative(alt, available[alt], chosen[alt]);

                alternative.Choice = alt;

                //Add utility terms that are not in components
                //alternative.AddUtilityTerm(399, 0);

                // OBS!!! This is new - 21nd January 2013 - it sais that these tris are less expected to be done with 3 or 4+ persons (compared to to people)
                alternative.AddUtilityTerm(59, altParticipants[alt][7] >= 3 ? 1 : 0);
                //alternative.AddUtilityTerm(60, altParticipants[alt][7] >= 4 ? 1 : 0); // OBS! no observations with 4+ HHsize
                alternative.AddUtilityTerm(58, tourLogsum);
                //Add utility components

                for (int p = 1; p <= 5; p++)
                {
                    if (altParticipants[alt][p] == 1)
                    {
                        alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]));
                    }
                }
                for (int t2 = 1; t2 <= 5; t2++)
                {
                    for (int t1 = 1; t1 < t2; t1++)
                    {
                        if (altParticipants[alt][t1] == 1 && altParticipants[alt][t2] == 1)
                        {
                            alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]));
                        }
                    }
                }
                for (int t2 = 1; t2 <= 5; t2++)
                {
                    for (int t1 = 1; t1 <= 5; t1++)
                    {
                        if (!(t1 == t2))
                        {
                            if (altParticipants[alt][t1] == 1 && altParticipants[alt][t2] == 1)
                            {
                                alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]));
                            }
                        }
                    }
                }
            }
        }
Esempio n. 29
0
        private void RunModel(ChoiceProbabilityCalculator choiceProbabilityCalculator, ITripWrapper trip, IEnumerable <dynamic> pathTypeModels, IParcelWrapper originParcel, IParcelWrapper destinationParcel, int departureTime, int choice = Constants.DEFAULT_VALUE)
        {
            var household       = trip.Household;
            var householdTotals = household.HouseholdTotals;
            var person          = trip.Person;
            var tour            = trip.Tour;
            var halfTour        = trip.HalfTour;

            // household inputs
            var onePersonHouseholdFlag  = household.IsOnePersonHousehold.ToFlag();
            var twoPersonHouseholdFlag  = household.IsTwoPersonHousehold.ToFlag();
            var income0To25KFlag        = household.Has0To25KIncome.ToFlag();
            var income25To45KFlag       = household.Has25To45KIncome.ToFlag();
            var childrenAge5Through15   = householdTotals.ChildrenAge5Through15;
            var nonworkingAdults        = householdTotals.NonworkingAdults;
            var retiredAdults           = householdTotals.RetiredAdults;
            var noCarsInHouseholdFlag   = household.GetFlagForNoCarsInHousehold(household.VehiclesAvailable);
            var carsLessThanDriversFlag = household.GetFlagForCarsLessThanDrivers(household.VehiclesAvailable);

            // person inputs
            var drivingAgeStudentFlag = person.IsDrivingAgeStudent.ToFlag();
            var maleFlag          = person.IsMale.ToFlag();
            var ageLessThan35Flag = person.AgeIsLessThan35.ToFlag();

            // tour inputs
            var parkAndRideTourFlag       = tour.IsParkAndRideMode().ToFlag();
            var transitTourFlag           = tour.IsTransitMode().ToFlag();
            var schoolBusTourFlag         = tour.IsSchoolBusMode().ToFlag();
            var hov3TourFlag              = tour.IsHov3Mode().ToFlag();
            var hov2TourFlag              = tour.IsHov2Mode().ToFlag();
            var sovTourFlag               = tour.IsSovMode().ToFlag();
            var bikeTourFlag              = tour.IsBikeMode().ToFlag();
            var walkTourFlag              = tour.IsWalkMode().ToFlag();
            var homeBasedWorkTourFlag     = (tour.IsHomeBasedTour && tour.IsWorkPurpose()).ToFlag();
            var homeBasedSchoolTourFlag   = (tour.IsHomeBasedTour && tour.IsSchoolPurpose()).ToFlag();
            var homeBasedEscortTourFlag   = (tour.IsHomeBasedTour && tour.IsEscortPurpose()).ToFlag();
            var homeBasedShoppingTourFlag = (tour.IsHomeBasedTour && tour.IsShoppingPurpose()).ToFlag();
            var homeBasedMealTourFlag     = (tour.IsHomeBasedTour && tour.IsMealPurpose()).ToFlag();
            var homeBasedSocialTourFlag   = (tour.IsHomeBasedTour && tour.IsSocialPurpose()).ToFlag();
            var notHomeBasedTourFlag      = (!tour.IsHomeBasedTour).ToFlag();
//			var homeBasedNotWorkSchoolEscortTourFlag = (tour.IsHomeBasedTour && tour.DestinationPurpose > Global.Settings.Purposes.Escort).ToFlag();
//			var costco = -0.1432 * homeBasedWorkTourFlag - 0.2000 * homeBasedSchoolTourFlag - 0.3000 * homeBasedEscortTourFlag - 0.2000 * homeBasedNotWorkSchoolEscortTourFlag - 0.2000 * notHomeBasedTourFlag;

            // trip inputs
            var originHomeEscortFlag = (trip.IsNoneOrHomePurposeByOrigin() && trip.IsEscortPurposeByDestination()).ToFlag();
            var originWorkEscortFlag = (trip.IsWorkPurposeByOrigin() && trip.IsEscortPurposeByDestination()).ToFlag();

            var destinationHomeEscortFlag = (trip.IsNoneOrHomePurposeByDestination() && trip.IsEscortPurposeByOrigin()).ToFlag();
            var destinationWorkEscortFlag = (trip.IsWorkPurposeByDestination() && trip.IsEscortPurposeByOrigin()).ToFlag();

            // only trip on first half-tour
            var onlyTripOnFirstHalfFlag = (trip.IsHalfTourFromOrigin && halfTour.SimulatedTrips == 1 && trip.IsToTourOrigin).ToFlag();

            // first trip on first half-tour, not only one
            var firstTripOnFirstHalfFlag = (trip.IsHalfTourFromOrigin && halfTour.SimulatedTrips == 1 && !trip.IsToTourOrigin).ToFlag();

            // last trip first half-tour, not only one
            var lastTripOnFirstHalfFlag = (trip.IsHalfTourFromOrigin && halfTour.SimulatedTrips > 1 && trip.IsToTourOrigin).ToFlag();

            // only trip on second half-tour
            var onlyTripOnSecondHalfFlag = (!trip.IsHalfTourFromOrigin && halfTour.SimulatedTrips == 1 && trip.IsToTourOrigin).ToFlag();

            // first trip on second half-tour, not only one
            var firstTripOnSecondHalfFlag = (!trip.IsHalfTourFromOrigin && halfTour.SimulatedTrips == 1 && !trip.IsToTourOrigin).ToFlag();

            // last trip second half-tour, not only one
            var lastTripOnSecondHalfFlag = (!trip.IsHalfTourFromOrigin && halfTour.SimulatedTrips > 1 && trip.IsToTourOrigin).ToFlag();

            // remaining inputs
            var originMixedDensity        = originParcel.MixedUse4Index1();
            var originIntersectionDensity = originParcel.NetIntersectionDensity1();
            var destinationParkingCost    = destinationParcel.ParkingCostBuffer1(2);
            var amPeriodFlag      = departureTime.IsLeftExclusiveBetween(Global.Settings.Times.SixAM, Global.Settings.Times.TenAM).ToFlag();
            var middayPeriodFlag  = departureTime.IsLeftExclusiveBetween(Global.Settings.Times.TenAM, Global.Settings.Times.ThreePM).ToFlag();
            var pmPeriodFlag      = departureTime.IsLeftExclusiveBetween(Global.Settings.Times.ThreePM, Global.Settings.Times.SevenPM).ToFlag();
            var eveningPeriodFlag = (departureTime > Global.Settings.Times.SevenPM).ToFlag();

            // availability
            var tripModeAvailable = new bool[Global.Settings.Modes.TotalModes];

            var isLastTripInTour = (!trip.IsHalfTourFromOrigin && halfTour.SimulatedTrips == 1 && trip.IsToTourOrigin) || (!trip.IsHalfTourFromOrigin && halfTour.SimulatedTrips > 1 && trip.IsToTourOrigin);
            var frequencyPreviousTripModeIsTourMode =
                trip.IsHalfTourFromOrigin
                                        ? tour.HalfTourFromOrigin.Trips.Where(x => x.Sequence < trip.Sequence).Count(x => tour.Mode == x.Mode)
                                        : tour.HalfTourFromOrigin.Trips.Union(tour.HalfTourFromDestination.Trips.Where(x => x.Sequence < trip.Sequence)).Count(x => tour.Mode == x.Mode);

            // if a park and ride tour, only car is available
            if (tour.Mode == Global.Settings.Modes.ParkAndRide)
            {
                tripModeAvailable[Global.Settings.Modes.Sov]  = tour.Household.VehiclesAvailable > 0 && tour.Person.IsDrivingAge;
                tripModeAvailable[Global.Settings.Modes.Hov2] = !tripModeAvailable[Global.Settings.Modes.Sov];
            }
            // if the last trip of the tour and tour mode not yet used, only the tour mode is available
            else if (isLastTripInTour && frequencyPreviousTripModeIsTourMode == 0)
            {
                tripModeAvailable[tour.Mode] = true;
            }
            else
            {
                // set availability based on tour mode
                for (var mode = Global.Settings.Modes.Walk; mode <= tour.Mode; mode++)
                {
                    tripModeAvailable[mode] = true;
                }
            }

            // school bus is a special case - use HOV3 impedance and only available for school bus tours
            var pathTypeExtra              = pathTypeModels.First(x => x.Mode == Global.Settings.Modes.Hov3);
            var modeExtra                  = Global.Settings.Modes.SchoolBus;
            var availableExtra             = pathTypeExtra.Available && tour.IsSchoolBusMode() && tripModeAvailable[modeExtra];
            var generalizedTimeLogsumExtra = pathTypeExtra.GeneralizedTimeLogsum;

            var alternative = choiceProbabilityCalculator.GetAlternative(modeExtra, availableExtra, choice == modeExtra);

            alternative.Choice = modeExtra;

            alternative.AddNestedAlternative(_nestedAlternativeIds[modeExtra], _nestedAlternativeIndexes[modeExtra], THETA_PARAMETER);

            if (availableExtra)
            {
                //	case Global.Settings.Modes.SchoolBus:
                alternative.AddUtilityTerm(2, generalizedTimeLogsumExtra * tour.TimeCoefficient);
                alternative.AddUtilityTerm(18, 1);
                alternative.AddUtilityTerm(100, schoolBusTourFlag);
                alternative.AddUtilityTerm(102, (schoolBusTourFlag * onlyTripOnFirstHalfFlag));
                alternative.AddUtilityTerm(103, (schoolBusTourFlag * onlyTripOnSecondHalfFlag));
                alternative.AddUtilityTerm(104, (schoolBusTourFlag * firstTripOnFirstHalfFlag));
                alternative.AddUtilityTerm(105, (schoolBusTourFlag * firstTripOnSecondHalfFlag));
                alternative.AddUtilityTerm(106, (schoolBusTourFlag * lastTripOnFirstHalfFlag));
                alternative.AddUtilityTerm(107, (schoolBusTourFlag * lastTripOnSecondHalfFlag));
                alternative.AddUtilityTerm(112, parkAndRideTourFlag);
                alternative.AddUtilityTerm(113, transitTourFlag);
            }

            foreach (var pathTypeModel in pathTypeModels)
            {
                var mode                  = pathTypeModel.Mode;
                var available             = pathTypeModel.Available && tripModeAvailable[mode];
                var generalizedTimeLogsum = pathTypeModel.GeneralizedTimeLogsum;

                alternative        = choiceProbabilityCalculator.GetAlternative(mode, available, choice == mode);
                alternative.Choice = mode;

                alternative.AddNestedAlternative(_nestedAlternativeIds[mode], _nestedAlternativeIndexes[mode], THETA_PARAMETER);

                if (!available)
                {
                    continue;
                }

                alternative.AddUtilityTerm(2, generalizedTimeLogsum * tour.TimeCoefficient);

                if (mode == Global.Settings.Modes.Transit)
                {
                    alternative.AddUtilityTerm(20, 1);
                    alternative.AddUtilityTerm(22, carsLessThanDriversFlag);
                    alternative.AddUtilityTerm(100, transitTourFlag);
                    alternative.AddUtilityTerm(102, (transitTourFlag * onlyTripOnFirstHalfFlag));
                    alternative.AddUtilityTerm(103, (transitTourFlag * onlyTripOnSecondHalfFlag));
                    alternative.AddUtilityTerm(104, (transitTourFlag * firstTripOnFirstHalfFlag));
                    alternative.AddUtilityTerm(105, (transitTourFlag * firstTripOnSecondHalfFlag));
                    alternative.AddUtilityTerm(106, (transitTourFlag * lastTripOnFirstHalfFlag));
                    alternative.AddUtilityTerm(107, (transitTourFlag * lastTripOnSecondHalfFlag));
                }
                else if (mode == Global.Settings.Modes.Hov3)
                {
                    alternative.AddUtilityTerm(30, 1);
                    alternative.AddUtilityTerm(1, (destinationParkingCost * tour.CostCoefficient / ChoiceModelUtility.CPFACT3));
                    alternative.AddUtilityTerm(32, childrenAge5Through15);
                    alternative.AddUtilityTerm(34, (nonworkingAdults + retiredAdults));
                    alternative.AddUtilityTerm(36, onePersonHouseholdFlag);
                    alternative.AddUtilityTerm(37, twoPersonHouseholdFlag);
                    alternative.AddUtilityTerm(41, noCarsInHouseholdFlag);
                    alternative.AddUtilityTerm(100, hov3TourFlag);
                    alternative.AddUtilityTerm(102, (hov3TourFlag * onlyTripOnFirstHalfFlag));
                    alternative.AddUtilityTerm(103, (hov3TourFlag * onlyTripOnSecondHalfFlag));
                    alternative.AddUtilityTerm(104, (hov3TourFlag * firstTripOnFirstHalfFlag));
                    alternative.AddUtilityTerm(105, (hov3TourFlag * firstTripOnSecondHalfFlag));
                    alternative.AddUtilityTerm(106, (hov3TourFlag * lastTripOnFirstHalfFlag));
                    alternative.AddUtilityTerm(107, (hov3TourFlag * lastTripOnSecondHalfFlag));
                    alternative.AddUtilityTerm(114, parkAndRideTourFlag);
                    alternative.AddUtilityTerm(115, transitTourFlag);
                    alternative.AddUtilityTerm(116, schoolBusTourFlag);
                    alternative.AddUtilityTerm(149, homeBasedWorkTourFlag);
                    alternative.AddUtilityTerm(150, homeBasedSchoolTourFlag);
                    alternative.AddUtilityTerm(152, homeBasedEscortTourFlag);
                    alternative.AddUtilityTerm(153, homeBasedShoppingTourFlag);
                    alternative.AddUtilityTerm(154, homeBasedMealTourFlag);
                    alternative.AddUtilityTerm(155, homeBasedSocialTourFlag);
                    alternative.AddUtilityTerm(161, (destinationWorkEscortFlag * amPeriodFlag));
                    alternative.AddUtilityTerm(162, (originWorkEscortFlag * pmPeriodFlag));
                    alternative.AddUtilityTerm(163, (originHomeEscortFlag * amPeriodFlag));
                    alternative.AddUtilityTerm(164, (originHomeEscortFlag * middayPeriodFlag));
                    alternative.AddUtilityTerm(165, (originHomeEscortFlag * pmPeriodFlag));
                    alternative.AddUtilityTerm(166, (originHomeEscortFlag * eveningPeriodFlag));
                    alternative.AddUtilityTerm(167, (destinationHomeEscortFlag * amPeriodFlag));
                    alternative.AddUtilityTerm(168, (destinationHomeEscortFlag * middayPeriodFlag));
                    alternative.AddUtilityTerm(169, (destinationHomeEscortFlag * pmPeriodFlag));
                    alternative.AddUtilityTerm(170, (destinationHomeEscortFlag * eveningPeriodFlag));
                }
                else if (mode == Global.Settings.Modes.Hov2)
                {
                    alternative.AddUtilityTerm(40, 1);
                    alternative.AddUtilityTerm(1, (destinationParkingCost * tour.CostCoefficient / ChoiceModelUtility.CPFACT2));
                    alternative.AddUtilityTerm(32, (childrenAge5Through15 * (1 - homeBasedEscortTourFlag)));
                    alternative.AddUtilityTerm(34, ((nonworkingAdults + retiredAdults) * (1 - homeBasedEscortTourFlag)));
                    alternative.AddUtilityTerm(38, onePersonHouseholdFlag);
                    alternative.AddUtilityTerm(41, noCarsInHouseholdFlag);
                    alternative.AddUtilityTerm(100, hov2TourFlag);
                    alternative.AddUtilityTerm(102, (hov2TourFlag * onlyTripOnFirstHalfFlag));
                    alternative.AddUtilityTerm(103, (hov2TourFlag * onlyTripOnSecondHalfFlag));
                    alternative.AddUtilityTerm(104, (hov2TourFlag * firstTripOnFirstHalfFlag));
                    alternative.AddUtilityTerm(105, (hov2TourFlag * firstTripOnSecondHalfFlag));
                    alternative.AddUtilityTerm(106, (hov2TourFlag * lastTripOnFirstHalfFlag));
                    alternative.AddUtilityTerm(107, (hov2TourFlag * lastTripOnSecondHalfFlag));
                    alternative.AddUtilityTerm(118, transitTourFlag);
                    alternative.AddUtilityTerm(119, schoolBusTourFlag);
                    alternative.AddUtilityTerm(120, hov3TourFlag);
                    alternative.AddUtilityTerm(149, homeBasedWorkTourFlag);
                    alternative.AddUtilityTerm(150, homeBasedSchoolTourFlag);
                    alternative.AddUtilityTerm(152, homeBasedEscortTourFlag);
                    alternative.AddUtilityTerm(153, homeBasedShoppingTourFlag);
                    alternative.AddUtilityTerm(154, homeBasedMealTourFlag);
                    alternative.AddUtilityTerm(155, homeBasedSocialTourFlag);
                    alternative.AddUtilityTerm(161, (destinationWorkEscortFlag * amPeriodFlag));
                    alternative.AddUtilityTerm(162, (originWorkEscortFlag * pmPeriodFlag));
                    alternative.AddUtilityTerm(163, (originHomeEscortFlag * amPeriodFlag));
                    alternative.AddUtilityTerm(164, (originHomeEscortFlag * middayPeriodFlag));
                    alternative.AddUtilityTerm(165, (originHomeEscortFlag * pmPeriodFlag));
                    alternative.AddUtilityTerm(166, (originHomeEscortFlag * eveningPeriodFlag));
                    alternative.AddUtilityTerm(167, (destinationHomeEscortFlag * amPeriodFlag));
                    alternative.AddUtilityTerm(168, (destinationHomeEscortFlag * middayPeriodFlag));
                    alternative.AddUtilityTerm(169, (destinationHomeEscortFlag * pmPeriodFlag));
                    alternative.AddUtilityTerm(170, (destinationHomeEscortFlag * eveningPeriodFlag));
                }
                else if (mode == Global.Settings.Modes.Sov)
                {
                    alternative.AddUtilityTerm(50, 1);
                    alternative.AddUtilityTerm(1, (destinationParkingCost * tour.CostCoefficient));
                    alternative.AddUtilityTerm(52, carsLessThanDriversFlag);
                    alternative.AddUtilityTerm(54, income0To25KFlag);
                    alternative.AddUtilityTerm(55, income25To45KFlag);
                    alternative.AddUtilityTerm(59, drivingAgeStudentFlag);
                    alternative.AddUtilityTerm(100, sovTourFlag);
                    alternative.AddUtilityTerm(102, (sovTourFlag * onlyTripOnFirstHalfFlag));
                    alternative.AddUtilityTerm(103, (sovTourFlag * onlyTripOnSecondHalfFlag));
                    alternative.AddUtilityTerm(104, (sovTourFlag * firstTripOnFirstHalfFlag));
                    alternative.AddUtilityTerm(105, (sovTourFlag * firstTripOnSecondHalfFlag));
                    alternative.AddUtilityTerm(106, (sovTourFlag * lastTripOnFirstHalfFlag));
                    alternative.AddUtilityTerm(107, (sovTourFlag * lastTripOnSecondHalfFlag));
                    alternative.AddUtilityTerm(121, parkAndRideTourFlag);
                    alternative.AddUtilityTerm(122, transitTourFlag);
                    alternative.AddUtilityTerm(124, hov3TourFlag);
                    alternative.AddUtilityTerm(125, hov2TourFlag);
                }
                else if (mode == Global.Settings.Modes.Bike)
                {
                    alternative.AddUtilityTerm(60, 1);
                    alternative.AddUtilityTerm(61, maleFlag);
                    alternative.AddUtilityTerm(62, ageLessThan35Flag);
                    alternative.AddUtilityTerm(65, originIntersectionDensity);
                    alternative.AddUtilityTerm(100, bikeTourFlag);
                    alternative.AddUtilityTerm(102, (bikeTourFlag * onlyTripOnFirstHalfFlag));
                    alternative.AddUtilityTerm(103, (bikeTourFlag * onlyTripOnSecondHalfFlag));
                    alternative.AddUtilityTerm(104, (bikeTourFlag * firstTripOnFirstHalfFlag));
                    alternative.AddUtilityTerm(105, (bikeTourFlag * firstTripOnSecondHalfFlag));
                    alternative.AddUtilityTerm(106, (bikeTourFlag * lastTripOnFirstHalfFlag));
                    alternative.AddUtilityTerm(107, (bikeTourFlag * lastTripOnSecondHalfFlag));
                    alternative.AddUtilityTerm(127, transitTourFlag);
                    alternative.AddUtilityTerm(128, schoolBusTourFlag);
                    alternative.AddUtilityTerm(130, hov2TourFlag);
                    alternative.AddUtilityTerm(131, sovTourFlag);
                    alternative.AddUtilityTerm(147, notHomeBasedTourFlag);
                }
                else if (mode == Global.Settings.Modes.Walk)
                {
                    alternative.AddUtilityTerm(72, ageLessThan35Flag);
                    alternative.AddUtilityTerm(75, originIntersectionDensity);
                    alternative.AddUtilityTerm(78, originMixedDensity);                     // origin and destination mixed use measures - geometric avg. - half mile from cell, in 1000s
                    alternative.AddUtilityTerm(100, walkTourFlag);
                    alternative.AddUtilityTerm(102, (walkTourFlag * onlyTripOnFirstHalfFlag));
                    alternative.AddUtilityTerm(103, (walkTourFlag * onlyTripOnSecondHalfFlag));
                    alternative.AddUtilityTerm(104, (walkTourFlag * firstTripOnFirstHalfFlag));
                    alternative.AddUtilityTerm(105, (walkTourFlag * firstTripOnSecondHalfFlag));
                    alternative.AddUtilityTerm(106, (walkTourFlag * lastTripOnFirstHalfFlag));
                    alternative.AddUtilityTerm(107, (walkTourFlag * lastTripOnSecondHalfFlag));
                    alternative.AddUtilityTerm(141, homeBasedWorkTourFlag);
                    alternative.AddUtilityTerm(142, homeBasedSchoolTourFlag);
                }
            }
        }
        private void RunModel(ChoiceProbabilityCalculator choiceProbabilityCalculator, HouseholdDayWrapper householdDay, int nCallsForTour, int[] purpose, int[][] altParticipants, int choice = Constants.DEFAULT_VALUE)
        {
            IEnumerable<PersonDayWrapper> orderedPersonDays = householdDay.PersonDays.OrderBy(p => p.GetJointTourParticipationPriority()).ToList().Cast<PersonDayWrapper>();
              // set household characteristics here that don't depend on person characteristics

              int carOwnership =
                householdDay.Household.VehiclesAvailable == 0
                     ? Global.Settings.CarOwnerships.NoCars
                     : householdDay.Household.VehiclesAvailable < householdDay.Household.HouseholdTotals.DrivingAgeMembers
                          ? Global.Settings.CarOwnerships.LtOneCarPerAdult
                          : Global.Settings.CarOwnerships.OneOrMoreCarsPerAdult;
              int hhsize = householdDay.Household.Size;
              int noCarsFlag = FlagUtility.GetNoCarsFlag(carOwnership);
              int carCompetitionFlag = FlagUtility.GetCarCompetitionFlag(carOwnership);

              int tourPurpose = purpose[nCallsForTour];

              int escortPurpose = purpose[nCallsForTour] == Global.Settings.Purposes.Escort ? 1 : 0;
              int shopPurpose = purpose[nCallsForTour] == Global.Settings.Purposes.Shopping ? 1 : 0;
              int socialPurpose = (purpose[nCallsForTour] == Global.Settings.Purposes.Social ? 1 : 0);
              int recreationPurpose = (purpose[nCallsForTour] == Global.Settings.Purposes.Recreation) ? 1 : 0;
              int personalBusinessMedicalPurpose = (purpose[nCallsForTour] == Global.Settings.Purposes.PersonalBusiness
                                                   || purpose[nCallsForTour] == Global.Settings.Purposes.Medical) ? 1 : 0;
              int meal = (purpose[nCallsForTour] == Global.Settings.Purposes.Meal) ? 1 : 0;
              int socialRecreationPurpose = (purpose[nCallsForTour] == Global.Settings.Purposes.Social ||
                                              purpose[nCallsForTour] == Global.Settings.Purposes.Recreation) ? 1 : 0;
              //nt recreationPurpose =    (purpose[nCallsForTour] == Global.Settings.Purposes.Recreation)     ? 1 : 0;

              int votALSegment = householdDay.Household.GetVotALSegment();
              int transitAccessSegment = householdDay.Household.ResidenceParcel.TransitAccessSegment();
              double totalAggregateLogsum = Global.AggregateLogsums[householdDay.Household.ResidenceParcel.ZoneId]
                                                [Global.Settings.Purposes.HomeBasedComposite][carOwnership][votALSegment][transitAccessSegment];

              PersonDayWrapper pPersonDay = null;

              bool[] pLessThan3NonMandatoryTours = new bool[6];
              bool[] pLessThan3TourPurposes = new bool[6];
              int[] pUsualLocationParcelId = new int[6];
              int[] pUsualLocationZoneId = new int[6];
              IParcelWrapper[] pUsualLocationParcel = new IParcelWrapper[6];
              int[] pPatternType = new int[6];
              int[] pConstant = new int[6];
              int[,] pType = new int[9, 6];
              int[] pAdult = new int[6];
              int[] pChild = new int[6];
              int[] pAge = new int[6];

              //int[] pAdultMale = new int[6];
              int[] pAdultFemale = new int[6];
              int[] pAdultMandatory = new int[6];
              int[] pNonMandatory = new int[6];
              int[] pMandatory = new int[6];
              int[] pAdultNonMandatory = new int[6];
              int[] pAdultWithChildrenUnder16 = new int[6];

              int[] pAge5To8 = new int[6];
              int[] pAge9To12 = new int[6];
              int[] pAge13To15 = new int[6];
              int[] pAgeUnder13 = new int[6];

              int[] pTransit = new int[6];

              //int[] pJointNonMandatoryTours = new int[6];
              int[] pJointEscortTours = new int[6];
              int[] pMandatoryTours = new int[6];
              int[] pJointSocialRecreationTours = new int[6];
              //int[] pJointPersMedtours = new int[6];
              int[] pNonMandatoryChild = new int[6];
              int[] pMandatoryChild = new int[6];
              //int[] pJointShopTours = new int[6];
              int[] pJointMealTours = new int[6];

              int count = 0;
              foreach (PersonDayWrapper personDay in orderedPersonDays) {
            count++;
            if (count <= 5) {
              if (count == 1) {
            pPersonDay = personDay;
              }
              for (int i = 1; i < 9; i++) {
            pType[personDay.Person.PersonType, count] = 1;
              }

              if (personDay.Person.IsFullOrPartTimeWorker && personDay.Person.UsualWorkParcel != null) {
            pUsualLocationParcelId[count] = personDay.Person.UsualWorkParcelId;
            pUsualLocationParcel[count] = personDay.Person.UsualWorkParcel;
            pUsualLocationZoneId[count] = personDay.Person.UsualWorkParcel.ZoneId;
              } else if (personDay.Person.IsStudent && personDay.Person.UsualSchoolParcel != null) {
            pUsualLocationParcelId[count] = personDay.Person.UsualSchoolParcelId;
            pUsualLocationParcel[count] = personDay.Person.UsualSchoolParcel;
            pUsualLocationZoneId[count] = personDay.Person.UsualSchoolParcel.ZoneId;
              } else if (personDay.Person.IsWorker && personDay.Person.IsNotFullOrPartTimeWorker && personDay.Person.UsualWorkParcel != null) {
            pUsualLocationParcelId[count] = personDay.Person.UsualWorkParcelId;
            pUsualLocationParcel[count] = personDay.Person.UsualWorkParcel;
            pUsualLocationZoneId[count] = personDay.Person.UsualWorkParcel.ZoneId;
              } else {
            pUsualLocationParcelId[count] = personDay.Household.ResidenceParcelId;
            pUsualLocationParcel[count] = personDay.Household.ResidenceParcel;
            pUsualLocationZoneId[count] = personDay.Household.ResidenceZoneId;
              }

              pLessThan3NonMandatoryTours[count] = personDay.GetCreatedNonMandatoryTours() < 3;
              pLessThan3TourPurposes[count] = personDay.GetTotalCreatedTourPurposes() < 3;
              pPatternType[count] = personDay.PatternType;
              pConstant[count] = 1;
              pAdult[count] = personDay.Person.IsAdult.ToFlag();
              pChild[count] = (!(personDay.Person.IsAdult)).ToFlag();
              pAdultWithChildrenUnder16[count] = (personDay.Person.IsAdult && personDay.Household.HasChildrenUnder16).ToFlag();
              pAdultFemale[count] = personDay.Person.IsAdultFemale.ToFlag();
              //pAdultMale[count] = personDay.Person.IsAdultMale.ToFlag();
              pAdultMandatory[count] = personDay.Person.IsAdult.ToFlag() * (personDay.PatternType == Global.Settings.PatternTypes.Mandatory).ToFlag();
              pNonMandatory[count] = (personDay.PatternType == Global.Settings.PatternTypes.Optional).ToFlag();
              pAdultNonMandatory[count] = (personDay.PatternType == Global.Settings.PatternTypes.Optional).ToFlag() * personDay.Person.IsAdult.ToFlag();
              pAgeUnder13[count] = (personDay.Person.Age < 13).ToFlag();
              pAge5To8[count] = (personDay.Person.Age >= 5 && personDay.Person.Age <= 8).ToFlag();
              //pAge9To12[count] = (personDay.Person.Age >= 9 && personDay.Person.Age <= 12).ToFlag();
              pAge13To15[count] = (personDay.Person.Age >= 13 && personDay.Person.Age <= 15).ToFlag();
              pTransit[count] = (personDay.Person.TransitPassOwnership == 1 ? 1 : 0);
              pMandatory[count] = (personDay.PatternType == Global.Settings.PatternTypes.Mandatory).ToFlag();
              pMandatoryTours[count] = personDay.WorkTours + personDay.SchoolTours;
              pJointEscortTours[count] = personDay.CreatedEscortTours;
              pJointMealTours[count] = personDay.CreatedMealTours;
              //pJointShopTours[count]= personDay.CreatedShoppingTours;
              pJointSocialRecreationTours[count] = personDay.CreatedSocialTours + personDay.CreatedRecreationTours;
              pNonMandatoryChild[count] = (personDay.PatternType == Global.Settings.PatternTypes.Optional).ToFlag() * personDay.Person.IsChildUnder16.ToFlag();
              pMandatoryChild[count] = (personDay.PatternType == Global.Settings.PatternTypes.Mandatory).ToFlag() * personDay.Person.IsChildUnder16.ToFlag();

            }
              }
              int componentIndex = 0;
              //Create person utility components
              int[] componentPerson = new int[6];
              for (int p = 1; p <= 5; p++) {
            // create component for basic person-purposes
            componentIndex++;
            componentPerson[p] = componentIndex;
            choiceProbabilityCalculator.CreateUtilityComponent(componentPerson[p]);

            choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(01, pAge5To8[p]);
            choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(02, pAdultFemale[p]);
            //choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(03, pAge9To12[p]);
            choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(05, (pMandatoryTours[p] > 1).ToFlag());
            //choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(06, (pJointNonMandatoryTours[p]>1).ToFlag());
            choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(07, pAdultMandatory[p]);
            choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(08, pTransit[p]);

            choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(21, pAdult[p] * escortPurpose);
            choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(26, pType[6, p] * pNonMandatory[p] * escortPurpose);
            choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(28, pType[8, p] * pNonMandatory[p] * escortPurpose);
            choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(29, pType[6, p] * pMandatory[p] * escortPurpose);
            choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(30, pType[7, p] * pMandatory[p] * escortPurpose);
            choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(31, pType[8, p] * pMandatory[p] * escortPurpose);
            choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(32, (pJointEscortTours[p] == 1).ToFlag() * escortPurpose);
            choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(33, (pJointEscortTours[p] >= 2).ToFlag() * escortPurpose);

            choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(41, pAdult[p] * personalBusinessMedicalPurpose);
            choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(44, pNonMandatoryChild[p] * personalBusinessMedicalPurpose);
            choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(45, pMandatoryChild[p] * personalBusinessMedicalPurpose);

            //choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(51, pAdultMandatory[p]*  shopPurpose);
            choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(52, pAdultNonMandatory[p] * shopPurpose);
            choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(54, pNonMandatoryChild[p] * shopPurpose);
            choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(56, pType[6, p] * pMandatory[p] * shopPurpose);
            choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(57, pType[7, p] * pMandatory[p] * shopPurpose);
            choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(58, pType[8, p] * pMandatory[p] * shopPurpose);
            //choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(59, (pJointShopTours[p]>1).ToFlag() *  shopPurpose);

            choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(71, pAdult[p] * meal);
            choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(77, (pJointMealTours[p] > 0).ToFlag() * meal);

            choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(92, pAdult[p] * socialRecreationPurpose);
            choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(96, pType[6, p] * pMandatory[p] * socialRecreationPurpose);
            choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(97, pType[7, p] * pMandatory[p] * socialRecreationPurpose);
            choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(98, pType[8, p] * pMandatory[p] * socialRecreationPurpose);
            choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(99, (pJointSocialRecreationTours[p] >= 1).ToFlag() * socialRecreationPurpose);
              }

              //create two-way match interaction utility components
              int[,] componentMatch = new int[6, 6];
              int[,] iMatchAdult = new int[6, 6];
              int[,] iMatchAdultWithChildrenUnder16 = new int[6, 6];

              int[,] iMatchMandatoryAdults = new int[6, 6];
              int[,] iMatchNonMandatoryAdults = new int[6, 6];
              int[,] iMatchChild = new int[6, 6];
              int[,] iMatchNonMandatoryKids = new int[6, 6];
              int[,] iMatchMandatoryKids = new int[6, 6];
              int[,] iMatchNonMandatory = new int[6, 6];
              int[,] iMatchUsualLocation = new int[6, 6];

              for (int t2 = 1; t2 <= 5; t2++) {
            for (int t1 = 1; t1 < t2; t1++) {
              //populate match variables
              iMatchAdultWithChildrenUnder16[t1, t2] = pAdultWithChildrenUnder16[t1] * pAdultWithChildrenUnder16[t2];
              iMatchNonMandatoryAdults[t1, t2] = pAdultNonMandatory[t1] * pAdultNonMandatory[t2];
              iMatchMandatoryAdults[t1, t2] = pAdultMandatory[t1] * pAdultMandatory[t2];

              iMatchNonMandatory[t1, t2] = pNonMandatory[t1] * pNonMandatory[t2];
              iMatchUsualLocation[t1, t2] = (pUsualLocationParcelId[t1] == pUsualLocationParcelId[t2]) ? 1 : 0;

              iMatchChild[t1, t2] = (1 - pAdult[t1]) * (1 - pAdult[t2]);
              iMatchNonMandatoryKids[t1, t2] = pNonMandatory[t1] * pAgeUnder13[t1] * pNonMandatory[t2] * pAgeUnder13[t2];
              iMatchMandatoryKids[t1, t2] = pMandatory[t1] * pAgeUnder13[t1] * pMandatory[t2] * pAgeUnder13[t2];

              //create and populate components
              componentIndex++;
              componentMatch[t1, t2] = componentIndex;
              choiceProbabilityCalculator.CreateUtilityComponent(componentMatch[t1, t2]);
              choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(109, iMatchNonMandatoryKids[t1, t2]);
              choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(110, iMatchMandatoryKids[t1, t2]);
              choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(111, iMatchMandatoryAdults[t1, t2]);
              //choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(113, iMatchAdultNonMandatorys[t1, t2]);
              choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(114, iMatchAdultWithChildrenUnder16[t1, t2]);
              choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(116, iMatchNonMandatory[t1, t2] * socialRecreationPurpose);
              choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(124, iMatchChild[t1, t2] * shopPurpose);
              choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(125, iMatchUsualLocation[t1, t2]);

            }
              }

              //create two-way cross interaction utility components
              int[,] componentCross = new int[6, 6];
              int iCrossAgeUnder5AndNonMandatory;
              int iCrossAge5To12AndNonMandatory;
              int iCrossAge13To15AndNonMandatory;
              int iCrossDrivingAgeChildAndNonMandatory;
              int iCrossMandatoryAdAndChild;

              for (int t2 = 1; t2 <= 5; t2++) {
            for (int t1 = 1; t1 <= 5; t1++) {
              if (!(t1 == t2)) {
            //populate cross variables
            iCrossAge5To12AndNonMandatory = pAdultNonMandatory[t1] * (pAge5To8[t2] + pAge9To12[t2]);
            iCrossAgeUnder5AndNonMandatory = pAdultNonMandatory[t1] * pType[8, t2];
            iCrossAge13To15AndNonMandatory = pNonMandatory[t1] * pAge13To15[t2];
            iCrossDrivingAgeChildAndNonMandatory = pNonMandatory[t1] * pType[6, t2];
            iCrossMandatoryAdAndChild = pAdultMandatory[t1] * pChild[t2];
            //create and populate cross components
            componentIndex++;
            componentCross[t1, t2] = componentIndex;
            choiceProbabilityCalculator.CreateUtilityComponent(componentCross[t1, t2]);
            choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(133, iCrossAge13To15AndNonMandatory);
            choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(135, iCrossAgeUnder5AndNonMandatory * escortPurpose);
            choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(136, iCrossAgeUnder5AndNonMandatory * personalBusinessMedicalPurpose);
            choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(137, iCrossAgeUnder5AndNonMandatory * shopPurpose);
            choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(138, iCrossAgeUnder5AndNonMandatory * meal);
            choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(139, iCrossAgeUnder5AndNonMandatory * socialRecreationPurpose);
            choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(144, iCrossAge5To12AndNonMandatory * socialRecreationPurpose);
            //choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(145, iCrossMandatoryAdAndChild*escortPurpose);
            choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(146, iCrossMandatoryAdAndChild * personalBusinessMedicalPurpose);
            choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(147, iCrossMandatoryAdAndChild * shopPurpose);
            choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(148, iCrossMandatoryAdAndChild * meal);
            choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(149, iCrossMandatoryAdAndChild * socialRecreationPurpose);

              }
            }
              }

              //Generate utility funtions for the alternatives
              bool[] available = new bool[32];
              bool[] chosen = new bool[32];
              for (int alt = 0; alt < 32; alt++) {

            available[alt] = false;
            chosen[alt] = false;
            // set availability based on household size
            if (hhsize >= altParticipants[alt][6]) {
              available[alt] = true;
            }
            // restrict availability of alts that include less than 2 participants
            if (altParticipants[alt][7] < 2) {
              available[alt] = false;
            }
            // restrict availability if any participant has at-home patternType
            int numberAtHomePatternTypes = 0;
            for (int i = 1; i <= 5; i++) {
              if (altParticipants[alt][i] == 1 && pPatternType[i] == Global.Settings.PatternTypes.Home) {
            numberAtHomePatternTypes++;
              }
            }
            if (numberAtHomePatternTypes > 0) {
              available[alt] = false;
            }
            // restrict availability if any participant has 3 or more nonmandatory tours already
            for (int i = 1; i <= 5; i++) {
              if (altParticipants[alt][i] == 1 && !pLessThan3NonMandatoryTours[i]) {
            available[alt] = false;
              }
            }

            // restrict availability if any participant has 3 or more tour purposes already
            for (int i = 1; i <= 5; i++) {
              if (altParticipants[alt][i] == 1 && !pLessThan3TourPurposes[i]) {
            available[alt] = false;
              }
            }

            int numberOfParticipants = 0;
            int workersParticipating = 0;
            int numberOfParticipatingChildren = 0;
            int numberOfParticipatingAdults = 0;
            int numberOfAvailableChildren = 0;
            int numberOfAvailablePersons = 0;
            int numberOfAvailableAdults = 0;

            if (available[alt] == true) {
              for (int i = 1; i <= 5; i++) {
            if (pChild[i] == 1) {
              numberOfAvailableChildren++;
              numberOfAvailablePersons++;
            }
            if (pAdult[i] == 1) {
              numberOfAvailableChildren++;
              numberOfAvailableAdults++;
            }

            if (altParticipants[alt][i] == 1) {
              numberOfParticipants++;
              if (pType[0, i] == 1 || pType[1, i] == 1) {
                workersParticipating++;
              }
              if (pAdult[i] == 1) { numberOfParticipatingAdults++; }
              if (pChild[i] == 1) { numberOfParticipatingChildren++; }
            }
              }
            }

            // determine choice
            if (choice == alt) { chosen[alt] = true; }

            //Get the alternative
            ChoiceProbabilityCalculator.Alternative alternative = choiceProbabilityCalculator.GetAlternative(alt, available[alt], chosen[alt]);

            alternative.Choice = alt;

            //Add alt-specific utility terms
            alternative.AddUtilityTerm(160, (numberOfParticipatingAdults > 1 && numberOfParticipatingChildren > 0) ? 1 : 0);
            //alternative.AddUtilityTerm(161, (numberOfParticipatingChildren < numberOfAvailableChildren) ? 1 : 0);
            //alternative.AddUtilityTerm(162, (numberOfParticipatingAdults >1).ToFlag() *socialRecreationPurpose);
            //alternative.AddUtilityTerm(163, (numberOfParticipatingAdults == 1).ToFlag() *personalBusinessMedicalPurpose);

            for (int p = 1; p <= 5; p++) {
              if (altParticipants[alt][p] == 1) {
            alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]));
              }
            }
            for (int t2 = 1; t2 <= 5; t2++) {
              for (int t1 = 1; t1 < t2; t1++) {
            if (altParticipants[alt][t1] == 1 && altParticipants[alt][t2] == 1) {
              alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]));

            }
              }
            }
            for (int t2 = 1; t2 <= 5; t2++) {
              for (int t1 = 1; t1 <= 5; t1++) {
            if (!(t1 == t2)) {
              if (altParticipants[alt][t1] == 1 && altParticipants[alt][t2] == 1) {
                alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]));
              }
            }
              }
            }
              }
        }