示例#1
0
        protected override void RegionSpecificCustomizations(ChoiceProbabilityCalculator.Alternative alternative, IPersonWrapper _person, IParcelWrapper destinationParcel)
        {
            var homedist = _person.Household.ResidenceParcel.District;
            var zonedist = destinationParcel.District;

            //add any region-specific new terms in region-specific class, using coefficient numbers 91-97, 99,100 or other unused variable #
            //Global.PrintFile.WriteLine("Default PSRC_WorkLocationModel.RegionSpecificCustomizations called");
            var homeSKitWorkTRP   = homedist == 11 && (zonedist == 8 || zonedist == 10 || zonedist == 7) ? 1 : 0;
            var homeKitWorkTRP    = homedist == 9 && (zonedist == 8 || zonedist == 10 || zonedist == 7) ? 1 : 0;
            var homeEastWorkCBD   = homedist == 6 && zonedist == 4 ? 1 : 0;
            var homeKitWorkCBD    = (homedist == 9 || homedist == 11) && (zonedist == 4) ? 1 : 0;
            var homeTacWorkKit    = homedist == 8 && (zonedist == 9 || zonedist == 11) ? 1 : 0;
            var homeEvWorkEv      = homedist == 2 && zonedist == 2 ? 1 : 0;
            var homeWSWorkEast    = homedist == 5 && zonedist == 6 ? 1 : 0;
            var homeEastWorkEast  = homedist == 6 && zonedist == 6 ? 1 : 0;
            var homeKitWorkNotKit = (homedist == 9 || homedist == 11) && zonedist != 9 && zonedist != 11 ? 1 : 0;
            var homeSTacWorkCBD   = (homedist == 5 || homedist == 8) && zonedist == 9 ? 1 : 0;

            alternative.AddUtilityTerm(91, homeEastWorkEast);
            alternative.AddUtilityTerm(92, homeTacWorkKit);
            alternative.AddUtilityTerm(93, homeEvWorkEv);
            alternative.AddUtilityTerm(94, homeWSWorkEast);
            alternative.AddUtilityTerm(95, homeSKitWorkTRP);
            alternative.AddUtilityTerm(96, homeSTacWorkCBD);
            alternative.AddUtilityTerm(97, homeKitWorkTRP);
            alternative.AddUtilityTerm(49, homeKitWorkNotKit);
            alternative.AddUtilityTerm(99, homeEastWorkCBD);
            alternative.AddUtilityTerm(100, homeKitWorkCBD);
        }
示例#2
0
        protected override void RegionSpecificCustomizations(ChoiceProbabilityCalculator.Alternative alternative, ITourWrapper tour, int pathType, int mode, IParcelWrapper destinationParcel)
        {
            //Global.PrintFile.WriteLine("Default PSRC_WorkTourModeModel.RegionSpecificCustomizations called");

            if (mode == Global.Settings.Modes.Transit && pathType != Global.Settings.PathTypes.LightRail && pathType != Global.Settings.PathTypes.CommuterRail && pathType != Global.Settings.PathTypes.Ferry)
            {
                if (tour.OriginParcel.District < 60)
                {
                    alternative.AddUtilityTerm(200 + tour.OriginParcel.District, 1);//district specific transit calibration constant
                }
                else
                {
                    alternative.AddUtilityTerm(200 + 6, 1);
                }

                if (destinationParcel.District < 60)
                {
                    alternative.AddUtilityTerm(300 + destinationParcel.District, 1);//district specific transit calibration constant
                }
                else
                {
                    alternative.AddUtilityTerm(300 + 6, 1);
                }
            }
        }
示例#3
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
            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(90, 100);

            //make oddball alt unavailable and remove nesting for estimation of conditional MNL
            //            alternative.Available = false;
            alternative.AddNestedAlternative(sampleSize + 3, 1, 98);
        }
        protected override void RegionSpecificOtherTourDistrictCoefficients(ChoiceProbabilityCalculator.Alternative alternative, ITourWrapper _tour, IParcelWrapper destinationParcel)
        {
            //add any region-specific new terms in region-specific class, using coefficient numbers 114-120, or other unused variable #
            //Global.PrintFile.WriteLine("Fresno_OtherTourDestinationModel.RegionSpecificOtherTourDistrictCoefficients called");
            int origdist = _tour.OriginParcel.District;
            //var destZone = destinationParcel.ZoneId;
            int destParcel = destinationParcel.Id;

            //var destRiverPark = (destZone == 514 || destZone == 515 || destZone == 516 || destZone == 1486 || destZone == 1487) ? 1 : 0;
            int destRiverPark         = (destParcel == 19599 || destParcel == 19600 || destParcel == 19601 || destParcel == 19598 || destParcel == 12156 || destParcel == 12158 || destParcel == 19603) ? 1 : 0;
            int origDistDestRiverPark = (origdist == 4 || origdist == 7 || origdist == 10) && (destParcel == 19599 || destParcel == 19600 || destParcel == 19601 || destParcel == 19598 || destParcel == 12156 || destParcel == 12158 || destParcel == 19603) ? 1 : 0;
            int origEastDestRiverPark = (origdist == 5) && (destParcel == 19599 || destParcel == 19600 || destParcel == 19601 || destParcel == 19598 || destParcel == 12156 || destParcel == 12158 || destParcel == 19603) ? 1 : 0;

            if (_tour.DestinationPurpose == Global.Settings.Purposes.Shopping || _tour.DestinationPurpose == Global.Settings.Purposes.Meal)
            {
                //Global.PrintFile.WriteLine("Destination is River Park Mall");
                alternative.AddUtilityTerm(115, destRiverPark);
                alternative.AddUtilityTerm(116, origDistDestRiverPark);
                alternative.AddUtilityTerm(117, origEastDestRiverPark);
            }

            //alternative.AddUtilityTerm(115, origEastDestCBD);
            //alternative.AddUtilityTerm(116, origKitDestTRP);
            //alternative.AddUtilityTerm(117, origTacDestKit);
            //alternative.AddUtilityTerm(118, origKitDestNotKit);
            //alternative.AddUtilityTerm(119, origSTacWorkCBD);
        }
示例#5
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.School, Global.Settings.TourPriorities.UsualLocation, Global.Settings.Modes.Sov, person.PersonType);
            DestinationSampler destinationSampler           = new DestinationSampler(choiceProbabilityCalculator, segment, sampleSize, choice, person.Household.ResidenceParcel);
            int destinationArrivalTime                      = ChoiceModelUtility.GetDestinationArrivalTime(Global.Settings.Models.SchoolTourModeModel);
            int destinationDepartureTime                    = ChoiceModelUtility.GetDestinationDepartureTime(Global.Settings.Models.SchoolTourModeModel);
            SchoolLocationUtilities schoolLocationUtilities = new SchoolLocationUtilities(person, sampleSize, destinationArrivalTime, destinationDepartureTime);

            destinationSampler.SampleTourDestinations(schoolLocationUtilities);

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

            // JLB 20120403 added third call parameter to idenitfy whether this alt is chosen or not
            ChoiceProbabilityCalculator.Alternative alternative = choiceProbabilityCalculator.GetAlternative(sampleSize, true, choseHome);

            alternative.Choice = person.Household.ResidenceParcel;

            alternative.AddUtilityTerm(50, 1);
            alternative.AddUtilityTerm(51, (!person.IsStudentAge).ToFlag());
            alternative.AddUtilityTerm(52, person.Household.Size);
            alternative.AddUtilityTerm(97, 1);   //new dummy size variable for oddball alt
            alternative.AddUtilityTerm(98, 100); //old dummy size variable for oddball alt

            //make oddball alt unavailable and remove nesting for estimation of conditional MNL
            //            alternative.Available = false;
            alternative.AddNestedAlternative(sampleSize + 3, 1, 99);
        }
示例#6
0
        protected override void RegionSpecificOtherTourDistrictCoefficients(ChoiceProbabilityCalculator.Alternative alternative, ITourWrapper _tour, IParcelWrapper destinationParcel)
        {
            //add any region-specific new terms in region-specific class, using coefficient numbers 114-120, or other unused variable #
            //Global.PrintFile.WriteLine("JAX_OtherTourDestinationModel.RegionSpecificOtherTourDistrictCoefficients called");
            double crossriver = ImpedanceRoster.GetValue("crossriver", Global.Settings.Modes.Sov, Global.Settings.PathTypes.FullNetwork, Global.Settings.ValueOfTimes.DefaultVot,
                                                         1, _tour.OriginParcel, destinationParcel).Variable;
            double intracounty = ImpedanceRoster.GetValue("intracounty", Global.Settings.Modes.Sov, Global.Settings.PathTypes.FullNetwork, Global.Settings.ValueOfTimes.DefaultVot,
                                                          1, _tour.OriginParcel, destinationParcel).Variable;


            if (_tour.DestinationPurpose == Global.Settings.Purposes.Escort)
            {
                alternative.AddUtilityTerm(114, crossriver);
            }
            else if (_tour.DestinationPurpose == Global.Settings.Purposes.PersonalBusiness || _tour.DestinationPurpose == Global.Settings.Purposes.Medical)
            {
                alternative.AddUtilityTerm(115, crossriver);
                alternative.AddUtilityTerm(119, intracounty);
            }
            else if (_tour.DestinationPurpose == Global.Settings.Purposes.Shopping)
            {
                alternative.AddUtilityTerm(116, crossriver);
                alternative.AddUtilityTerm(119, intracounty);
            }
            else if (_tour.DestinationPurpose == Global.Settings.Purposes.Meal)
            {
                alternative.AddUtilityTerm(117, crossriver);
                alternative.AddUtilityTerm(119, intracounty);
            }
            else if (_tour.DestinationPurpose == Global.Settings.Purposes.Social || _tour.DestinationPurpose == Global.Settings.Purposes.Recreation)
            {
                alternative.AddUtilityTerm(118, crossriver);
                alternative.AddUtilityTerm(119, intracounty);
            }
        }
示例#7
0
        protected override void RegionSpecificCustomizations(ChoiceProbabilityCalculator.Alternative alternative, IPersonWrapper _person, IParcelWrapper destinationParcel)
        {
            int origState = _person.Household.ResidenceParcel.District;
            int destState = destinationParcel.District;

            int bridgeFromNJ = (origState == 34 && destState > 0 && destState != 34).ToFlag();
            int bridgeToNJ   = (destState == 34 && origState > 0 && origState != 34).ToFlag();

            alternative.AddUtilityTerm(91, bridgeFromNJ);
            alternative.AddUtilityTerm(92, bridgeToNJ);
        }
示例#8
0
        protected override void RegionSpecificCustomizations(ChoiceProbabilityCalculator.Alternative alternative, IPersonWrapper _person, IParcelWrapper destinationParcel)
        {
            int homedist = _person.Household.ResidenceParcel.District;
            int zonedist = destinationParcel.District;

            //add any region-specific new terms in region-specific class, using coefficient numbers 91-97, 49, 99,100 or other unused variable #
            //Global.PrintFile.WriteLine("Default Fresno_WorkLocationModel.RegionSpecificCustomizations called");
            int homeNorthWorkSCBD = (homedist == 2 || homedist == 3 || homedist == 4 || homedist == 5 || homedist == 6 || homedist == 7) && (zonedist == 10) ? 1 : 0;
            int homeSCBDWorkSCBD  = homedist == 10 && (zonedist == 10) ? 1 : 0;

            alternative.AddUtilityTerm(91, homeNorthWorkSCBD);
            alternative.AddUtilityTerm(92, homeSCBDWorkSCBD);
        }
示例#9
0
        protected override void RegionSpecificOtherTourDistrictCoefficients(ChoiceProbabilityCalculator.Alternative alternative, ITourWrapper _tour, IParcelWrapper destinationParcel)
        {
            //add any region-specific new terms in region-specific class, using coefficient numbers 114-120, or other unused variable #

            int origState = _tour.OriginParcel.District;
            int destState = destinationParcel.District;

            int bridgeFromNJ = (origState == 34 && destState > 0 && destState != 34).ToFlag();
            int bridgeToNJ   = (destState == 34 && origState > 0 && origState != 34).ToFlag();

            alternative.AddUtilityTerm(114, bridgeFromNJ);
            alternative.AddUtilityTerm(115, bridgeToNJ);
        }
