示例#1
0
        public int Run(HouseholdDayWrapper householdDay, int nCallsForTour, int choice)
        {
            if (householdDay == null)
            {
                throw new ArgumentNullException("householdDay");
            }

            householdDay.ResetRandom(935 + nCallsForTour);

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

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

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

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

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

            return(choice);
        }
示例#2
0
        public void Run(PersonDayWrapper personDay, HouseholdDayWrapper householdDay)
        {
            if (personDay == null)
            {
                throw new ArgumentNullException("personDay");
            }

            personDay.Person.ResetRandom(961);

            int choice = 0;

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

            var choiceProbabilityCalculator = _helpers[ParallelUtility.GetBatchFromThreadId()].GetChoiceProbabilityCalculator(personDay.Person.Id * 10 + personDay.Day);

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

                RunModel(choiceProbabilityCalculator, personDay, householdDay, choice);

                choiceProbabilityCalculator.WriteObservation();
            }

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

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

                RunModel(choiceProbabilityCalculator, personDay, householdDay);

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

                Global.Configuration.IsInEstimationMode = true;
            }

            else
            {
                RunModel(choiceProbabilityCalculator, personDay, householdDay);

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

                if (choice == 1 || choice == 3)
                {
                    personDay.BusinessStops = 1;
                }
                if (choice == 2 || choice == 3)
                {
                    personDay.SchoolStops = 1;
                }
            }
        }
        public int Run(HouseholdDayWrapper householdDay, int jHTSimulated, int genChoice, int[] participants, int[] jHTChauffeurSequence)
        {
            if (householdDay == null)
            {
                throw new ArgumentNullException("householdDay");
            }

            householdDay.ResetRandom(930 + jHTSimulated);

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

            int chauffeurSequence = 0;
            int choice            = 0;

            if (Global.Configuration.IsInEstimationMode)
            {
                chauffeurSequence = jHTChauffeurSequence[jHTSimulated];
                int i = 0;
                foreach (PersonDayWrapper personDay in orderedPersonDays)
                {
                    i++;
                    if (personDay.Person.Sequence == chauffeurSequence && i <= 5)
                    {
                        choice = i;
                    }
                }
                if (Global.Configuration.EstimationModel != CHOICE_MODEL_NAME || choice == 0)
                {
                    return(choice);
                }
            }

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

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

                choiceProbabilityCalculator.WriteObservation();

                return(choice);
            }
            else
            {
                RunModel(choiceProbabilityCalculator, householdDay, jHTSimulated, genChoice, participants);

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

                int i = 0;
                foreach (PersonDayWrapper personDay in orderedPersonDays)
                {
                    i++;
                    if ((int)chosenAlternative.Choice == i)
                    {
                        choice = personDay.Person.Sequence;
                    }
                }
                return(choice);
            }
        }
示例#4
0
        public static void SignalShutdown()
        {
            if (ThreadQueue == null)
            {
                return;
            }

            ThreadQueue.Shutdown();

            HouseholdWrapper.Close();
            PersonWrapper.Close();
            HouseholdDayWrapper.Close();
            PersonDayWrapper.Close();
            TourWrapper.Close();
            TripWrapper.Close();
            if (!string.IsNullOrEmpty(Global.Configuration.OutputJointTourPath))
            {
                JointTourWrapper.Close();
            }
            if (!string.IsNullOrEmpty(Global.Configuration.OutputFullHalfTourPath))
            {
                FullHalfTourWrapper.Close();
            }
            if (!string.IsNullOrEmpty(Global.Configuration.OutputPartialHalfTourPath))
            {
                PartialHalfTourWrapper.Close();
            }
        }
示例#5
0
        public int Run(HouseholdDayWrapper householdDay, int nCallsForTour, bool[] available, int type, int subType)
        {
            if (householdDay == null)
            {
                throw new ArgumentNullException("householdDay");
            }

            householdDay.ResetRandom(920 + nCallsForTour);

            int choice = 0;

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

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

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

            if (_helpers[ParallelUtility.threadLocalAssignedIndex.Value].ModelIsInEstimationMode)
            {
                //if (tour.PersonDay.TotalStops > 0) {  // TODO:  maybe the restrictions coming from HH pattern shoudl enter here
                RunModel(choiceProbabilityCalculator, householdDay, nCallsForTour, available, choice);

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

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

                RunModel(choiceProbabilityCalculator, householdDay, nCallsForTour, available);

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

                Global.Configuration.IsInEstimationMode = true;
            }
            else
            {
                //if (tour.PersonDay.TotalStops > 0) {  // TODO:  maybe the restrictions coming from HH pattern shoudl enter here
                RunModel(choiceProbabilityCalculator, householdDay, nCallsForTour, available);

                ChoiceProbabilityCalculator.Alternative chosenAlternative = choiceProbabilityCalculator.SimulateChoice(householdDay.Household.RandomUtility);
                choice = (int)chosenAlternative.Choice;
                //}
                //else {                                      // TODO:  see above TODO:
                //	choice = Global.Settings.Purposes.NoneOrHome;   // this is returned if the model isn't even run because we know there are no tours
                //                                               which is used by the choicemodelrunneer to break tour generation
                // }
            }

            return(choice);
        }