示例#10
0
        protected override void RegionSpecificCustomizations(ChoiceProbabilityCalculator.Alternative alternative, IHouseholdWrapper household)
        {
            //sfcta inserted special fields on the microzne file for residental parking - using unused properties
            double offStreetResidentParkingSpacesPerHH = household.ResidenceParcel.LandUseCode / Math.Max(household.ResidenceParcel.Households, 1);
            double onStreetResidentParkingSpacesPerHH  = household.ResidenceParcel.OpenSpaceType1Buffer2 / Math.Max(household.ResidenceParcel.HouseholdsBuffer2, 1);

            //put on each alternative except 3 (2 vehicles), using the alternative number to number coefficient
            if (alternative.Id != 3)
            {
                alternative.AddUtilityTerm(100 + alternative.Id, Math.Min(offStreetResidentParkingSpacesPerHH, 4));
                alternative.AddUtilityTerm(110 + alternative.Id, Math.Min(onStreetResidentParkingSpacesPerHH, 4));
                alternative.AddUtilityTerm(120 + alternative.Id, (offStreetResidentParkingSpacesPerHH * offStreetResidentParkingSpacesPerHH) > 0 ? 1 : 0);
            }
        }
        private void RunModel(ChoiceProbabilityCalculator choiceProbabilityCalculator, HouseholdDayWrapper householdDay, int[][] pfptSchedule, int[] choice = null)
        {
            //var householdDay = (ActumHouseholdDayWrapper)tour.HouseholdDay;
            Framework.DomainModels.Wrappers.IHouseholdWrapper household = householdDay.Household;

            //Generate utility funtions for the alternatives
            bool[] available = new bool[TOTAL_ALTERNATIVES + 1];
            bool[] chosen    = new bool[TOTAL_ALTERNATIVES + 1];
            for (int alt = 1; alt <= TOTAL_ALTERNATIVES; alt++)
            {
                available[alt] = false;
                chosen[alt]    = false;
                // set availability based on household CHILDREN
                if ((household.HasChildren && pfptSchedule[alt][0] == 1) || (!household.HasChildren && pfptSchedule[alt][0] == 0))
                {
                    available[alt] = true;
                }

                ChoiceProbabilityCalculator.Alternative alternative = choiceProbabilityCalculator.GetAlternative(alt - 1, available[alt], chosen[alt]);
                alternative.Choice = pfptSchedule[alt];

                // add utility terms for this alterative
                alternative.AddUtilityTerm(1, 1); // asc
            }
        }
示例#12
0
        protected override void RegionSpecificCustomizations(ChoiceProbabilityCalculator.Alternative alternative, IPersonWrapper _person, IParcelWrapper destinationParcel)
        {
            double intracounty = ImpedanceRoster.GetValue("intracounty", Global.Settings.Modes.Sov, Global.Settings.PathTypes.FullNetwork, Global.Settings.ValueOfTimes.DefaultVot,
                                                          1, _person.Household.ResidenceParcel, destinationParcel).Variable;

            alternative.AddUtilityTerm(45, intracounty);
        }
示例#13
0
        protected override void RegionSpecificWorkTourCustomCoefficients(ChoiceProbabilityCalculator.Alternative alternative, ITourWrapper _tour, IParcelWrapper destinationParcel, IPersonWrapper person)
        {
            //add any region-specific new terms in region-specific class, using coefficient numbers 114-120, or other unused variable #
            //Global.PrintFile.WriteLine("PSRC_OtherTourDestinationModel.RegionSpecificOtherTourDistrictCoefficients called");
            double distanceFromOrigin    = _tour.OriginParcel.DistanceFromOrigin(destinationParcel, _tour.DestinationArrivalTime);
            double distanceFromOriginLog = Math.Log(1 + distanceFromOrigin);

            alternative.AddUtilityTerm(100, person.WorksAtHome().ToFlag() * distanceFromOriginLog);
        }
示例#14
0
        protected override void RegionSpecificCustomizations(ChoiceProbabilityCalculator.Alternative alternative, ITourWrapper tour, int pathType, int mode, IParcelWrapper destinationParcel)
        {
            //Global.PrintFile.WriteLine("Default Fresno_WorkTourModeModel.RegionSpecificCustomizations called");

            if (mode == Global.Settings.Modes.Bike)
            {
                int origDist         = tour.OriginParcel.District;
                int destDist         = destinationParcel.District;
                int origCBDdestNorth = (origDist == 1) && (destDist > 1) && (destDist < 5) ? 1 : 0; //cbd to north districts
                int origNorthdestCBD = (origDist > 1) && (origDist < 5) && (destDist == 1) ? 1 : 0; //north districts to cbd

                alternative.AddUtilityTerm(201, origCBDdestNorth);
                alternative.AddUtilityTerm(301, origNorthdestCBD);

                //alternative.AddUtilityTerm(200 + tour.OriginParcel.District, 1);//district specific calibration constant
                //alternative.AddUtilityTerm(300 + destinationParcel.District, 1);//district specific calibration constant
            }
        }
示例#15
0
        protected override void RegionSpecificOtherTourDistrictCoefficients(ChoiceProbabilityCalculator.Alternative alternative, ITourWrapper _tour, IParcelWrapper destinationParcel)
        {
            //add any region-specific new terms in region-specific class, using coefficient numbers 114-120, or other unused variable #
            //Global.PrintFile.WriteLine("PSRC_OtherTourDestinationModel.RegionSpecificOtherTourDistrictCoefficients called");
            var origdist          = _tour.OriginParcel.District;
            var destdist          = destinationParcel.District;
            var origKitDestTRP    = (origdist == 9 || origdist == 11) && (destdist == 8 || destdist == 10 || destdist == 7) ? 1 : 0;
            var origEastDestCBD   = origdist == 6 && destdist == 4 ? 1 : 0;
            var origTacDestKit    = origdist == 8 && destdist == 9 || destdist == 11 ? 1 : 0;
            var origKitDestNotKit = (origdist == 9 || origdist == 11) && (destdist != 9 && destdist != 11) ? 1 : 0;
            var origSTacWorkCBD   = (origdist == 11 && destdist == 4) ? 1 : 0;

            alternative.AddUtilityTerm(115, origEastDestCBD);
            alternative.AddUtilityTerm(116, origKitDestTRP);
            alternative.AddUtilityTerm(117, origTacDestKit);
            alternative.AddUtilityTerm(118, origKitDestNotKit);
            alternative.AddUtilityTerm(119, origSTacWorkCBD);
        }
示例#16
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);
        }
示例#17
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.Settings.ValueOfTimes.DefaultVot,
                                                                 destinationArrivalTime, household.ResidenceParcel, person.UsualWorkParcel).Variable;
                    totalCommuteTime += ImpedanceRoster.GetValue("ivtime", Global.Settings.Modes.Sov, Global.Settings.PathTypes.FullNetwork, Global.Settings.ValueOfTimes.DefaultVot,
                                                                 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

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

            alternative.AddUtilityTerm(200, Global.Configuration.AV_AutoTypeConstant);
            alternative.AddUtilityTerm(200, Global.Configuration.AV_HHIncomeUnder50KCoefficient * household.HasIncomeUnder50K.ToFlag());
            alternative.AddUtilityTerm(200, Global.Configuration.AV_HHIncomeOver100KCoefficient * household.Has100KPlusIncome.ToFlag());
            alternative.AddUtilityTerm(200, Global.Configuration.AV_HHHeadUnder35Coefficient * (ageOfHouseholdHead < 35).ToFlag());
            alternative.AddUtilityTerm(200, Global.Configuration.AV_HHHeadOver65Coefficient * (ageOfHouseholdHead >= 65).ToFlag());
            alternative.AddUtilityTerm(200, Global.Configuration.AV_CoefficientPerHourCommuteTime * (totalCommuteTime / 60.0));

            // 2 not available

            alternative        = choiceProbabilityCalculator.GetAlternative(2, false, choice == 2);
            alternative.Choice = 2;

            // 3 not available

            alternative        = choiceProbabilityCalculator.GetAlternative(3, false, choice == 3);
            alternative.Choice = 3;


            // 4 not available

            alternative        = choiceProbabilityCalculator.GetAlternative(4, false, choice == 4);
            alternative.Choice = 4;
        }
        protected override void RegionSpecificOtherTourDistrictCoefficients(ChoiceProbabilityCalculator.Alternative alternative, ITourWrapper _tour, IParcelWrapper destinationParcel, IPersonWrapper person)
        {
            //add any region-specific new terms in region-specific class, using coefficient numbers 114-120, or other unused variable #
            //Global.PrintFile.WriteLine("PSRC_OtherTourDestinationModel.RegionSpecificOtherTourDistrictCoefficients called");
            int    origdist              = _tour.OriginParcel.District;
            int    destdist              = destinationParcel.District;
            int    origKitDestTRP        = (origdist == 9 || origdist == 11) && (destdist == 8 || destdist == 10 || destdist == 7) ? 1 : 0;
            int    origEastDestCBD       = origdist == 6 && destdist == 4 ? 1 : 0;
            int    origTacDestKit        = origdist == 8 && destdist == 9 || destdist == 11 ? 1 : 0;
            int    origKitDestNotKit     = (origdist == 9 || origdist == 11) && (destdist != 9 && destdist != 11) ? 1 : 0;
            int    origSTacWorkCBD       = (origdist == 11 && destdist == 4) ? 1 : 0;
            double distanceFromOrigin    = _tour.OriginParcel.DistanceFromOrigin(destinationParcel, _tour.DestinationArrivalTime);
            double distanceFromOriginLog = Math.Log(1 + distanceFromOrigin);

            alternative.AddUtilityTerm(114, person.WorksAtHome().ToFlag() * distanceFromOriginLog);
            alternative.AddUtilityTerm(115, origEastDestCBD);
            alternative.AddUtilityTerm(116, origKitDestTRP);
            alternative.AddUtilityTerm(117, origTacDestKit);
            alternative.AddUtilityTerm(118, origKitDestNotKit);
            alternative.AddUtilityTerm(119, origSTacWorkCBD);
        }
        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, 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]));
              }
            }
              }
            }
              }
        }
        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]));
                            }
                        }
                    }
                }
            }
        }