示例#6
0
        public void Run(PersonDayWrapper personDay, HouseholdDayWrapper householdDay)
        {
            if (personDay == null)
            {
                throw new ArgumentNullException("personDay");
            }

            personDay.Person.ResetRandom(903);

            int choice = 0;

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

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

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

                RunModel(choiceProbabilityCalculator, personDay, householdDay, choice);

                choiceProbabilityCalculator.WriteObservation();
            }

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

                //choice = personDay.PatternType;

                RunModel(choiceProbabilityCalculator, personDay, householdDay);

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

                //var simulatedChoice = choiceProbabilityCalculator.SimulateChoice(householdDay.Household.RandomUtility, householdDay.Household.Id, altPTypes.);

                //var chosenAlternative = choiceProbabilityCalculator.SimulateChoice(householdDay.Household.RandomUtility, householdDay.Household.Id, choice);

                var chosenAlternative = choiceProbabilityCalculator.SimulateChoice(householdDay.Household.RandomUtility, personDay.Id, personDay.PatternType - 1);

                Global.Configuration.IsInEstimationMode = true;
            }

            else
            {
                RunModel(choiceProbabilityCalculator, personDay, householdDay);

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

                personDay.PatternType = choice;
            }
        }
示例#7
0
        public int Run(PersonDayWrapper personDay, HouseholdDayWrapper householdDay, int nCallsForTour, int[] simulatedMandatoryTours, int choice)
        {
            if (personDay == null)
            {
                throw new ArgumentNullException("personDay");
            }

            personDay.Person.ResetRandom(904 + nCallsForTour);

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

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

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

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

                RunModel(choiceProbabilityCalculator, personDay, householdDay, nCallsForTour, simulatedMandatoryTours);

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

                Global.Configuration.IsInEstimationMode = true;
            }

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

            return(choice);
        }
示例#8
0
		public void Run(PersonDayWrapper personDay, HouseholdDayWrapper householdDay) {
			if (personDay == null) {
				throw new ArgumentNullException("personDay");
			}
			
			personDay.Person.ResetRandom(904);

			if (Global.Configuration.IsInEstimationMode) {

				if (personDay.WorkAtHomeDuration >= 120 && personDay.Person.IsFullOrPartTimeWorker) { personDay.WorksAtHomeFlag = 1; }
				else personDay.WorksAtHomeFlag = 0;
				if (!_helpers[ParallelUtility.GetBatchFromThreadId()].ModelIsInEstimationMode || !personDay.Person.IsFullOrPartTimeWorker) {
					return;
				}
			}

			var choiceProbabilityCalculator = _helpers[ParallelUtility.GetBatchFromThreadId()].GetChoiceProbabilityCalculator(personDay.Person.Id * 10 + personDay.Day);

			if (_helpers[ParallelUtility.GetBatchFromThreadId()].ModelIsInEstimationMode) {

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

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

				choiceProbabilityCalculator.WriteObservation();
			}

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

				RunModel(choiceProbabilityCalculator, personDay, householdDay);

				var chosenAlternative = choiceProbabilityCalculator.SimulateChoice(householdDay.Household.RandomUtility, personDay.Id, personDay.WorksAtHomeFlag);

				Global.Configuration.IsInEstimationMode = true;
			}

			else {

				int choice;

				if (!personDay.Person.IsFullOrPartTimeWorker) {
					choice = 0;
				}
				else {

					RunModel(choiceProbabilityCalculator, personDay, householdDay);

					var chosenAlternative = choiceProbabilityCalculator.SimulateChoice(personDay.Household.RandomUtility);
					choice = (int) chosenAlternative.Choice;
				}
				personDay.WorksAtHomeFlag = choice;
				personDay.WorkAtHomeDuration = choice * 120; //default predicted duration for output
			}
		}
示例#9
0
        public void Run(HouseholdDayWrapper householdDay, TripWrapper trip)
        {
            if (trip == null)
            {
                throw new ArgumentNullException("trip");
            }

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

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

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

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

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

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

                var chosenAlternative = choiceProbabilityCalculator.SimulateChoice(trip.Household.RandomUtility);

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

                var choice = (HTripTime)chosenAlternative.Choice;

                trip.DepartureTime = choice.GetRandomFeasibleMinute(trip, choice);
            }
        }
示例#10
0
        public int Run(HouseholdDayWrapper householdDay, int nCallsForTour, int choice)
        {
            if (householdDay == null)
            {
                throw new ArgumentNullException("householdDay");
            }

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

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

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

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

                choiceProbabilityCalculator.WriteObservation();
            }

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

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

                RunModel(choiceProbabilityCalculator, householdDay, nCallsForTour);

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

                Global.Configuration.IsInEstimationMode = true;
            }

            else
            {
                RunModel(choiceProbabilityCalculator, householdDay, nCallsForTour);

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

            return(choice);
        }
示例#11
0
        public static PersonDayWrapper GetPersonDayWrapper(PersonWrapper personWrapper = null, int income = 0)
        {
            List <IPerson> persons = new List <IPerson> {
                new Person()
            };
            HouseholdWrapper    householdWrapper = TestHelper.GetHouseholdWrapper(persons, income: income);
            HouseholdDayWrapper householdDay     = TestHelper.GetHouseholdDayWrapper(householdWrapper: householdWrapper);

            if (personWrapper == null)
            {
                personWrapper = GetPersonWrapper(household: householdWrapper);
            }
            return(new PersonDayWrapper(new PersonDay(), personWrapper, householdDay));
        }
示例#12
0
        public int Run(TourWrapper tour, HouseholdDayWrapper householdDay, int nCallsForTour, int choice)
        {
            if (tour == null)
            {
                throw new ArgumentNullException("tour");
            }

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

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

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

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

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

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

            return(choice);
        }
示例#13
0
        public int Run(PersonDayWrapper personDay, HouseholdDayWrapper householdDay, int maxPurpose, int choice)
        {
            if (householdDay == null)
            {
                throw new ArgumentNullException("householdDay");
            }

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

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

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

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

                choiceProbabilityCalculator.WriteObservation();
            }

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

                RunModel(choiceProbabilityCalculator, personDay, householdDay, maxPurpose);

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

                Global.Configuration.IsInEstimationMode = true;
            }

            else
            {
                RunModel(choiceProbabilityCalculator, personDay, householdDay, maxPurpose);

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

            return(choice);
        }
示例#14
0
        public void TestHouseholdDayWrapperJointHalfTour()
        {
            List <IPerson> persons = new List <IPerson> {
                new Person()
            };

            Global.Configuration = new Configuration {
                HouseholdSamplingRateOneInX = 1
            };
            ChoiceModelFactory.Parcels = new Dictionary <int, CondensedParcel>();
            const int residenceParcelId = 99;

            ChoiceModelFactory.Parcels.Add(residenceParcelId, new CondensedParcel());

            HouseholdWrapper    household = TestHelper.GetHouseholdWrapper(persons);
            HouseholdDayWrapper wrapper   = TestHelper.GetHouseholdDayWrapper(householdWrapper: household);
        }
        public void Run(HouseholdDayWrapper householdDay)
        {
            if (householdDay == null)
            {
                throw new ArgumentNullException("householdDay");
            }

            householdDay.ResetRandom(962);

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

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



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

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

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

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

            var chosenAlternative = choiceProbabilityCalculator.SimulateChoice(householdDay.Household.RandomUtility);
            var choice            = (int[])chosenAlternative.Choice;

            householdDay.StartingMinuteSharedHomeStay  = choice[1];
            householdDay.DurationMinutesSharedHomeStay = choice[2];
            //}
        }
示例#16
0
        public int Run(TourWrapper tour, int nCallsForTour, HouseholdDayWrapper householdDay, int choice)
        {
            if (tour == null)
            {
                throw new ArgumentNullException("tour");
            }

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

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

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

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

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

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

            return(choice);
        }