示例#22
0
        private void RunModel(ChoiceProbabilityCalculator choiceProbabilityCalculator, IHouseholdDayWrapper householdDay, ITourWrapper tour,
                              IParcelWrapper destinationParcel, int householdCars,
                              int constrainedMode, int constrainedArrivalTime, int constrainedDepartureTime, HTourModeTime choice = null)
        {
            IHouseholdWrapper household = tour.Household;
            IPersonWrapper    person    = tour.Person;
            IPersonDayWrapper personDay = tour.PersonDay;

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

            // household inputs
            int childrenUnder5         = householdTotals.ChildrenUnder5;
            int childrenAge5Through15  = householdTotals.ChildrenAge5Through15;
            int nonworkingAdults       = householdTotals.NonworkingAdults;
            int retiredAdults          = householdTotals.RetiredAdults;
            int onePersonHouseholdFlag = household.IsOnePersonHousehold.ToFlag();
            int twoPersonHouseholdFlag = household.IsTwoPersonHousehold.ToFlag();
            //var householdCars = household.VehiclesAvailable; MABADD now an input parameter
            int noCarsInHouseholdFlag   = household.GetFlagForNoCarsInHousehold(householdCars);
            int carsLessThanDriversFlag = household.GetFlagForCarsLessThanDrivers(householdCars);
            int carsLessThanWorkersFlag = household.GetFlagForCarsLessThanWorkers(householdCars);
            int income0To25KFlag        = household.Has0To25KIncome.ToFlag();
            int income100KPlusFlag      = household.Has100KPlusIncome.ToFlag();

            // person inputs
            int partTimeWorkerFlag     = person.IsPartTimeWorker.ToFlag();
            int nonworkingAdultFlag    = person.IsNonworkingAdult.ToFlag();
            int universityStudentFlag  = person.IsUniversityStudent.ToFlag();
            int retiredAdultFlag       = person.IsRetiredAdult.ToFlag();
            int drivingAgeStudentFlag  = person.IsDrivingAgeStudent.ToFlag();
            int fulltimeWorkerFlag     = person.IsFulltimeWorker.ToFlag();
            int childAge5Through15Flag = person.IsChildAge5Through15.ToFlag();
            int childUnder5Flag        = person.IsChildUnder5.ToFlag();
            int maleFlag              = person.IsMale.ToFlag();
            int ageUnder30Flag        = person.AgeIsLessThan30.ToFlag();
            int ageBetween51And98Flag = person.AgeIsBetween51And98.ToFlag();
            int adultFlag             = person.IsAdult.ToFlag();

            // person-day inputs
            int homeBasedToursOnlyFlag          = (personDay == null) ? 1 : personDay.OnlyHomeBasedToursExist().ToFlag();
            int firstSimulatedHomeBasedTourFlag = (personDay == null) ? 1 : personDay.IsFirstSimulatedHomeBasedTour().ToFlag();
            int laterSimulatedHomeBasedTourFlag = (personDay == null) ? 0 : personDay.IsLaterSimulatedHomeBasedTour().ToFlag();
            int totalStops              = (personDay == null) ? 0 : personDay.GetTotalStops();
            int totalSimulatedStops     = (personDay == null) ? 0 : personDay.GetTotalSimulatedStops();
            int escortStops             = (personDay == null) ? 0 : personDay.EscortStops;
            int homeBasedTours          = (personDay == null) ? 1 : personDay.HomeBasedTours;
            int simulatedHomeBasedTours = (personDay == null) ? 0 : personDay.SimulatedHomeBasedTours;

            // tour inputs
            int            escortTourFlag           = tour.IsEscortPurpose().ToFlag();
            int            shoppingTourFlag         = tour.IsShoppingPurpose().ToFlag();
            int            mealTourFlag             = tour.IsMealPurpose().ToFlag();
            int            socialTourFlag           = tour.IsSocialPurpose().ToFlag();
            int            personalBusinessTourFlag = tour.IsPersonalBusinessPurpose().ToFlag();
            int            recreationTourFlag       = tour.IsRecreationPurpose().ToFlag();
            int            medicalTourFlag          = tour.IsMedicalPurpose().ToFlag();
            IParcelWrapper originParcel             = tour.OriginParcel;
            //var destinationParcel = tour.DestinationParcel; MABADD now an input parameter
            int jointTourFlag        = (tour.JointTourSequence > 0) ? 1 : 0;
            int partialHalfTour1Flag = (tour.PartialHalfTour1Sequence > 0) ? 1 : 0;
            int partialHalfTour2Flag = (tour.PartialHalfTour2Sequence > 0) ? 1 : 0;
            int fullHalfTour1Flag    = (tour.FullHalfTour1Sequence > 0) ? 1 : 0;
            int fullHalfTour2Flag    = (tour.FullHalfTour2Sequence > 0) ? 1 : 0;
            int parentTourMode       = tour.ParentTour == null ? 0 : tour.ParentTour.Mode;


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

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

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

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

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


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


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

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

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

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

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

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

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


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

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

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

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

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

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

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



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

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

                    int mode = modeTimes.Mode;

                    int altIndex = modeTimes.Index;

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


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

                    alternative.Choice = modeTimes; // JLB added 20130420

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

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

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

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

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

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

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

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


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

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

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

                    //alternative.AddUtilityTerm(5,
                    //                           (maleFlag == 0 && mode == Global.Settings.Modes.Walk &&
                    //                            arrivalPeriod.Index >= DayPeriod.EVENING)
                    //                                   ? 1
                    //                                   : 0);
                    //    alternative.AddUtilityTerm(5,
                    //                               (maleFlag == 0 && mode == Global.Settings.Modes.Walk &&
                    //                                departurePeriod.Index >= DayPeriod.EVENING)
                    //                                   ? 1
                    //                                   : 0);
                }
            }
        }
        private void RunModel(ChoiceProbabilityCalculator choiceProbabilityCalculator, IPersonDayWrapper personDay, DayPattern choice = null)
        {
            IHouseholdWrapper household       = personDay.Household;
            IParcelWrapper    residenceParcel = household.ResidenceParcel;
            IPersonWrapper    person          = personDay.Person;

            int    carsPerDriver       = household.GetCarsPerDriver();
            double mixedDensity        = residenceParcel.MixedUse3Index2();
            double intersectionDensity = residenceParcel.IntersectionDensity34Minus1Buffer2();

            double[] purposeLogsums = new double[Global.Settings.Purposes.TotalPurposes];
            double[] atUsualLogsums = new double[3];
            int      carOwnership   = person.GetCarOwnershipSegment();
            int      votSegment     = person.Household.GetVotALSegment();
            int      transitAccess  = residenceParcel.TransitAccessSegment();

            if (person.UsualWorkParcel == null || person.UsualWorkParcelId == household.ResidenceParcelId)
            {
                purposeLogsums[Global.Settings.Purposes.Work] = 0;
            }
            else
            {
                int destinationArrivalTime   = ChoiceModelUtility.GetDestinationArrivalTime(Global.Settings.Models.WorkTourModeModel);
                int destinationDepartureTime = ChoiceModelUtility.GetDestinationDepartureTime(Global.Settings.Models.WorkTourModeModel);
                ChoiceProbabilityCalculator.Alternative nestedAlternative = Global.ChoiceModelSession.Get <WorkTourModeModel>().RunNested(personDay, residenceParcel, person.UsualWorkParcel, destinationArrivalTime, destinationDepartureTime, household.VehiclesAvailable);

                purposeLogsums[Global.Settings.Purposes.Work] = nestedAlternative == null ? 0 : nestedAlternative.ComputeLogsum();
                atUsualLogsums[Global.Settings.Purposes.Work] = Global.AggregateLogsums[person.UsualWorkParcel.ZoneId][Global.Settings.Purposes.HomeBasedComposite][carOwnership][votSegment][person.UsualWorkParcel.TransitAccessSegment()];
            }

            if (person.UsualSchoolParcel == null || person.UsualSchoolParcelId == household.ResidenceParcelId)
            {
                purposeLogsums[Global.Settings.Purposes.School] = 0;
            }
            else
            {
                int destinationArrivalTime   = ChoiceModelUtility.GetDestinationArrivalTime(Global.Settings.Models.SchoolTourModeModel);
                int destinationDepartureTime = ChoiceModelUtility.GetDestinationDepartureTime(Global.Settings.Models.SchoolTourModeModel);
                ChoiceProbabilityCalculator.Alternative nestedAlternative = Global.ChoiceModelSession.Get <SchoolTourModeModel>().RunNested(personDay, residenceParcel, person.UsualSchoolParcel, destinationArrivalTime, destinationDepartureTime, household.VehiclesAvailable);

                purposeLogsums[Global.Settings.Purposes.School] = nestedAlternative == null ? 0 : nestedAlternative.ComputeLogsum();
                atUsualLogsums[Global.Settings.Purposes.School] = Global.AggregateLogsums[person.UsualSchoolParcel.ZoneId][Global.Settings.Purposes.HomeBasedComposite][carOwnership][votSegment][person.UsualSchoolParcel.TransitAccessSegment()];
            }

            double compositeLogsum = Global.AggregateLogsums[household.ResidenceZoneId][Global.Settings.Purposes.HomeBasedComposite][carOwnership][votSegment][transitAccess];

            purposeLogsums[Global.Settings.Purposes.Escort]           = Global.AggregateLogsums[household.ResidenceZoneId][Global.Settings.Purposes.Escort][carOwnership][votSegment][transitAccess];
            purposeLogsums[Global.Settings.Purposes.PersonalBusiness] = Global.AggregateLogsums[household.ResidenceZoneId][Global.Settings.Purposes.PersonalBusiness][carOwnership][votSegment][transitAccess];
            purposeLogsums[Global.Settings.Purposes.Shopping]         = Global.AggregateLogsums[household.ResidenceZoneId][Global.Settings.Purposes.Shopping][carOwnership][votSegment][transitAccess];
            purposeLogsums[Global.Settings.Purposes.Meal]             = Global.AggregateLogsums[household.ResidenceZoneId][Global.Settings.Purposes.Meal][carOwnership][votSegment][transitAccess];
            purposeLogsums[Global.Settings.Purposes.Social]           = Global.AggregateLogsums[household.ResidenceZoneId][Global.Settings.Purposes.Social][carOwnership][votSegment][transitAccess];
            purposeLogsums[Global.Settings.Purposes.Recreation]       = compositeLogsum;
            purposeLogsums[Global.Settings.Purposes.Medical]          = compositeLogsum;

            for (int xPurpose = Global.Settings.Purposes.Work; xPurpose <= Global.Settings.Purposes.Social + 10; xPurpose++)
            {
                // extra components 1-5 are for 2,3,4,5,6 tour purposes
                // extra components 6-10 are for 2,3,4,5,6 stop puroposes

                // recode purpose to match coefficients
                int purpose = xPurpose <= Global.Settings.Purposes.Social ? xPurpose :
                              xPurpose <= Global.Settings.Purposes.Social + 5 ?
                              Global.Settings.Purposes.Social + 1 : Global.Settings.Purposes.Social + 2;

                // get correct multiplier on coefficients.
                double xMultiplier = xPurpose <= Global.Settings.Purposes.Social ? 1.0 :
                                     xPurpose <= Global.Settings.Purposes.Social + 5 ?
                                     Math.Log(xPurpose - Global.Settings.Purposes.Social + 1) : Math.Log(xPurpose - Global.Settings.Purposes.Social - 5 + 1);

                choiceProbabilityCalculator.CreateUtilityComponent(xPurpose);
                ChoiceProbabilityCalculator.Component component = choiceProbabilityCalculator.GetUtilityComponent(xPurpose);

                component.AddUtilityTerm(100 * purpose + 51, xMultiplier * person.IsFulltimeWorker.ToFlag());
                component.AddUtilityTerm(100 * purpose + 2, xMultiplier * person.IsPartTimeWorker.ToFlag());
                component.AddUtilityTerm(100 * purpose + 3, xMultiplier * person.IsRetiredAdult.ToFlag());
                component.AddUtilityTerm(100 * purpose + 4, xMultiplier * person.IsNonworkingAdult.ToFlag());
                component.AddUtilityTerm(100 * purpose + 5, xMultiplier * person.IsUniversityStudent.ToFlag());
                component.AddUtilityTerm(100 * purpose + 6, xMultiplier * person.IsDrivingAgeStudent.ToFlag());
                component.AddUtilityTerm(100 * purpose + 7, xMultiplier * person.IsChildAge5Through15.ToFlag());
                component.AddUtilityTerm(100 * purpose + 8, xMultiplier * person.IsChildUnder5.ToFlag());
                component.AddUtilityTerm(100 * purpose + 9, xMultiplier * household.Has0To25KIncome.ToFlag());
                component.AddUtilityTerm(100 * purpose + 10, xMultiplier * household.Has25To45KIncome.ToFlag());
                component.AddUtilityTerm(100 * purpose + 11, xMultiplier * household.Has75KPlusIncome.ToFlag());
                component.AddUtilityTerm(100 * purpose + 12, xMultiplier * carsPerDriver);
                component.AddUtilityTerm(100 * purpose + 13, xMultiplier * person.IsOnlyAdult().ToFlag());
                component.AddUtilityTerm(100 * purpose + 14, xMultiplier * person.IsOnlyFullOrPartTimeWorker().ToFlag());
                component.AddUtilityTerm(100 * purpose + 15, xMultiplier * 0);
                component.AddUtilityTerm(100 * purpose + 16, xMultiplier * person.IsFemale.ToFlag() * person.IsAdult.ToFlag() * (!household.HasChildrenUnder16).ToFlag());
                component.AddUtilityTerm(100 * purpose + 17, xMultiplier * person.IsFemale.ToFlag() * person.IsAdult.ToFlag() * household.HasChildrenUnder5.ToFlag());
                component.AddUtilityTerm(100 * purpose + 18, xMultiplier * person.IsFemale.ToFlag() * person.IsAdult.ToFlag() * household.HasChildrenAge5Through15.ToFlag());
                component.AddUtilityTerm(100 * purpose + 19, xMultiplier * person.IsMale.ToFlag() * person.IsAdult.ToFlag() * household.HasChildrenUnder5.ToFlag());
                component.AddUtilityTerm(100 * purpose + 20, xMultiplier * person.IsMale.ToFlag() * person.IsAdult.ToFlag() * household.HasChildrenAge5Through15.ToFlag());
                component.AddUtilityTerm(100 * purpose + 21, xMultiplier * person.AgeIsBetween18And25.ToFlag());
                component.AddUtilityTerm(100 * purpose + 22, xMultiplier * person.AgeIsBetween26And35.ToFlag());
                component.AddUtilityTerm(100 * purpose + 23, xMultiplier * person.AgeIsBetween51And65.ToFlag());
                component.AddUtilityTerm(100 * purpose + 24, xMultiplier * person.WorksAtHome().ToFlag());
                component.AddUtilityTerm(100 * purpose + 25, xMultiplier * mixedDensity);
                component.AddUtilityTerm(100 * purpose + 26, xMultiplier * intersectionDensity);
                component.AddUtilityTerm(100 * purpose + 27, xMultiplier * purposeLogsums[purpose]);
                component.AddUtilityTerm(100 * purpose + 28, xMultiplier * person.TransitPassOwnership);
            }

            // tour utility
            int tourComponentIndex = Global.Settings.Purposes.Social + 11;

            choiceProbabilityCalculator.CreateUtilityComponent(tourComponentIndex);
            ChoiceProbabilityCalculator.Component tourComponent = choiceProbabilityCalculator.GetUtilityComponent(tourComponentIndex);
            tourComponent.AddUtilityTerm(1401, carsPerDriver);
            tourComponent.AddUtilityTerm(1402, person.WorksAtHome().ToFlag());
            tourComponent.AddUtilityTerm(1403, mixedDensity);
            tourComponent.AddUtilityTerm(1404, mixedDensity * person.IsChildAge5Through15.ToFlag());
            tourComponent.AddUtilityTerm(1405, compositeLogsum);
            tourComponent.AddUtilityTerm(1406, person.TransitPassOwnership);

            // stop utility
            int stopComponentIndex = Global.Settings.Purposes.Social + 12;

            choiceProbabilityCalculator.CreateUtilityComponent(stopComponentIndex);
            ChoiceProbabilityCalculator.Component stopComponent = choiceProbabilityCalculator.GetUtilityComponent(stopComponentIndex);
            stopComponent.AddUtilityTerm(1411, carsPerDriver);
            stopComponent.AddUtilityTerm(1412, person.WorksAtHome().ToFlag());
            stopComponent.AddUtilityTerm(1413, mixedDensity);
            stopComponent.AddUtilityTerm(1414, mixedDensity * person.IsChildAge5Through15.ToFlag());
            stopComponent.AddUtilityTerm(1415, compositeLogsum);
            stopComponent.AddUtilityTerm(1416, person.TransitPassOwnership);

            for (int alternativeIndex = 0; alternativeIndex < TOTAL_ALTERNATIVES; alternativeIndex++)
            {
                DayPattern dayPattern = _dayPatterns[alternativeIndex];
                bool       available  =
                    // work tours and stops only available for workers
                    (person.IsWorker || (dayPattern.WorkTours <= 0 && dayPattern.WorkStops <= 0)) &&
                    // school tours and stops only available for students with usual school parcel not at home
                    ((person.IsStudent && person.UsualSchoolParcel != null && person.UsualSchoolParcel != person.Household.ResidenceParcel) || (dayPattern.SchoolTours <= 0 && dayPattern.SchoolStops <= 0)) &&
                    // school stops not available if usual school parcel is same as usual work parcel
                    ((person.IsStudent && person.UsualSchoolParcel != null && person.UsualSchoolParcel != person.UsualWorkParcel) || (dayPattern.SchoolStops <= 0));

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

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

                alternative.Choice = dayPattern;

                // components for the purposes
                for (int purpose = Global.Settings.Purposes.Work; purpose <= Global.Settings.Purposes.Social; purpose++)
                {
                    if (dayPattern.Tours[purpose] > 0 || dayPattern.Stops[purpose] > 0)
                    {
                        alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(purpose));

                        if (dayPattern.Tours[purpose] > 0)
                        {
                            alternative.AddUtilityTerm(100 * purpose, 1);                                  // tour purpose ASC
                            alternative.AddUtilityTerm(100 * purpose + 29, purposeLogsums[purpose]);       // tour purpose logsum
                            alternative.AddUtilityTerm(100 * purpose + 30, person.PaidParkingAtWorkplace); // only use for work purpose
                        }

                        if (dayPattern.Stops[purpose] > 0)
                        {
                            alternative.AddUtilityTerm(100 * purpose + 1, 1);                        // stop purpose ASC
                            alternative.AddUtilityTerm(100 * purpose + 31, purposeLogsums[purpose]); // stop purpose logsum
                        }
                        if (Global.Configuration.IsInEstimationMode)
                        {
                            alternative.AddUtilityTerm(100 * purpose + 32, 1 - person.PaperDiary);
                            alternative.AddUtilityTerm(100 * purpose + 33, person.ProxyResponse);
                        }
                    }
                }

                // multiple tour purposes component
                if (dayPattern.TotalTours > 1)
                {
                    alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(Global.Settings.Purposes.Social + (dayPattern.TotalTours - 1)));
                }

                // multiple stop purposes component
                if (dayPattern.TotalStops > 1)
                {
                    alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(Global.Settings.Purposes.Social + 5 + (dayPattern.TotalStops - 1)));
                }

                for (int tourPurpose = Global.Settings.Purposes.Work; tourPurpose <= Global.Settings.Purposes.Social; tourPurpose++)
                {
                    for (int stopPurpose = Global.Settings.Purposes.Work; stopPurpose <= Global.Settings.Purposes.Social - 1; stopPurpose++)
                    {
                        if (tourPurpose > Global.Settings.Purposes.School && stopPurpose <= Global.Settings.Purposes.School)
                        {
                            continue;
                        }

                        if (dayPattern.Tours[tourPurpose] > 0 && dayPattern.Stops[stopPurpose] > 0)
                        {
                            alternative.AddUtilityTerm(1000 + 10 * tourPurpose + stopPurpose, 1); // tour-stop comb. utility
                        }
                    }
                }

                for (int tourPurpose = Global.Settings.Purposes.Work; tourPurpose <= Global.Settings.Purposes.School; tourPurpose++)
                {
                    if (dayPattern.Tours[tourPurpose] == 1 && dayPattern.TotalStops >= 1)
                    {
                        alternative.AddUtilityTerm(1000 + 10 * tourPurpose, purposeLogsums[tourPurpose]);     // usual location logsum x presence of stops in work or school pattern
                        alternative.AddUtilityTerm(1000 + 10 * tourPurpose + 8, compositeLogsum);             // home aggregate logsum x  presence of stops in work or school pattern
                        alternative.AddUtilityTerm(1000 + 10 * tourPurpose + 9, atUsualLogsums[tourPurpose]); // at usual location aggregate logsum x  presence of stops in work or school pattern
                    }
                }

                for (int tourPurpose = Global.Settings.Purposes.Work; tourPurpose <= Global.Settings.Purposes.Social - 2; tourPurpose++)
                {
                    for (int tourPurpose2 = tourPurpose + 1; tourPurpose2 <= Global.Settings.Purposes.Social; tourPurpose2++)
                    {
                        if (dayPattern.Tours[tourPurpose] > 0 && dayPattern.Tours[tourPurpose2] > 0)
                        {
                            alternative.AddUtilityTerm(1100 + 10 * tourPurpose + tourPurpose2, 1); // tour-tour comb. utility
                        }
                    }
                }

                for (int stopPurpose = Global.Settings.Purposes.Work; stopPurpose <= Global.Settings.Purposes.Social - 2; stopPurpose++)
                {
                    for (int stopPurpose2 = stopPurpose + 1; stopPurpose2 <= Global.Settings.Purposes.Social; stopPurpose2++)
                    {
                        if (dayPattern.Stops[stopPurpose] > 0 && dayPattern.Stops[stopPurpose2] > 0)
                        {
                            alternative.AddUtilityTerm(1200 + 10 * stopPurpose + stopPurpose2, 1); // stop-stop comb. utility
                        }
                    }
                }

                if (dayPattern.TotalTours > 0 && dayPattern.TotalStops > 0)
                {
                    int totalStops = dayPattern.TotalStops;

                    if (totalStops > 3)
                    {
                        totalStops = 3;
                    }

                    alternative.AddUtilityTerm(1300 + 10 * dayPattern.TotalTours + totalStops, 1); // nttour-ntstop utility
                }
                if (dayPattern.TotalTours - dayPattern.Tours[Global.Settings.Purposes.Work] - dayPattern.Tours[Global.Settings.Purposes.School] > 0)
                {
                    // tour utility
                    alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(tourComponentIndex));
                }
                if (dayPattern.TotalStops - dayPattern.Stops[Global.Settings.Purposes.Work] - dayPattern.Stops[Global.Settings.Purposes.School] > 0)
                {
                    // stop utility
                    alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(stopComponentIndex));
                }
            }
        }
        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);
        }
        private void RunModel(ChoiceProbabilityCalculator choiceProbabilityCalculator, HouseholdDayWrapper householdDay, int jHTSimulated, int genChoice, int[] participants, int choice = Constants.DEFAULT_VALUE)
        {
            IEnumerable <PersonDayWrapper> orderedPersonDays = householdDay.PersonDays.OrderBy(p => p.GetJointHalfTourParticipationPriority()).ToList().Cast <PersonDayWrapper>();

            int pairedHalfTour = genChoice == 1 ? 1 : 0;
            int firstHalfTour  = genChoice == 2 ? 1 : 0;
            int secondHalfTour = genChoice == 3 ? 1 : 0;

            int[,] pType = new int[9, 6];
            int[] pDrivingAge = new int[6];

            int count = 0;

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

            //Generate utility funtions for the alternatives
            bool[] available = new bool[5];
            bool[] chosen    = new bool[5];
            int    alt       = 0;

            for (int i = 0; i < 5; i++)
            {
                alt          = i + 1;
                available[i] = false;
                chosen[i]    = false;

                // set availability based on participation in tour
                if (participants[alt] == 1)
                {
                    available[i] = true;
                }
                // restrict availability if person is not driving age
                if (pDrivingAge[alt] == 0)
                {
                    available[i] = false;
                }

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

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

                alternative.Choice = alt;

                //Add utility terms
                alternative.AddUtilityTerm(1, pType[1, alt] * firstHalfTour);
                alternative.AddUtilityTerm(2, pType[2, alt] * firstHalfTour);
                alternative.AddUtilityTerm(5, pType[5, alt] * firstHalfTour);
                alternative.AddUtilityTerm(6, pType[6, alt] * firstHalfTour);

                alternative.AddUtilityTerm(11, pType[1, alt] * secondHalfTour);
                alternative.AddUtilityTerm(12, pType[2, alt] * secondHalfTour);
                alternative.AddUtilityTerm(15, pType[5, alt] * secondHalfTour);
                alternative.AddUtilityTerm(16, pType[6, alt] * secondHalfTour);

                alternative.AddUtilityTerm(21, pType[1, alt] * pairedHalfTour);
                alternative.AddUtilityTerm(22, pType[2, alt] * pairedHalfTour);
                alternative.AddUtilityTerm(25, pType[5, alt] * pairedHalfTour);
                alternative.AddUtilityTerm(26, pType[6, alt] * pairedHalfTour);
            }
        }
示例#26
0
        protected override void RegionSpecificOtherTourDistrictCoefficients(ChoiceProbabilityCalculator.Alternative alternative, ITourWrapper _tour, IParcelWrapper destinationParcel, IPersonWrapper person)
        {
            //add any region-specific new terms in region-specific class, using coefficient numbers 114-120, or other unused variable #
            //Global.PrintFile.WriteLine("PSRC_OtherTourDestinationModel.RegionSpecificOtherTourDistrictCoefficients called");
            int origdist          = _tour.OriginParcel.District;
            int destdist          = destinationParcel.District;
            int origKitDestTRP    = (origdist == 9 || origdist == 11) && (destdist == 8 || destdist == 10 || destdist == 7) ? 1 : 0;
            int origEastDestCBD   = origdist >= 60 && origdist <= 65 && destdist == 4 ? 1 : 0;
            int origTacDestKit    = origdist == 8 && destdist == 9 || destdist == 11 ? 1 : 0;
            int origKitDestNotKit = (origdist == 9 || origdist == 11) && (destdist != 9 && destdist != 11) ? 1 : 0;
            int origSTacWorkCBD   = (origdist == 11 && destdist == 4) ? 1 : 0;

            alternative.AddUtilityTerm(115, origEastDestCBD);
            alternative.AddUtilityTerm(116, origKitDestTRP);
            alternative.AddUtilityTerm(117, origTacDestKit);
            alternative.AddUtilityTerm(118, origKitDestNotKit);
            alternative.AddUtilityTerm(119, origSTacWorkCBD);


            // Below is BKR customization
            //Global.PrintFile.WriteLine("Default BKR_OtherHomeBasedTourModeModel.RegionSpecificCustomizations2 called");
            if (_tour.IsShoppingPurpose() && (_tour.Mode == Global.Settings.Modes.Sov || _tour.Mode == Global.Settings.Modes.Hov2 || _tour.Mode == Global.Settings.Modes.Hov3))
            {
                if (destinationParcel.District == 62 && _tour.OriginParcel.District != 62)
                {
                    alternative.AddUtilityTerm(120, 1);
                }
            }
            if (_tour.IsMealPurpose() && (_tour.Mode == Global.Settings.Modes.Sov || _tour.Mode == Global.Settings.Modes.Hov2 || _tour.Mode == Global.Settings.Modes.Hov3))
            {
                if (destinationParcel.District == 62 && _tour.OriginParcel.District != 62)
                {
                    alternative.AddUtilityTerm(121, 1);
                }
            }
            if (_tour.IsPersonalBusinessPurpose() && (_tour.Mode == Global.Settings.Modes.Sov || _tour.Mode == Global.Settings.Modes.Hov2 || _tour.Mode == Global.Settings.Modes.Hov3))
            {
                if (destinationParcel.District == 62 && _tour.OriginParcel.District != 62)
                {
                    alternative.AddUtilityTerm(122, 1);
                }
            }
            if (_tour.IsSocialPurpose() && (_tour.Mode == Global.Settings.Modes.Sov || _tour.Mode == Global.Settings.Modes.Hov2 || _tour.Mode == Global.Settings.Modes.Hov3))
            {
                if (destinationParcel.District == 62 && _tour.OriginParcel.District != 62)
                {
                    alternative.AddUtilityTerm(123, 1);
                }
            }
            if (_tour.IsEscortPurpose() && (_tour.Mode == Global.Settings.Modes.Sov || _tour.Mode == Global.Settings.Modes.Hov2 || _tour.Mode == Global.Settings.Modes.Hov3))
            {
                if (destinationParcel.District == 62 && _tour.OriginParcel.District != 62)
                {
                    alternative.AddUtilityTerm(124, 1);
                }
            }

            // to Belleuve Square from outside of Bel CBD
            // even thoug the zoneid is clearly labeled, it is zero-based. that means if you want to reference a TAZ nunber, you need to use TAZ number - 1 in ZoneId.
            // in this case, Bellevue Square is in TAZ 11. its ZoneId in destinationParcel is 10.
            if (destinationParcel.ZoneId == 10 && origdist != 62)
            {
                alternative.AddUtilityTerm(125, 1);
            }
        }