示例#17
0
        public void TestFullHalfTourExport()
        {
            Global.Configuration = new Configuration {
                HouseholdSamplingRateOneInX = 256
            };
            FullHalfTour        tour = new FullHalfTour();
            HouseholdDayWrapper householdDayWrapper = TestHelper.GetHouseholdDayWrapper();
            var exporter = new TestFullHalfTourExporter();

            FullHalfTourWrapper.SetPersister(new PersisterWithHDF5 <FullHalfTour>(exporter));
            FullHalfTourWrapper wrapper = new FullHalfTourWrapper(tour, householdDayWrapper);

            Assert.Equal(false, exporter.HasWritten);
            Assert.Equal(0, ChoiceModelFactory.FullHalfTourFileRecordsWritten);
            wrapper.Export();
            Assert.Equal(true, exporter.HasWritten);
            Assert.Equal(1, ChoiceModelFactory.FullHalfTourFileRecordsWritten);
        }
示例#18
0
        public ChoiceProbabilityCalculator.Alternative RunNested(TourWrapper tour, IParcelWrapper destinationParcel, int householdCars, double transitDiscountFraction)
        {
            if (Global.Configuration.AvoidDisaggregateModeChoiceLogsums)
            {
                return(null);
            }
            ChoiceProbabilityCalculator choiceProbabilityCalculator = _helpers[ParallelUtility.threadLocalAssignedIndex.Value].GetNestedChoiceProbabilityCalculator();

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

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

            tour.DestinationParcel = destinationParcel;
            HTourModeTime.SetModeTimeImpedances(householdDay, tour, constrainedMode, constrainedArrivalTime, constrainedDepartureTime, householdCars, transitDiscountFraction);

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

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

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

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

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

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

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

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

            return(choice);
        }
        public int Run(HouseholdDayWrapper householdDay, int nCallsForTour, bool[] available, int type, int subType)
        {
            if (householdDay == null)
            {
                throw new ArgumentNullException("householdDay");
            }

            householdDay.ResetRandom(920 + nCallsForTour);

            int choice = 0;

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

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

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

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

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

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

            return(choice);
        }
        public void Run(PersonDayWrapper personDay, HouseholdDayWrapper householdDay)
        {
            if (personDay == null)
            {
                throw new ArgumentNullException("personDay");
            }

            personDay.Person.ResetRandom(903);

            int choice = 0;

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

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

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

                RunModel(choiceProbabilityCalculator, personDay, householdDay, choice);

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

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

                personDay.PatternType = choice;
            }
        }
示例#22
0
        public void TestHouseholdDayWrapperFullHalfTour()
        {
            List <IPerson> persons = new List <IPerson> {
                new Person()
            };

            Global.Configuration = new Configuration {
                HouseholdSamplingRateOneInX = 1
            };
            ChoiceModelFactory.Parcels = new Dictionary <int, CondensedParcel>();
            const int residenceParcelId = 99;

            ChoiceModelFactory.Parcels.Add(residenceParcelId, new CondensedParcel());
            Global.Configuration.IsInEstimationMode = false;
            Global.Configuration.UseJointTours      = true;
            FullHalfTourWrapper.SetPersister(new PersisterWithHDF5 <FullHalfTour>(new TestFullHalfTourExporter()));

            HouseholdWrapper household = TestHelper.GetHouseholdWrapper(persons, id: 9);

            HouseholdDayWrapper wrapper = TestHelper.GetHouseholdDayWrapper(householdWrapper: household, id: 8);

            Assert.Equal(0, wrapper.FullHalfTours);
            Assert.Equal(0, wrapper.FullHalfToursList.Count);
            IEnumerable <PersonDayWrapper> orderedPersonDays = wrapper.PersonDays.OrderBy(p => p.JointHalfTourParticipationPriority).ToList().Cast <PersonDayWrapper>();

            int[]                participants = new [] { 0, 0, 0, 0, 0, 0, 0, 0 };
            const int            direction    = 1;
            IFullHalfTourWrapper tourWrapper  = wrapper.CreateFullHalfTour(wrapper, orderedPersonDays, participants, direction);

            Assert.Equal(1, tourWrapper.Direction);
            Assert.Equal(household, tourWrapper.Household);
            Assert.Equal(wrapper, tourWrapper.HouseholdDay);
            Assert.Equal(81, tourWrapper.Id);
            Assert.Equal(false, tourWrapper.Paired);
            tourWrapper.Paired = true;
            Assert.Equal(true, tourWrapper.Paired);
            Assert.Equal(0, tourWrapper.Participants);
        }