示例#27
0
            public void SetUtilities(ISampleItem sampleItem, int sampleFrequency)
            {
                if (sampleItem == null)
                {
                    throw new ArgumentNullException("sampleItem");
                }

                ChoiceProbabilityCalculator.Alternative alternative = sampleItem.Alternative;

                if (!alternative.Available)
                {
                    return;
                }

                IHouseholdWrapper household = _tour.Household;
                IPersonWrapper    person    = _tour.Person;
                //var personDay = _tour.PersonDay;
                bool householdHasChildren   = household.HasChildren;
                bool householdHasNoChildren = householdHasChildren ? false : true;

                IParcelWrapper destinationParcel = ChoiceModelFactory.Parcels[sampleItem.ParcelId];


                int jointTourFlag = (_tour.JointTourSequence > 0).ToFlag();


                double fastestTravelTime =
                    ImpedanceRoster.GetValue("ivtime", Global.Settings.Modes.Hov3, Global.Settings.PathTypes.FullNetwork, Global.Settings.ValueOfTimes.DefaultVot, _fastestAvailableTimeOfDay, _tour.OriginParcel, destinationParcel).Variable +
                    ImpedanceRoster.GetValue("ivtime", Global.Settings.Modes.Hov3, Global.Settings.PathTypes.FullNetwork, Global.Settings.ValueOfTimes.DefaultVot, _fastestAvailableTimeOfDay, destinationParcel, _tour.OriginParcel).Variable;

                if (fastestTravelTime >= _maxAvailableMinutes)
                {
                    alternative.Available = false;

                    return;
                }

                alternative.Choice = destinationParcel;

                //double tourLogsum = 0;
                double jointTourLogsum = 0;
                double workTourLogsum  = 0;
                double otherTourLogsum = 0;
                double subtourLogsum   = 0;

                if (_tour.IsHomeBasedTour)
                {
                    if (_tour.DestinationPurpose == Global.Settings.Purposes.Work)
                    {
                        //var destinationArrivalTime = ChoiceModelUtility.GetDestinationArrivalTime(Global.Settings.Models.WorkTourModeModel);
                        //var destinationDepartureTime = ChoiceModelUtility.GetDestinationDepartureTime(Global.Settings.Models.WorkTourModeModel);
                        ChoiceProbabilityCalculator.Alternative nestedAlternative = Global.ChoiceModelSession.Get <WorkTourModeTimeModel>().RunNested(_tour, destinationParcel, _tour.Household.VehiclesAvailable, _tour.Person.GetTransitFareDiscountFraction());
                        workTourLogsum = nestedAlternative == null ? 0 : nestedAlternative.ComputeLogsum();
                    }
                    //                    else if (_tour.DestinationPurpose == Global.Settings.Purposes.Escort) {
                    //                        var nestedAlternative = (Global.ChoiceModelDictionary.Get("HEscortTourModeModel") as HEscortTourModeModel).RunNested(_tour, destinationParcel);
                    //                        tourLogsum = nestedAlternative == null ? 0 : nestedAlternative.ComputeLogsum();
                    //                    }
                    else
                    {
                        ChoiceProbabilityCalculator.Alternative nestedAlternative = Global.ChoiceModelSession.Get <OtherHomeBasedTourModeTimeModel>().RunNested(_tour, destinationParcel, _tour.Household.VehiclesAvailable, _tour.Person.GetTransitFareDiscountFraction());
                        if (_tour.JointTourSequence > 0)
                        {
                            jointTourLogsum = nestedAlternative == null ? 0 : nestedAlternative.ComputeLogsum();
                        }
                        else
                        {
                            otherTourLogsum = nestedAlternative == null ? 0 : nestedAlternative.ComputeLogsum();
                        }
                    }
                }
                else
                {
                    ChoiceProbabilityCalculator.Alternative nestedAlternative = Global.ChoiceModelSession.Get <WorkBasedSubtourModeTimeModel>().RunNested(_tour, destinationParcel, _tour.Household.VehiclesAvailable, _tour.Person.GetTransitFareDiscountFraction());
                    subtourLogsum = nestedAlternative == null ? 0 : nestedAlternative.ComputeLogsum();
                }

                //var purpose = _tour.TourPurposeSegment;
                //var carOwnership = person.CarOwnershipSegment;
                //var votSegment = _tour.VotALSegment;
                //var transitAccess = destinationParcel.TransitAccessSegment();
                //var aggregateLogsum = Global.AggregateLogsums[destinationParcel.ZoneId][purpose][carOwnership][votSegment][transitAccess];
                //var aggregateLogsumHomeBased = Global.AggregateLogsums[destinationParcel.ZoneId][Global.Settings.Purposes.HomeBasedComposite][carOwnership][votSegment][transitAccess];
                //var aggregateLogsumWorkBased = Global.AggregateLogsums[destinationParcel.ZoneId][Global.Settings.Purposes.Work_BASED][carOwnership][votSegment][transitAccess];

                double distanceFromOrigin = _tour.OriginParcel.DistanceFromOrigin(destinationParcel, _tour.DestinationArrivalTime);
                double piecewiseDistanceFrom5To10Miles         = Math.Max(0, Math.Min(distanceFromOrigin - .5, 1 - .5));
                double piecewiseDistanceFrom10MilesToInfinity  = Math.Max(0, distanceFromOrigin - 1);
                double piecewiseDistanceFrom0To1Mile           = Math.Min(distanceFromOrigin, .10);
                double piecewiseDistanceFrom1To5Miles          = Math.Max(0, Math.Min(distanceFromOrigin - .1, .5 - .1));
                double piecewiseDistanceFrom1To3AndAHalfMiles  = Math.Max(0, Math.Min(distanceFromOrigin - .1, .35 - .1));
                double piecewiseDistanceFrom3AndAHalfTo10Miles = Math.Max(0, Math.Min(distanceFromOrigin - .35, 1 - .35));
                double distanceFromOriginLog = Math.Log(1 + distanceFromOrigin);
                //var distanceFromWorkLog = person.UsualWorkParcel.DistanceFromWorkLog(destinationParcel, 1);
                double distanceFromSchoolLog = person.UsualSchoolParcel.DistanceFromSchoolLog(destinationParcel, 1);

                double timePressure = Math.Log(1 - fastestTravelTime / _maxAvailableMinutes);

                // log transforms of buffers for Neighborhood effects
                double logOfOnePlusEmploymentEducationBuffer1  = Math.Log(destinationParcel.EmploymentEducationBuffer1 + 1.0);
                double logOfOnePlusEmploymentFoodBuffer1       = Math.Log(destinationParcel.EmploymentFoodBuffer1 + 1.0);
                double logOfOnePlusEmploymentGovernmentBuffer1 = Math.Log(destinationParcel.EmploymentGovernmentBuffer1 + 1.0);
                double logOfOnePlusEmploymentOfficeBuffer1     = Math.Log(destinationParcel.EmploymentOfficeBuffer1 + 1.0);
                double logOfOnePlusEmploymentRetailBuffer1     = Math.Log(destinationParcel.EmploymentRetailBuffer1 + 1.0);
                double logOfOnePlusEmploymentServiceBuffer1    = Math.Log(destinationParcel.EmploymentServiceBuffer1 + 1.0);
                double logOfOnePlusEmploymentMedicalBuffer1    = Math.Log(destinationParcel.EmploymentMedicalBuffer1 + 1.0);
                double logOfOnePlusEmploymentIndustrial_Ag_ConstructionBuffer1 = Math.Log(destinationParcel.EmploymentIndustrialBuffer1 + destinationParcel.EmploymentAgricultureConstructionBuffer1 + 1.0);
                double logOfOnePlusEmploymentTotalBuffer1    = Math.Log(destinationParcel.EmploymentTotalBuffer1 + 1.0);
                double logOfOnePlusHouseholdsBuffer1         = Math.Log(destinationParcel.HouseholdsBuffer1 + 1.0);
                double logOfOnePlusStudentsK12Buffer1        = Math.Log(destinationParcel.StudentsK8Buffer1 + destinationParcel.StudentsHighSchoolBuffer1 + 1.0);
                double logOfOnePlusStudentsUniversityBuffer1 = Math.Log(destinationParcel.StudentsUniversityBuffer1 + 1.0);

                //                var EMPHOU_B = Math.Log(destinationParcel.EmploymentTotalBuffer1 + destinationParcel.HouseholdsBuffer1 + 1.0);

                //var logOfOnePlusParkingOffStreetDailySpacesBuffer1 = Math.Log(1 + destinationParcel.ParkingOffStreetPaidDailySpacesBuffer1);
                // connectivity attributes
                //var c34Ratio = destinationParcel.C34RatioBuffer1();

                //var carCompetitionFlag = FlagUtility.GetCarCompetitionFlag(carOwnership); // exludes no cars
                //var noCarCompetitionFlag = FlagUtility.GetNoCarCompetitionFlag(carOwnership);
                //var noCarsFlag = FlagUtility.GetNoCarsFlag(carOwnership);

                alternative.AddUtilityTerm(2, sampleItem.AdjustmentFactor);
                alternative.AddUtilityTerm(3, workTourLogsum);
                alternative.AddUtilityTerm(4, otherTourLogsum);
                alternative.AddUtilityTerm(5, jointTourLogsum);
                alternative.AddUtilityTerm(6, subtourLogsum);

                //subpopulation-specific terms
                //alternative.AddUtilityTerm(260, _secondaryFlag * _workOrSchoolPatternFlag * piecewiseDistanceFrom0To1Mile);
                //alternative.AddUtilityTerm(261, _secondaryFlag * _workOrSchoolPatternFlag * piecewiseDistanceFrom1To5Miles);
                //alternative.AddUtilityTerm(262, _secondaryFlag * _workOrSchoolPatternFlag * piecewiseDistanceFrom5To10Miles);
                //alternative.AddUtilityTerm(263, _secondaryFlag * _workOrSchoolPatternFlag * piecewiseDistanceFrom10MilesToInfinity);
                alternative.AddUtilityTerm(260, _secondaryFlag * _workOrSchoolPatternFlag * distanceFromOriginLog);
                //alternative.AddUtilityTerm(264, _secondaryFlag * _otherPatternFlag * piecewiseDistanceFrom0To1Mile);
                //alternative.AddUtilityTerm(265, _secondaryFlag * _otherPatternFlag * piecewiseDistanceFrom1To5Miles);
                //alternative.AddUtilityTerm(266, _secondaryFlag * _otherPatternFlag * piecewiseDistanceFrom5To10Miles);
                //alternative.AddUtilityTerm(267, _secondaryFlag * _otherPatternFlag * piecewiseDistanceFrom10MilesToInfinity);
                alternative.AddUtilityTerm(264, _secondaryFlag * _otherPatternFlag * distanceFromOriginLog);

                alternative.AddUtilityTerm(268, (!_tour.IsHomeBasedTour).ToFlag() * distanceFromOriginLog);
                //alternative.AddUtilityTerm(269, household.Has0To15KIncome.ToFlag() * distanceFromOriginLog);
                //alternative.AddUtilityTerm(270, household.HasMissingIncome.ToFlag() * distanceFromOriginLog);
                //alternative.AddUtilityTerm(271, person.IsRetiredAdult.ToFlag() * distanceFromOriginLog);
                //alternative.AddUtilityTerm(272, person.IsUniversityStudent.ToFlag() * distanceFromOriginLog);
                alternative.AddUtilityTerm(273, person.IsChildAge5Through15.ToFlag() * distanceFromOriginLog);
                //alternative.AddUtilityTerm(274, person.IsChildUnder5.ToFlag() * distanceFromOriginLog);

                alternative.AddUtilityTerm(275, (_tour.IsHomeBasedTour).ToFlag() * timePressure);
                alternative.AddUtilityTerm(276, (_tour.IsHomeBasedTour).ToFlag() * distanceFromSchoolLog);
                //alternative.AddUtilityTerm(14, distanceFromWorkLog);

                //alternative.AddUtilityTerm(277, (carCompetitionFlag + noCarCompetitionFlag) * destinationParcel.ParkingHourlyEmploymentCommercialMixInParcel());
                //alternative.AddUtilityTerm(278, noCarCompetitionFlag * destinationParcel.ParkingHourlyEmploymentCommercialMixInParcel());
                //alternative.AddUtilityTerm(279, carCompetitionFlag * destinationParcel.ParkingHourlyEmploymentCommercialMixBuffer1());
                //alternative.AddUtilityTerm(280, noCarCompetitionFlag * destinationParcel.ParkingHourlyEmploymentCommercialMixBuffer1());

                //alternative.AddUtilityTerm(281, noCarsFlag * c34Ratio);
                //alternative.AddUtilityTerm(282, noCarCompetitionFlag * c34Ratio);
                //alternative.AddUtilityTerm(283, (carCompetitionFlag + noCarCompetitionFlag) * logOfOnePlusParkingOffStreetDailySpacesBuffer1);

                alternative.AddUtilityTerm(284, jointTourFlag * piecewiseDistanceFrom0To1Mile);
                alternative.AddUtilityTerm(285, jointTourFlag * piecewiseDistanceFrom1To5Miles);
                alternative.AddUtilityTerm(286, jointTourFlag * piecewiseDistanceFrom5To10Miles);
                alternative.AddUtilityTerm(287, jointTourFlag * piecewiseDistanceFrom10MilesToInfinity);

                if (_tour.DestinationPurpose == Global.Settings.Purposes.Work)
                {
                    alternative.AddUtilityTerm(10, piecewiseDistanceFrom0To1Mile);
                    alternative.AddUtilityTerm(11, piecewiseDistanceFrom1To3AndAHalfMiles);
                    alternative.AddUtilityTerm(12, piecewiseDistanceFrom3AndAHalfTo10Miles);
                    alternative.AddUtilityTerm(13, piecewiseDistanceFrom10MilesToInfinity);
                    //alternative.AddUtilityTerm(14, aggregateLogsumWorkBased);

                    // Neighborhood
                    alternative.AddUtilityTerm(20, logOfOnePlusEmploymentEducationBuffer1);
                    //alternative.AddUtilityTerm(21, logOfOnePlusEmploymentGovernmentBuffer1);
                    alternative.AddUtilityTerm(22, logOfOnePlusEmploymentOfficeBuffer1);
                    //alternative.AddUtilityTerm(23, logOfOnePlusEmploymentServiceBuffer1);
                    alternative.AddUtilityTerm(24, logOfOnePlusEmploymentMedicalBuffer1);
                    alternative.AddUtilityTerm(25, logOfOnePlusHouseholdsBuffer1);
                    alternative.AddUtilityTerm(26, logOfOnePlusStudentsUniversityBuffer1);
                    alternative.AddUtilityTerm(27, logOfOnePlusStudentsK12Buffer1);
                    alternative.AddUtilityTerm(28, logOfOnePlusEmploymentIndustrial_Ag_ConstructionBuffer1);

                    // Size terms
                    alternative.AddUtilityTerm(30, destinationParcel.EmploymentEducation);
                    alternative.AddUtilityTerm(31, destinationParcel.EmploymentFood);
                    alternative.AddUtilityTerm(32, destinationParcel.EmploymentGovernment);
                    alternative.AddUtilityTerm(33, destinationParcel.EmploymentOffice);
                    alternative.AddUtilityTerm(34, destinationParcel.EmploymentRetail);
                    alternative.AddUtilityTerm(35, destinationParcel.EmploymentService);
                    alternative.AddUtilityTerm(36, destinationParcel.EmploymentMedical);
                    alternative.AddUtilityTerm(37, destinationParcel.EmploymentIndustrial + destinationParcel.EmploymentAgricultureConstruction);
                    alternative.AddUtilityTerm(38, destinationParcel.Households);
                    alternative.AddUtilityTerm(39, destinationParcel.GetStudentsK12());
                    //(for application) alternative.AddUtilityTerm(40, destinationParcel.StudentsUniversity);
                }
                else if (_tour.DestinationPurpose == Global.Settings.Purposes.Escort)
                {
                    alternative.AddUtilityTerm(50, piecewiseDistanceFrom0To1Mile);
                    alternative.AddUtilityTerm(51, piecewiseDistanceFrom1To3AndAHalfMiles);
                    alternative.AddUtilityTerm(52, piecewiseDistanceFrom3AndAHalfTo10Miles);
                    alternative.AddUtilityTerm(53, piecewiseDistanceFrom10MilesToInfinity);
                    //alternative.AddUtilityTerm(54, aggregateLogsumHomeBased);

                    // Neighborhood
                    alternative.AddUtilityTerm(60, householdHasNoChildren.ToFlag() * logOfOnePlusEmploymentGovernmentBuffer1);
                    alternative.AddUtilityTerm(61, householdHasNoChildren.ToFlag() * logOfOnePlusHouseholdsBuffer1);
                    //alternative.AddUtilityTerm(62, householdHasChildren.ToFlag() * logOfOnePlusHouseholdsBuffer1);
                    alternative.AddUtilityTerm(63, householdHasChildren.ToFlag() * logOfOnePlusStudentsK12Buffer1);
                    alternative.AddUtilityTerm(64, logOfOnePlusEmploymentTotalBuffer1);

                    // Size terms
                    alternative.AddUtilityTerm(70, (!householdHasChildren).ToFlag() * destinationParcel.EmploymentEducation);
                    alternative.AddUtilityTerm(71, (!householdHasChildren).ToFlag() * destinationParcel.EmploymentFood);
                    alternative.AddUtilityTerm(72, (!householdHasChildren).ToFlag() * destinationParcel.EmploymentGovernment);
                    alternative.AddUtilityTerm(73, (!householdHasChildren).ToFlag() * destinationParcel.EmploymentOffice);
                    alternative.AddUtilityTerm(74, (!householdHasChildren).ToFlag() * destinationParcel.EmploymentRetail);
                    alternative.AddUtilityTerm(75, (!householdHasChildren).ToFlag() * destinationParcel.EmploymentService);
                    alternative.AddUtilityTerm(76, (!householdHasChildren).ToFlag() * destinationParcel.EmploymentMedical);
                    alternative.AddUtilityTerm(77, (!householdHasChildren).ToFlag() * (destinationParcel.EmploymentIndustrial + destinationParcel.EmploymentAgricultureConstruction));
                    alternative.AddUtilityTerm(78, (!householdHasChildren).ToFlag() * destinationParcel.Households);
                    alternative.AddUtilityTerm(79, (!householdHasChildren).ToFlag() * destinationParcel.GetStudentsK12());

                    alternative.AddUtilityTerm(80, householdHasChildren.ToFlag() * destinationParcel.EmploymentEducation);
                    alternative.AddUtilityTerm(81, householdHasChildren.ToFlag() * destinationParcel.EmploymentFood);
                    alternative.AddUtilityTerm(82, householdHasChildren.ToFlag() * destinationParcel.EmploymentGovernment);
                    alternative.AddUtilityTerm(83, householdHasChildren.ToFlag() * destinationParcel.EmploymentOffice);
                    alternative.AddUtilityTerm(84, householdHasChildren.ToFlag() * destinationParcel.EmploymentRetail);
                    alternative.AddUtilityTerm(85, householdHasChildren.ToFlag() * destinationParcel.EmploymentService);
                    alternative.AddUtilityTerm(86, householdHasChildren.ToFlag() * destinationParcel.EmploymentMedical);
                    alternative.AddUtilityTerm(87, householdHasChildren.ToFlag() * (destinationParcel.EmploymentIndustrial + destinationParcel.EmploymentAgricultureConstruction));
                    alternative.AddUtilityTerm(88, householdHasChildren.ToFlag() * destinationParcel.Households);
                    alternative.AddUtilityTerm(89, householdHasChildren.ToFlag() * destinationParcel.GetStudentsK12());
                }
                else if (_tour.DestinationPurpose == Global.Settings.Purposes.PersonalBusiness)
                {
                    alternative.AddUtilityTerm(90, piecewiseDistanceFrom0To1Mile);
                    alternative.AddUtilityTerm(91, piecewiseDistanceFrom1To3AndAHalfMiles);
                    alternative.AddUtilityTerm(92, piecewiseDistanceFrom3AndAHalfTo10Miles);
                    alternative.AddUtilityTerm(93, piecewiseDistanceFrom10MilesToInfinity);
                    //alternative.AddUtilityTerm(94, aggregateLogsumHomeBased);

                    // Neighborhood
                    alternative.AddUtilityTerm(100, logOfOnePlusEmploymentEducationBuffer1);
                    alternative.AddUtilityTerm(101, logOfOnePlusEmploymentOfficeBuffer1);
                    //alternative.AddUtilityTerm(102, logOfOnePlusEmploymentServiceBuffer1);
                    //alternative.AddUtilityTerm(103, logOfOnePlusEmploymentMedicalBuffer1);
                    alternative.AddUtilityTerm(104, logOfOnePlusHouseholdsBuffer1);
                    //alternative.AddUtilityTerm(105, logOfOnePlusStudentsUniversityBuffer1);
                    alternative.AddUtilityTerm(106, logOfOnePlusEmploymentGovernmentBuffer1);
                    alternative.AddUtilityTerm(107, logOfOnePlusEmploymentRetailBuffer1);

                    // Size terms
                    alternative.AddUtilityTerm(110, destinationParcel.EmploymentEducation);
                    alternative.AddUtilityTerm(111, destinationParcel.EmploymentFood);
                    alternative.AddUtilityTerm(112, destinationParcel.EmploymentGovernment);
                    alternative.AddUtilityTerm(113, destinationParcel.EmploymentOffice);
                    alternative.AddUtilityTerm(114, destinationParcel.EmploymentRetail);
                    alternative.AddUtilityTerm(115, destinationParcel.EmploymentService);
                    alternative.AddUtilityTerm(116, destinationParcel.EmploymentMedical);
                    alternative.AddUtilityTerm(117, destinationParcel.EmploymentIndustrial + destinationParcel.EmploymentAgricultureConstruction);
                    alternative.AddUtilityTerm(118, destinationParcel.Households);
                    //(for application) alternative.AddUtilityTerm(119, destinationParcel.GetStudentsK12());
                }
                else if (_tour.DestinationPurpose == Global.Settings.Purposes.Shopping)
                {
                    alternative.AddUtilityTerm(120, piecewiseDistanceFrom0To1Mile);
                    alternative.AddUtilityTerm(121, piecewiseDistanceFrom1To3AndAHalfMiles);
                    alternative.AddUtilityTerm(122, piecewiseDistanceFrom3AndAHalfTo10Miles);
                    alternative.AddUtilityTerm(123, piecewiseDistanceFrom10MilesToInfinity);
                    //alternative.AddUtilityTerm(124, aggregateLogsumHomeBased);

                    // Neighborhood
                    alternative.AddUtilityTerm(130, logOfOnePlusEmploymentEducationBuffer1);
                    alternative.AddUtilityTerm(131, logOfOnePlusEmploymentRetailBuffer1);

                    // Size terms
                    alternative.AddUtilityTerm(140, destinationParcel.EmploymentFood);
                    alternative.AddUtilityTerm(141, destinationParcel.EmploymentOffice);
                    alternative.AddUtilityTerm(142, destinationParcel.EmploymentRetail);
                    alternative.AddUtilityTerm(143, destinationParcel.EmploymentService);
                }
                else if (_tour.DestinationPurpose == Global.Settings.Purposes.Meal)
                {
                    alternative.AddUtilityTerm(150, piecewiseDistanceFrom0To1Mile);
                    alternative.AddUtilityTerm(151, piecewiseDistanceFrom1To3AndAHalfMiles);
                    alternative.AddUtilityTerm(152, piecewiseDistanceFrom3AndAHalfTo10Miles);
                    alternative.AddUtilityTerm(153, piecewiseDistanceFrom10MilesToInfinity);
                    //alternative.AddUtilityTerm(154, aggregateLogsumHomeBased);

                    // Neighborhood
                    alternative.AddUtilityTerm(156, logOfOnePlusEmploymentFoodBuffer1);
                    //alternative.AddUtilityTerm(157, logOfOnePlusEmploymentRetailBuffer1);
                    alternative.AddUtilityTerm(158, logOfOnePlusEmploymentServiceBuffer1);

                    // Size terms
                    alternative.AddUtilityTerm(160, destinationParcel.EmploymentFood);
                    //(for application) alternative.AddUtilityTerm(161, destinationParcel.EmploymentOffice);
                    alternative.AddUtilityTerm(162, destinationParcel.EmploymentTotal);
                    alternative.AddUtilityTerm(163, destinationParcel.Households);
                }
                else if (_tour.DestinationPurpose == Global.Settings.Purposes.Social)
                {
                    alternative.AddUtilityTerm(170, piecewiseDistanceFrom0To1Mile);
                    alternative.AddUtilityTerm(171, piecewiseDistanceFrom1To3AndAHalfMiles);
                    alternative.AddUtilityTerm(172, piecewiseDistanceFrom3AndAHalfTo10Miles);
                    alternative.AddUtilityTerm(173, piecewiseDistanceFrom10MilesToInfinity);
                    //alternative.AddUtilityTerm(174, aggregateLogsumHomeBased);

                    // Neighborhood
                    //alternative.AddUtilityTerm(180, logOfOnePlusEmploymentOfficeBuffer1);
                    //alternative.AddUtilityTerm(181, logOfOnePlusEmploymentServiceBuffer1);
                    //alternative.AddUtilityTerm(182, logOfOnePlusHouseholdsBuffer1);
                    //alternative.AddUtilityTerm(183, logOfOnePlusStudentsK12Buffer1);
                    //alternative.AddUtilityTerm(184, logOfOnePlusStudentsUniversityBuffer1);
                    //alternative.AddUtilityTerm(185, logOfOnePlusEmploymentTotalBuffer1);

                    // Size terms
                    alternative.AddUtilityTerm(190, destinationParcel.EmploymentEducation);
                    alternative.AddUtilityTerm(191, destinationParcel.EmploymentFood);
                    alternative.AddUtilityTerm(192, destinationParcel.EmploymentGovernment);
                    alternative.AddUtilityTerm(193, destinationParcel.EmploymentOffice);
                    alternative.AddUtilityTerm(194, destinationParcel.EmploymentRetail);
                    alternative.AddUtilityTerm(195, destinationParcel.EmploymentService);
                    alternative.AddUtilityTerm(196, destinationParcel.EmploymentMedical);
                    alternative.AddUtilityTerm(197, destinationParcel.Households);
                    alternative.AddUtilityTerm(198, destinationParcel.StudentsUniversity);
                    //(for application) alternative.AddUtilityTerm(199, destinationParcel.GetStudentsK12());
                }
                else if (_tour.DestinationPurpose == Global.Settings.Purposes.Recreation)
                {
                    alternative.AddUtilityTerm(200, piecewiseDistanceFrom0To1Mile);
                    alternative.AddUtilityTerm(201, piecewiseDistanceFrom1To3AndAHalfMiles);
                    alternative.AddUtilityTerm(202, piecewiseDistanceFrom3AndAHalfTo10Miles);
                    alternative.AddUtilityTerm(203, piecewiseDistanceFrom10MilesToInfinity);
                    //alternative.AddUtilityTerm(204, aggregateLogsumHomeBased);

                    // Neighborhood
                    alternative.AddUtilityTerm(210, logOfOnePlusEmploymentOfficeBuffer1);
                    alternative.AddUtilityTerm(211, logOfOnePlusEmploymentServiceBuffer1);
                    alternative.AddUtilityTerm(212, logOfOnePlusHouseholdsBuffer1);
                    //alternative.AddUtilityTerm(213, logOfOnePlusStudentsK12Buffer1);
                    alternative.AddUtilityTerm(214, logOfOnePlusStudentsUniversityBuffer1);
                    //alternative.AddUtilityTerm(215, logOfOnePlusEmploymentTotalBuffer1);

                    // Size terms
                    alternative.AddUtilityTerm(220, destinationParcel.EmploymentEducation);
                    alternative.AddUtilityTerm(221, destinationParcel.EmploymentFood);
                    alternative.AddUtilityTerm(222, destinationParcel.EmploymentGovernment);
                    alternative.AddUtilityTerm(223, destinationParcel.EmploymentOffice);
                    alternative.AddUtilityTerm(224, destinationParcel.EmploymentRetail);
                    alternative.AddUtilityTerm(225, destinationParcel.EmploymentService);
                    alternative.AddUtilityTerm(226, destinationParcel.EmploymentMedical);
                    alternative.AddUtilityTerm(227, destinationParcel.Households);
                    alternative.AddUtilityTerm(228, destinationParcel.StudentsUniversity);
                    alternative.AddUtilityTerm(229, destinationParcel.GetStudentsK12());
                }
                else if (_tour.DestinationPurpose == Global.Settings.Purposes.Medical)
                {
                    alternative.AddUtilityTerm(230, piecewiseDistanceFrom0To1Mile);
                    alternative.AddUtilityTerm(231, piecewiseDistanceFrom1To3AndAHalfMiles);
                    alternative.AddUtilityTerm(232, piecewiseDistanceFrom3AndAHalfTo10Miles);
                    alternative.AddUtilityTerm(233, piecewiseDistanceFrom10MilesToInfinity);
                    //alternative.AddUtilityTerm(234, aggregateLogsumHomeBased);

                    // Neighborhood
                    //alternative.AddUtilityTerm(240, logOfOnePlusEmploymentEducationBuffer1);
                    //alternative.AddUtilityTerm(241, logOfOnePlusEmploymentOfficeBuffer1);
                    //alternative.AddUtilityTerm(242, logOfOnePlusEmploymentServiceBuffer1);
                    //alternative.AddUtilityTerm(243, logOfOnePlusEmploymentMedicalBuffer1);
                    alternative.AddUtilityTerm(244, logOfOnePlusHouseholdsBuffer1);
                    //alternative.AddUtilityTerm(245, logOfOnePlusStudentsUniversityBuffer1);
                    //alternative.AddUtilityTerm(246, logOfOnePlusEmploymentGovernmentBuffer1);
                    alternative.AddUtilityTerm(247, logOfOnePlusEmploymentRetailBuffer1);

                    // Size terms
                    //(for application) alternative.AddUtilityTerm(250, destinationParcel.EmploymentEducation);
                    //(for application) alternative.AddUtilityTerm(251, destinationParcel.EmploymentFood);
                    //(for application) alternative.AddUtilityTerm(252, destinationParcel.EmploymentGovernment);
                    //(for application) alternative.AddUtilityTerm(253, destinationParcel.EmploymentOffice);
                    //(for application) alternative.AddUtilityTerm(254, destinationParcel.EmploymentRetail);
                    //(for application) alternative.AddUtilityTerm(255, destinationParcel.EmploymentService);
                    alternative.AddUtilityTerm(256, destinationParcel.EmploymentMedical);
                    //(for application) alternative.AddUtilityTerm(257, destinationParcel.EmploymentIndustrial + destinationParcel.EmploymentAgricultureConstruction);
                    //(for application) alternative.AddUtilityTerm(258, destinationParcel.Households);
                    //(for application) alternative.AddUtilityTerm(259, destinationParcel.GetStudentsK12());
                }
            }