示例#23
0
        public void TestHouseholdDayWrapper()
        {
            List <IPerson> persons = new List <IPerson> {
                new Person {
                    Id = 58
                }
            };

            Global.Configuration = new Configuration {
                HouseholdSamplingRateOneInX = 1
            };
            ChoiceModelFactory.Parcels = new Dictionary <int, CondensedParcel>();
            const int residenceParcelId = 99;

            ChoiceModelFactory.Parcels.Add(residenceParcelId, new CondensedParcel());

            HouseholdWrapper    household = TestHelper.GetHouseholdWrapper(persons);
            HouseholdDayWrapper wrapper   = TestHelper.GetHouseholdDayWrapper(householdWrapper: household);

            Assert.Equal(0, wrapper.AttemptedSimulations);
            wrapper.AttemptedSimulations++;
            Assert.Equal(1, wrapper.AttemptedSimulations);

            Assert.Equal(household, wrapper.Household);

            Assert.Equal(false, wrapper.IsMissingData);
            wrapper.IsMissingData = true;
            Assert.Equal(true, wrapper.IsMissingData);

            Assert.Equal(false, wrapper.IsValid);
            wrapper.IsValid = true;
            Assert.Equal(true, wrapper.IsValid);

            Assert.Equal(1, wrapper.PersonDays.Count);
            Assert.Equal(persons[0].Id, wrapper.PersonDays[0].Person.Id);
        }
        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);
        }
 public int Run(TourWrapper tour, int nCallsForTour, HouseholdDayWrapper householdDay)
 {
     return(Run(tour, nCallsForTour, householdDay, Global.Settings.Purposes.NoneOrHome));
 }
        public int[] Run(HouseholdDayWrapper householdDay, int jHTSimulated, int genChoice, bool[,] jHTAvailable, bool[] fHTAvailable, bool[,] jHTParticipation)
        {
            if (householdDay == null)
            {
                throw new ArgumentNullException("householdDay");
            }

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

            householdDay.ResetRandom(925 + jHTSimulated);

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

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

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

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

                choiceProbabilityCalculator.WriteObservation();

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

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

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

                Global.Configuration.IsInEstimationMode = true;

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

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

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

                choice = (int)chosenAlternative.Choice;

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

            PersonDayWrapper pPersonDay = null;

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

            int hhsize = householdDay.Household.Size;

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

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

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

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

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

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

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

            int count = 0;

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

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

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

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

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

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

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

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

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

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

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

            int componentIndex = 0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

            //create two-way cross interaction utility components

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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


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

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

                alternative.Choice = alt;

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

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

                for (int p = 1; p <= 5; p++)
                {
                    if (altParticipants[alt][p] == 1)
                    {
                        alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]));
                    }
                }
                for (int t2 = 1; t2 <= 5; t2++)
                {
                    for (int t1 = 1; t1 < t2; t1++)
                    {
                        if (altParticipants[alt][t1] == 1 && altParticipants[alt][t2] == 1)
                        {
                            alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]));
                        }
                    }
                }
                for (int t2 = 1; t2 <= 5; t2++)
                {
                    for (int t1 = 1; t1 <= 5; t1++)
                    {
                        if (!(t1 == t2))
                        {
                            if (altParticipants[alt][t1] == 1 && altParticipants[alt][t2] == 1)
                            {
                                alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]));
                            }
                        }
                    }
                }
            }
        }
        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 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 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;

            bool[] pLessThan3NonMandatoryTours = new bool[6];
            bool[] pLessThan3TourPurposes      = new bool[6];

            int[] pUsualLocation            = new int[6];
            int[] pPatternType              = new int[6];
            int[] pConstant                 = new int[6];
            int[] pType9                    = new int[6]; //GV
            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[] pAgeUnder16               = new int[6];
            int[] pType8Mandatory           = new int[6];
            int[] pType8NonMandatory        = new int[6];

            int[] pType7Mandatory    = new int[6];
            int[] pType7NonMandatory = 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];

            int count = 0;

            foreach (PersonDayWrapper personDay in orderedPersonDays)
            {
                count++;
                if (count <= 5)
                {
                    // set characteristics here that depend on person characteristics
                    if (personDay.Person.IsFullOrPartTimeWorker)
                    {
                        pUsualLocation[count] = personDay.Person.UsualWorkParcelId;
                    }
                    else if (personDay.Person.IsStudent)
                    {
                        pUsualLocation[count] = personDay.Person.UsualSchoolParcelId;
                    }
                    else if (personDay.Person.IsWorker && personDay.Person.IsNotFullOrPartTimeWorker)
                    {
                        pUsualLocation[count] = personDay.Person.UsualWorkParcelId;
                    }
                    else
                    {
                        pUsualLocation[count] = Constants.DEFAULT_VALUE;
                    }

                    pLessThan3NonMandatoryTours[count] = personDay.GetCreatedNonMandatoryTours() < 3;
                    pLessThan3TourPurposes[count]      = personDay.GetTotalCreatedTourPurposes() < 3;
                    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();

                    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();
                    pAdultNonMandatory[count] = (personDay.Person.IsAdult && personDay.PatternType == Global.Settings.PatternTypes.Optional).ToFlag();

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

            var componentIndex = 0;

            //Create person utility components
            int[] componentPerson = new int[6];
            for (var 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
                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
                choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(6, pType7NonMandatory[p]);              // impact of Child5-16 with non-mandatory travel

                //GV: 16. june, not sign
                //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 (var t2 = 1; t2 <= 5; t2++)
            {
                for (var t1 = 1; t1 < t2; t1++)
                {
                    //populate match variables
                    // 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]);
                    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 (var t2 = 1; t2 <= 5; t2++)
            {
                for (var 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]);

                        //GV: 16. june 2016 - not sign.
                        //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]);

                        choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(46, iCrossAdultFemaleWithChildUnder5[t1, t2]);

                        //choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(47, iCrossYouthAndChildUnder5[t1, t2]);
                        //GV: 16. june 2016 - not sign.
                        //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 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;
                    }
                }

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

                //Get the alternative
                var 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);

                //Add utility components

                for (int p = 1; p <= 5; p++)
                {
                    if (altParticipants[alt][p] == 1)
                    {
                        alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]));
                    }
                }
                for (var t2 = 1; t2 <= 5; t2++)
                {
                    for (var t1 = 1; t1 < t2; t1++)
                    {
                        if (altParticipants[alt][t1] == 1 && altParticipants[alt][t2] == 1)
                        {
                            alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]));
                        }
                    }
                }
                for (var t2 = 1; t2 <= 5; t2++)
                {
                    for (var t1 = 1; t1 <= 5; t1++)
                    {
                        if (!(t1 == t2))
                        {
                            if (altParticipants[alt][t1] == 1 && altParticipants[alt][t2] == 1)
                            {
                                alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]));
                            }
                        }
                    }
                }
            }
        }