示例#28
0
        protected override void RegionSpecificCustomizations(ChoiceProbabilityCalculator.Alternative alternative, IPersonWrapper _person, IParcelWrapper destinationParcel)
        {
            //areas

            int o_int_paphi = (_person.Household.ResidenceParcel.ZoneKey <= 4000).ToFlag();
            int o_int_paoth = (_person.Household.ResidenceParcel.ZoneKey <= 18000).ToFlag() * (1 - o_int_paphi);
            int o_int_nj    = (_person.Household.ResidenceParcel.ZoneKey > 18000 && _person.Household.ResidenceParcel.ZoneKey <= 30000).ToFlag();
            int o_ext_pa    = (_person.Household.ResidenceParcel.ZoneKey > 50000 && _person.Household.ResidenceParcel.ZoneKey <= 53000).ToFlag();
            int o_ext_nnj   = (_person.Household.ResidenceParcel.ZoneKey > 53000 && _person.Household.ResidenceParcel.ZoneKey <= 56000).ToFlag();
            int o_ext_snj   = (_person.Household.ResidenceParcel.ZoneKey > 56000 && _person.Household.ResidenceParcel.ZoneKey <= 58000).ToFlag();
            int o_ext_oth   = (_person.Household.ResidenceParcel.ZoneKey > 58000).ToFlag();

            int d_int_paphi = (destinationParcel.ZoneKey <= 4000).ToFlag();
            int d_int_paoth = (destinationParcel.ZoneKey <= 18000).ToFlag() * (1 - d_int_paphi);
            int d_int_nj    = (destinationParcel.ZoneKey > 18000 && destinationParcel.ZoneKey <= 30000).ToFlag();
            int d_ext_pa    = (destinationParcel.ZoneKey > 50000 && destinationParcel.ZoneKey <= 53000).ToFlag();
            int d_ext_nnj   = (destinationParcel.ZoneKey > 53000 && destinationParcel.ZoneKey <= 56000).ToFlag();
            int d_ext_snj   = (destinationParcel.ZoneKey > 56000 && destinationParcel.ZoneKey <= 58000).ToFlag();
            int d_ext_oth   = (destinationParcel.ZoneKey > 58000).ToFlag();

            int    cbdDest            = destinationParcel.CBD_AreaType_Buffer1();
            double distanceFromOrigin = _person.Household.ResidenceParcel.DistanceFromOrigin(destinationParcel, Global.Settings.Times.EightAM);

            alternative.AddUtilityTerm(121, o_int_nj * distanceFromOrigin);
            alternative.AddUtilityTerm(122, o_int_paoth * distanceFromOrigin);
            alternative.AddUtilityTerm(123, cbdDest * distanceFromOrigin);
            alternative.AddUtilityTerm(124, cbdDest);
            alternative.AddUtilityTerm(125, cbdDest * (_person.Household.Income < 50000).ToFlag());
            alternative.AddUtilityTerm(126, cbdDest * (_person.Household.Income >= 100000).ToFlag());

            alternative.AddUtilityTerm(131, o_int_paphi * d_int_paphi);
            alternative.AddUtilityTerm(132, o_int_paphi * d_int_paoth);
            alternative.AddUtilityTerm(133, o_int_paphi * d_int_nj);
            alternative.AddUtilityTerm(134, o_int_paphi * d_ext_pa);
            alternative.AddUtilityTerm(135, o_int_paphi * d_ext_nnj);
            alternative.AddUtilityTerm(136, o_int_paphi * d_ext_oth);
            alternative.AddUtilityTerm(137, o_int_paphi * d_ext_snj);

            alternative.AddUtilityTerm(141, o_int_paoth * d_int_paphi);
            alternative.AddUtilityTerm(142, o_int_paoth * d_int_paoth);
            alternative.AddUtilityTerm(143, o_int_paoth * d_int_nj);
            alternative.AddUtilityTerm(144, o_int_paoth * d_ext_pa);
            alternative.AddUtilityTerm(145, o_int_paoth * d_ext_nnj);
            alternative.AddUtilityTerm(146, o_int_paoth * d_ext_oth);
            alternative.AddUtilityTerm(147, o_int_paoth * d_ext_snj);

            alternative.AddUtilityTerm(151, o_int_nj * d_int_paphi);
            alternative.AddUtilityTerm(152, o_int_nj * d_int_paoth);
            alternative.AddUtilityTerm(153, o_int_nj * d_int_nj);
            alternative.AddUtilityTerm(154, o_int_nj * d_ext_pa);
            alternative.AddUtilityTerm(155, o_int_nj * d_ext_nnj);
            alternative.AddUtilityTerm(156, o_int_nj * d_ext_oth);
            alternative.AddUtilityTerm(157, o_int_nj * d_ext_snj);

            alternative.AddUtilityTerm(161, o_ext_pa * d_int_paphi);
            alternative.AddUtilityTerm(162, o_ext_pa * d_int_paoth);
            alternative.AddUtilityTerm(163, o_ext_pa * d_int_nj);
            alternative.AddUtilityTerm(164, o_ext_pa * d_ext_pa);
            alternative.AddUtilityTerm(165, o_ext_pa * d_ext_nnj);
            alternative.AddUtilityTerm(166, o_ext_pa * d_ext_oth);
            alternative.AddUtilityTerm(167, o_ext_pa * d_ext_snj);

            alternative.AddUtilityTerm(171, o_ext_nnj * d_int_paphi);
            alternative.AddUtilityTerm(172, o_ext_nnj * d_int_paoth);
            alternative.AddUtilityTerm(173, o_ext_nnj * d_int_nj);
            alternative.AddUtilityTerm(174, o_ext_nnj * d_ext_pa);
            alternative.AddUtilityTerm(175, o_ext_nnj * d_ext_nnj);
            alternative.AddUtilityTerm(176, o_ext_nnj * d_ext_oth);
            alternative.AddUtilityTerm(177, o_ext_nnj * d_ext_snj);

            alternative.AddUtilityTerm(181, o_ext_oth * d_int_paphi);
            alternative.AddUtilityTerm(182, o_ext_oth * d_int_paoth);
            alternative.AddUtilityTerm(183, o_ext_oth * d_int_nj);
            alternative.AddUtilityTerm(184, o_ext_oth * d_ext_pa);
            alternative.AddUtilityTerm(185, o_ext_oth * d_ext_nnj);
            alternative.AddUtilityTerm(186, o_ext_oth * d_ext_oth);
            alternative.AddUtilityTerm(187, o_ext_oth * d_ext_snj);

            alternative.AddUtilityTerm(191, o_ext_snj * d_int_paphi);
            alternative.AddUtilityTerm(192, o_ext_snj * d_int_paoth);
            alternative.AddUtilityTerm(193, o_ext_snj * d_int_nj);
            alternative.AddUtilityTerm(194, o_ext_snj * d_ext_pa);
            alternative.AddUtilityTerm(195, o_ext_snj * d_ext_nnj);
            alternative.AddUtilityTerm(196, o_ext_snj * d_ext_oth);
            alternative.AddUtilityTerm(197, o_ext_snj * d_ext_snj);

            //int origState = _person.Household.ResidenceParcel.District;
            //int destState = destinationParcel.District;

            //int bridgeFromNJ = (origState == 34 && destState > 0 && destState != 34).ToFlag();
            //int bridgeToNJ   = (destState == 34 && origState > 0 && origState != 34).ToFlag();

            //alternative.AddUtilityTerm(91, bridgeFromNJ);
            //alternative.AddUtilityTerm(92, bridgeToNJ);
        }
示例#29
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);
        }
示例#30
0
        private void RunModel(ChoiceProbabilityCalculator choiceProbabilityCalculator, ITourWrapper tour, IEnumerable <IPathTypeModel> pathTypeModels, IParcelWrapper destinationParcel, int householdCars, int choice = Constants.DEFAULT_VALUE)
        {
            IHouseholdWrapper household = tour.Household;
            IPersonWrapper    person    = tour.Person;
            IPersonDayWrapper personDay = tour.PersonDay;

            // household inputs
            int income0To25KFlag        = household.Has0To25KIncome.ToFlag();
            int income25To50KFlag       = household.Has25To50KIncome.ToFlag();
            int income75KPlusFlag       = household.Has75KPlusIncome.ToFlag();
            int incomeOver100Flag       = household.Has100KPlusIncome.ToFlag();
            int onePersonHouseholdFlag  = household.IsOnePersonHousehold.ToFlag();
            int twoPersonHouseholdFlag  = household.IsTwoPersonHousehold.ToFlag();
            int noCarsInHouseholdFlag   = household.GetFlagForNoCarsInHousehold(householdCars);
            int carsLessThanDriversFlag = household.GetFlagForCarsLessThanDrivers(householdCars);
            int carsLessThanWorkersFlag = household.GetFlagForCarsLessThanWorkers(householdCars);

            // person inputs
            int childUnder5Flag       = person.IsChildUnder5.ToFlag();
            int adultFlag             = person.IsAdult.ToFlag();
            int drivingAgeStudentFlag = person.IsDrivingAgeStudent.ToFlag();
            int maleFlag = person.IsMale.ToFlag();

            // remaining inputs
            IParcelWrapper originParcel           = tour.OriginParcel;
            double         destinationParkingCost = destinationParcel.ParkingCostBuffer1(6);

            ChoiceModelUtility.SetEscortPercentages(personDay, out double escortPercentage, out double nonEscortPercentage);

            // school bus is a special case - use HOV3 impedance
            {
                IPathTypeModel pathTypeExtra              = pathTypeModels.First(x => x.Mode == Global.Settings.Modes.Hov3);
                int            modeExtra                  = Global.Settings.Modes.SchoolBus;
                bool           availableExtra             = pathTypeExtra.Available;
                double         generalizedTimeLogsumExtra = pathTypeExtra.GeneralizedTimeLogsum;

                ChoiceProbabilityCalculator.Alternative 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(10, 1);
                    alternative.AddUtilityTerm(11, noCarsInHouseholdFlag);   // for calibration
                    alternative.AddUtilityTerm(13, carsLessThanDriversFlag); // for calibration
                    alternative.AddUtilityTerm(17, childUnder5Flag);
                    alternative.AddUtilityTerm(18, adultFlag);
                }
            }


            foreach (IPathTypeModel pathTypeModel in pathTypeModels)
            {
                int  mode      = pathTypeModel.Mode;
                bool available = (pathTypeModel.Mode != Global.Settings.Modes.ParkAndRide || Global.Configuration.IncludeParkAndRideInSchoolTourModeModel) &&
                                 (pathTypeModel.Mode != Global.Settings.Modes.PaidRideShare || Global.Configuration.PaidRideShareModeIsAvailable) &&
                                 pathTypeModel.Available;
                double generalizedTimeLogsum = pathTypeModel.GeneralizedTimeLogsum;

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

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

                if (!available)
                {
                    continue;
                }

                double modeTimeCoefficient = (Global.Configuration.AV_IncludeAutoTypeChoice && household.OwnsAutomatedVehicles > 0 && mode >= Global.Settings.Modes.Sov && mode <= Global.Settings.Modes.Hov3) ?
                                             tour.TimeCoefficient * (1.0 - Global.Configuration.AV_InVehicleTimeCoefficientDiscountFactor) :
                                             (mode == Global.Settings.Modes.PaidRideShare && Global.Configuration.AV_PaidRideShareModeUsesAVs) ?
                                             tour.TimeCoefficient * (1.0 - Global.Configuration.AV_InVehicleTimeCoefficientDiscountFactor) : tour.TimeCoefficient;
                alternative.AddUtilityTerm(2, generalizedTimeLogsum * modeTimeCoefficient);


                if (mode == Global.Settings.Modes.ParkAndRide)
                {
                    alternative.AddUtilityTerm(5, 1);
                    alternative.AddUtilityTerm(6, noCarsInHouseholdFlag);
                    alternative.AddUtilityTerm(7, carsLessThanWorkersFlag);
                    alternative.AddUtilityTerm(129, destinationParcel.MixedUse2Index1());
                }
                else if (mode == Global.Settings.Modes.Transit)
                {
                    alternative.AddUtilityTerm(20, 1);
                    alternative.AddUtilityTerm(21, noCarsInHouseholdFlag);
                    alternative.AddUtilityTerm(22, carsLessThanDriversFlag);
                    alternative.AddUtilityTerm(27, childUnder5Flag);
                    alternative.AddUtilityTerm(28, adultFlag);
                    alternative.AddUtilityTerm(29, drivingAgeStudentFlag);
                    alternative.AddUtilityTerm(129, destinationParcel.MixedUse2Index1());
                    alternative.AddUtilityTerm(128, destinationParcel.TotalEmploymentDensity1());
                    alternative.AddUtilityTerm(123, (tour.OriginParcel.DistanceToFerry > 0 && tour.OriginParcel.DistanceToFerry <= 0.5).ToFlag());
                    alternative.AddUtilityTerm(124, (destinationParcel.DistanceToFerry > 0 && destinationParcel.DistanceToFerry <= 0.5).ToFlag());
                    //alternative.AddUtilityTerm(125, 0.001 * originParcel.NetIntersectionDensity1()
                    //                                         + 0.0001 * originParcel.HouseholdDensity1()
                    //                                         + 1.0 * originParcel.MixedUse4Index1());
                    //alternative.AddUtilityTerm(126, 1.0 * destinationParcel.MixedUse4Index1()
                    //                                         + 0.00001 * destinationParcel.TotalEmploymentDensity1()
                    //                                         + 0.001 * destinationParcel.NetIntersectionDensity1());

                    //                        alternative.AddUtilityTerm(127, destinationParcel.NetIntersectionDensity1());
                    //                        alternative.AddUtilityTerm(126, originParcel.NetIntersectionDensity1());
                    //                        alternative.AddUtilityTerm(125, originParcel.HouseholdDensity1());
                    //                        alternative.AddUtilityTerm(124, originParcel.MixedUse2Index1());
                    //                        alternative.AddUtilityTerm(123, Math.Log(destinationParcel.StopsTransitBuffer1+1));
                    alternative.AddUtilityTerm(122, Math.Log(originParcel.StopsTransitBuffer1 + 1));
                }
                else if (mode == Global.Settings.Modes.Hov3)
                {
                    alternative.AddUtilityTerm(1, (destinationParkingCost * tour.CostCoefficient / ChoiceModelUtility.CPFACT3));
                    alternative.AddUtilityTerm(30, 1);
                    alternative.AddUtilityTerm(37, twoPersonHouseholdFlag);
                    alternative.AddUtilityTerm(37, onePersonHouseholdFlag);
                    alternative.AddUtilityTerm(36, noCarsInHouseholdFlag);   // for calibration of hov3 vs hov2
                    alternative.AddUtilityTerm(35, carsLessThanDriversFlag); // for calibration of hov3 vs hov2
                    alternative.AddUtilityTerm(41, noCarsInHouseholdFlag);
                    alternative.AddUtilityTerm(44, income0To25KFlag);
                    alternative.AddUtilityTerm(45, income25To50KFlag);
                    alternative.AddUtilityTerm(47, childUnder5Flag);
                    alternative.AddUtilityTerm(133, escortPercentage);
                    alternative.AddUtilityTerm(134, nonEscortPercentage);
                }
                else if (mode == Global.Settings.Modes.Hov2)
                {
                    alternative.AddUtilityTerm(1, (destinationParkingCost * tour.CostCoefficient / ChoiceModelUtility.CPFACT2));
                    alternative.AddUtilityTerm(38, onePersonHouseholdFlag);
                    alternative.AddUtilityTerm(40, 1);
                    alternative.AddUtilityTerm(41, noCarsInHouseholdFlag);
                    alternative.AddUtilityTerm(42, carsLessThanDriversFlag); // for calibration
                    alternative.AddUtilityTerm(44, income0To25KFlag);
                    alternative.AddUtilityTerm(45, income25To50KFlag);
                    alternative.AddUtilityTerm(47, childUnder5Flag);
                    alternative.AddUtilityTerm(133, escortPercentage);
                    alternative.AddUtilityTerm(134, nonEscortPercentage);
                }
                else if (mode == Global.Settings.Modes.Sov)
                {
                    alternative.AddUtilityTerm(1, (destinationParkingCost * tour.CostCoefficient));
                    alternative.AddUtilityTerm(50, 1);
                    alternative.AddUtilityTerm(52, carsLessThanDriversFlag);
                    alternative.AddUtilityTerm(54, income0To25KFlag);
                    alternative.AddUtilityTerm(56, income75KPlusFlag);
                    alternative.AddUtilityTerm(59, drivingAgeStudentFlag);
                    alternative.AddUtilityTerm(131, escortPercentage);
                    alternative.AddUtilityTerm(132, nonEscortPercentage);
                }
                else if (mode == Global.Settings.Modes.Bike)
                {
                    double class1Dist =
                        Global.Configuration.PathImpedance_BikeUseTypeSpecificDistanceFractions
                  ? ImpedanceRoster.GetValue("class1distance", mode, Global.Settings.PathTypes.FullNetwork,
                                             Global.Settings.ValueOfTimes.DefaultVot, tour.DestinationArrivalTime, originParcel, destinationParcel).Variable
                  : 0;

                    double class2Dist =
                        Global.Configuration.PathImpedance_BikeUseTypeSpecificDistanceFractions
                  ? ImpedanceRoster.GetValue("class2distance", mode, Global.Settings.PathTypes.FullNetwork,
                                             Global.Settings.ValueOfTimes.DefaultVot, tour.DestinationArrivalTime, originParcel, destinationParcel).Variable
                  : 0;

                    double worstDist =
                        Global.Configuration.PathImpedance_BikeUseTypeSpecificDistanceFractions
                  ? ImpedanceRoster.GetValue("worstdistance", mode, Global.Settings.PathTypes.FullNetwork,
                                             Global.Settings.ValueOfTimes.DefaultVot, tour.DestinationArrivalTime, originParcel, destinationParcel).Variable
                  : 0;

                    alternative.AddUtilityTerm(60, 1);
                    alternative.AddUtilityTerm(61, maleFlag);
                    alternative.AddUtilityTerm(67, noCarsInHouseholdFlag);   //for calibration
                    alternative.AddUtilityTerm(68, carsLessThanDriversFlag); //for calibration
                    alternative.AddUtilityTerm(69, adultFlag);
                    alternative.AddUtilityTerm(169, destinationParcel.MixedUse4Index1());
                    alternative.AddUtilityTerm(168, destinationParcel.TotalEmploymentDensity1());
                    alternative.AddUtilityTerm(167, destinationParcel.NetIntersectionDensity1());
                    alternative.AddUtilityTerm(166, originParcel.NetIntersectionDensity1());
                    alternative.AddUtilityTerm(165, originParcel.HouseholdDensity1());
                    alternative.AddUtilityTerm(164, originParcel.MixedUse4Index1());
                    alternative.AddUtilityTerm(161, (class1Dist > 0).ToFlag());
                    alternative.AddUtilityTerm(162, (class2Dist > 0).ToFlag());
                    alternative.AddUtilityTerm(163, (worstDist > 0).ToFlag());
                    alternative.AddUtilityTerm(170, 1.0 * destinationParcel.MixedUse4Index1()
                                               + 0.00002 * destinationParcel.TotalEmploymentDensity1()
                                               + 0.001 * destinationParcel.NetIntersectionDensity1()
                                               + 0.001 * originParcel.NetIntersectionDensity1()
                                               + 0.0002 * originParcel.HouseholdDensity1()
                                               + 1.0 * originParcel.MixedUse4Index1());
                }
                else if (mode == Global.Settings.Modes.Walk)
                {
                    alternative.AddUtilityTerm(70, 1);
                    alternative.AddUtilityTerm(77, noCarsInHouseholdFlag);   //for calibration
                    alternative.AddUtilityTerm(78, carsLessThanDriversFlag); //for calibration
                    alternative.AddUtilityTerm(79, adultFlag);
                    alternative.AddUtilityTerm(179, destinationParcel.MixedUse4Index1());
                    alternative.AddUtilityTerm(178, destinationParcel.TotalEmploymentDensity1());
                    alternative.AddUtilityTerm(177, destinationParcel.NetIntersectionDensity1());
                    alternative.AddUtilityTerm(176, originParcel.NetIntersectionDensity1());
                    alternative.AddUtilityTerm(175, originParcel.HouseholdDensity1());
                    alternative.AddUtilityTerm(179, originParcel.MixedUse4Index1());
                    alternative.AddUtilityTerm(181, 1.0 * destinationParcel.MixedUse4Index1()
                                               + 0.00001 * destinationParcel.TotalEmploymentDensity1()
                                               + 0.001 * destinationParcel.NetIntersectionDensity1()
                                               + 0.001 * originParcel.NetIntersectionDensity1()
                                               + 0.0001 * originParcel.HouseholdDensity1()
                                               + 1.0 * originParcel.MixedUse4Index1());
                }
                else if (mode == Global.Settings.Modes.PaidRideShare)
                {
                    if (Global.Configuration.PaidRideshare_UseEstimatedInsteadOfAssertedCoefficients)
                    {
                        alternative.AddUtilityTerm(80, 1.0);
                        alternative.AddUtilityTerm(81, noCarsInHouseholdFlag);   //for calibration
                        alternative.AddUtilityTerm(82, carsLessThanDriversFlag); //for calibration
                        alternative.AddUtilityTerm(83, tour.Person.AgeIsBetween26And35.ToFlag());
                        alternative.AddUtilityTerm(83, tour.Person.AgeIsBetween18And25.ToFlag());
                        alternative.AddUtilityTerm(84, (tour.Person.Age < 18).ToFlag());            //alternative.AddUtilityTerm(81, tour.Person.AgeIsBetween26And35.ToFlag());
                        alternative.AddUtilityTerm(85, originParcel.HouseholdsBuffer2 + originParcel.StudentsUniversityBuffer2 + originParcel.EmploymentTotalBuffer2);
                        alternative.AddUtilityTerm(86, destinationParcel.HouseholdsBuffer2 + destinationParcel.StudentsUniversityBuffer2 + destinationParcel.EmploymentTotalBuffer2);
                        alternative.AddUtilityTerm(87, income0To25KFlag);
                        alternative.AddUtilityTerm(88, incomeOver100Flag);
                    }
                    else
                    {
                        double modeConstant = Global.Configuration.AV_PaidRideShareModeUsesAVs
                        ? Global.Configuration.AV_PaidRideShare_ModeConstant
                                              + Global.Configuration.AV_PaidRideShare_DensityCoefficient * Math.Min(originParcel.HouseholdsBuffer2 + originParcel.StudentsUniversityBuffer2 + originParcel.EmploymentTotalBuffer2,
                                                                                                                    (Global.Configuration.PaidRideShare_DensityMeasureCapValue > 0) ? Global.Configuration.PaidRideShare_DensityMeasureCapValue : 6000)
                                              + Global.Configuration.AV_PaidRideShare_AVOwnerCoefficient * (household.OwnsAutomatedVehicles > 0).ToFlag()
                        : Global.Configuration.PaidRideShare_ModeConstant
                                              + Global.Configuration.PaidRideShare_DensityCoefficient * Math.Min(originParcel.HouseholdsBuffer2 + originParcel.StudentsUniversityBuffer2 + originParcel.EmploymentTotalBuffer2,
                                                                                                                 (Global.Configuration.PaidRideShare_DensityMeasureCapValue > 0) ? Global.Configuration.PaidRideShare_DensityMeasureCapValue : 6000);

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

                RegionSpecificCustomizations(alternative, tour, pathTypeModel.PathType, mode, destinationParcel);
            }
        }