示例#30
0
        private void RunModel(ChoiceProbabilityCalculator choiceProbabilityCalculator, PersonDayWrapper personDay, HouseholdDayWrapper householdDay, int nCallsForTour, int[] simulatedMandatoryTours, int choice = Constants.DEFAULT_VALUE)
        {
            var household = personDay.Household;

            Double workTourLogsum;

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

            Double schoolTourLogsum;

            if (personDay.Person.UsualSchoolParcelId != Constants.DEFAULT_VALUE && personDay.Person.UsualSchoolParcelId != Global.Settings.OutOfRegionParcelId)
            {
                //JLB
                //var nestedAlternative = Global.ChoiceModelSession.Get<SchoolTourModeModel>().RunNested(personDay.Person, personDay.Person.Household.ResidenceParcel, personDay.Person.UsualSchoolParcel, Global.Settings.Times.EightAM, Global.Settings.Times.FivePM, personDay.Person.Household.HouseholdTotals.DrivingAgeMembers);
                var nestedAlternative = Global.ChoiceModelSession.Get <SchoolTourModeTimeModel>().RunNested(personDay, personDay.Person.Household.ResidenceParcel, personDay.Person.UsualSchoolParcel, Global.Settings.Times.EightAM, Global.Settings.Times.FivePM, personDay.Person.Household.HouseholdTotals.DrivingAgeMembers);
                schoolTourLogsum = nestedAlternative == null ? 0 : nestedAlternative.ComputeLogsum();
            }
            else
            {
                schoolTourLogsum = 0;
            }

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

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

            var votALSegment                    = Global.Settings.VotALSegments.Medium; // TODO:  calculate a VOT segment that depends on household income
            var transitAccessSegment            = household.ResidenceParcel.TransitAccessSegment();
            var personalBusinessAggregateLogsum = Global.AggregateLogsums[household.ResidenceParcel.ZoneId]
                                                  [Global.Settings.Purposes.PersonalBusiness][carOwnership][votALSegment][transitAccessSegment];
            var shoppingAggregateLogsum = Global.AggregateLogsums[household.ResidenceParcel.ZoneId]
                                          [Global.Settings.Purposes.Shopping][carOwnership][votALSegment][transitAccessSegment];
            var mealAggregateLogsum = Global.AggregateLogsums[household.ResidenceParcel.ZoneId]
                                      [Global.Settings.Purposes.Meal][carOwnership][votALSegment][transitAccessSegment];
            var socialAggregateLogsum = Global.AggregateLogsums[household.ResidenceParcel.ZoneId]
                                        [Global.Settings.Purposes.Social][carOwnership][votALSegment][transitAccessSegment];
            //var compositeLogsum = Global.AggregateLogsums[household.ResidenceZoneId][Global.Settings.Purposes.HomeBasedComposite][carOwnership][votALSegment][transitAccessSegment];
            var compositeLogsum = Global.AggregateLogsums[household.ResidenceZoneId][Global.Settings.Purposes.HomeBasedComposite][Global.Settings.CarOwnerships.NoCars][votALSegment][transitAccessSegment];

            //int hasAdultEducLevel12 = 0;
            //int allAdultEducLevel12 = 1;
            int youngestAge = 999;

            foreach (PersonWrapper person in personDay.Household.Persons)
            {
                // set characteristics here that depend on person characteristics
                //if (person.Age >= 18 && person.EducationLevel >= 12) hasAdultEducLevel12 = 1;
                //if (person.Age >= 18 && person.EducationLevel < 12) allAdultEducLevel12 = 0;
                if (person.Age < youngestAge)
                {
                    youngestAge = person.Age;
                }
            }

            bool schoolAvailableFlag = true;

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

            // NONE_OR_HOME

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

            alternative.Choice = Global.Settings.Purposes.NoneOrHome;
            //alternative.AddUtilityTerm(1, (nCallsForTour > 2).ToFlag()); // GV; 16.april 2013 - cannot be estimated

            //alternative.AddUtilityTerm(2, householdDay.Household.HasChildren.ToFlag());
            alternative.AddUtilityTerm(3, householdDay.Household.HasChildrenUnder5.ToFlag());
            alternative.AddUtilityTerm(4, householdDay.Household.HasChildrenAge5Through15.ToFlag());
            //alternative.AddUtilityTerm(6, householdDay.Household.HasChildrenUnder16.ToFlag());

            //alternative.AddUtilityTerm(10, (householdDay.Household.Size == 2).ToFlag()); // GV; 16. april 2013 - cannot be estimated
            alternative.AddUtilityTerm(11, (householdDay.Household.Size == 3).ToFlag());
            alternative.AddUtilityTerm(12, (householdDay.Household.Size >= 4).ToFlag());

            //alternative.AddUtilityTerm(14, (householdDay.Household.Income >= 300000 && householdDay.Household.Income < 600000).ToFlag());
            //alternative.AddUtilityTerm(15, (householdDay.Household.Income >= 600000 && householdDay.Household.Income < 900000).ToFlag());
            //alternative.AddUtilityTerm(16, (householdDay.Household.Income >= 900000).ToFlag());

            //alternative.AddNestedAlternative(11, 0, 60);


            // USUAL WORK
            alternative        = choiceProbabilityCalculator.GetAlternative(1, (personDay.Person.UsualWorkParcelId > 0 && simulatedMandatoryTours[2] == 0), choice == 1);
            alternative.Choice = 1;
            alternative.AddUtilityTerm(21, 1);

            //alternative.AddUtilityTerm(22, personDay.Person.IsChildUnder5.ToFlag());
            alternative.AddUtilityTerm(23, personDay.Person.WorksAtHome.ToFlag());
            alternative.AddUtilityTerm(24, personDay.Person.IsFulltimeWorker.ToFlag());
            alternative.AddUtilityTerm(25, personDay.Person.IsMale.ToFlag());
            //alternative.AddUtilityTerm(4, person.IsPartTimeWorker.ToFlag());

            alternative.AddUtilityTerm(26, (householdDay.AdultsInSharedHomeStay == 2 && householdDay.Household.HouseholdTotals.FullAndPartTimeWorkers >= 2).ToFlag());
            //alternative.AddUtilityTerm(14, (householdDay.AdultsInSharedHomeStay == 2).ToFlag());
            //alternative.AddUtilityTerm(15, (householdDay.Household.HouseholdTotals.FullAndPartTimeWorkers >= 2).ToFlag());
            alternative.AddUtilityTerm(27, (householdDay.AdultsInSharedHomeStay == 1 && householdDay.Household.HasChildren).ToFlag());

            alternative.AddUtilityTerm(28, workTourLogsum);

            //alternative.AddUtilityTerm(28, (householdDay.Household.VehiclesAvailable == 1 && household.Has2Drivers).ToFlag());
            alternative.AddUtilityTerm(29, (householdDay.Household.VehiclesAvailable >= 2 && household.Has2Drivers).ToFlag());

            alternative.AddUtilityTerm(30, householdDay.PrimaryPriorityTimeFlag);

            //alternative.AddNestedAlternative(12, 1, 60);

            // BUSINESS
            alternative        = choiceProbabilityCalculator.GetAlternative(2, (personDay.Person.IsWorker && simulatedMandatoryTours[3] == 0), choice == 2);
            alternative.Choice = 2;
            alternative.AddUtilityTerm(31, 1);

            //alternative.AddUtilityTerm(32, personDay.Person.IsChildUnder5.ToFlag());
            alternative.AddUtilityTerm(33, personDay.Person.WorksAtHome.ToFlag());
            alternative.AddUtilityTerm(34, personDay.Person.IsFulltimeWorker.ToFlag());
            alternative.AddUtilityTerm(35, personDay.Person.IsMale.ToFlag());
            //alternative.AddUtilityTerm(4, person.IsPartTimeWorker.ToFlag());

            alternative.AddUtilityTerm(36, (householdDay.AdultsInSharedHomeStay == 2 && householdDay.Household.HouseholdTotals.FullAndPartTimeWorkers >= 2).ToFlag());
            //alternative.AddUtilityTerm(14, (householdDay.AdultsInSharedHomeStay == 2).ToFlag());
            //alternative.AddUtilityTerm(15, (householdDay.Household.HouseholdTotals.FullAndPartTimeWorkers >= 2).ToFlag());
            alternative.AddUtilityTerm(37, (householdDay.AdultsInSharedHomeStay == 1 && householdDay.Household.HasChildren).ToFlag());

            alternative.AddUtilityTerm(38, workTourLogsum);

            //alternative.AddUtilityTerm(38, (householdDay.Household.VehiclesAvailable == 1 && household.Has2Drivers).ToFlag());
            alternative.AddUtilityTerm(39, (householdDay.Household.VehiclesAvailable >= 2 && household.Has2Drivers).ToFlag());

            alternative.AddUtilityTerm(40, householdDay.PrimaryPriorityTimeFlag);

            //alternative.AddNestedAlternative(12, 1, 60);

            // SCHOOL
            alternative        = choiceProbabilityCalculator.GetAlternative(3, schoolAvailableFlag, choice == 3);
            alternative.Choice = 3;
            alternative.AddUtilityTerm(41, 1);

            alternative.AddUtilityTerm(42, personDay.Person.IsNonworkingAdult.ToFlag());
            //alternative.AddUtilityTerm(43, personDay.Person.IsPartTimeWorker.ToFlag());
            alternative.AddUtilityTerm(43, personDay.Person.IsYouth.ToFlag());

            //alternative.AddUtilityTerm(46, (householdDay.AdultsInSharedHomeStay == 2 && householdDay.Household.HouseholdTotals.FullAndPartTimeWorkers >= 2).ToFlag());
            //alternative.AddUtilityTerm(14, (householdDay.AdultsInSharedHomeStay == 2).ToFlag());
            //alternative.AddUtilityTerm(15, (householdDay.Household.HouseholdTotals.FullAndPartTimeWorkers >= 2).ToFlag());
            //alternative.AddUtilityTerm(47, (householdDay.AdultsInSharedHomeStay == 1 && householdDay.Household.HasChildren).ToFlag());

            alternative.AddUtilityTerm(48, workTourLogsum);
            alternative.AddUtilityTerm(49, schoolTourLogsum);

            //alternative.AddUtilityTerm(48, (householdDay.Household.VehiclesAvailable == 1 && household.Has2Drivers).ToFlag());
            //alternative.AddUtilityTerm(49, (householdDay.Household.VehiclesAvailable >= 2 && household.Has2Drivers).ToFlag());

            alternative.AddUtilityTerm(50, householdDay.PrimaryPriorityTimeFlag);

            //alternative.AddNestedAlternative(12, 1, 60);
        }