private void RunModel(ChoiceProbabilityCalculator choiceProbabilityCalculator, HouseholdDayWrapper householdDay, int nCallsForTour, int[] purpose, int[][] altParticipants, int choice = Constants.DEFAULT_VALUE) { IEnumerable<PersonDayWrapper> orderedPersonDays = householdDay.PersonDays.OrderBy(p => p.GetJointTourParticipationPriority()).ToList().Cast<PersonDayWrapper>(); // set household characteristics here that don't depend on person characteristics int carOwnership = householdDay.Household.VehiclesAvailable == 0 ? Global.Settings.CarOwnerships.NoCars : householdDay.Household.VehiclesAvailable < householdDay.Household.HouseholdTotals.DrivingAgeMembers ? Global.Settings.CarOwnerships.LtOneCarPerAdult : Global.Settings.CarOwnerships.OneOrMoreCarsPerAdult; int hhsize = householdDay.Household.Size; int noCarsFlag = FlagUtility.GetNoCarsFlag(carOwnership); int carCompetitionFlag = FlagUtility.GetCarCompetitionFlag(carOwnership); int tourPurpose = purpose[nCallsForTour]; int escortPurpose = purpose[nCallsForTour] == Global.Settings.Purposes.Escort ? 1 : 0; int shopPurpose = purpose[nCallsForTour] == Global.Settings.Purposes.Shopping ? 1 : 0; int socialPurpose = (purpose[nCallsForTour] == Global.Settings.Purposes.Social ? 1 : 0); int recreationPurpose = (purpose[nCallsForTour] == Global.Settings.Purposes.Recreation) ? 1 : 0; int personalBusinessMedicalPurpose = (purpose[nCallsForTour] == Global.Settings.Purposes.PersonalBusiness || purpose[nCallsForTour] == Global.Settings.Purposes.Medical) ? 1 : 0; int meal = (purpose[nCallsForTour] == Global.Settings.Purposes.Meal) ? 1 : 0; int socialRecreationPurpose = (purpose[nCallsForTour] == Global.Settings.Purposes.Social || purpose[nCallsForTour] == Global.Settings.Purposes.Recreation) ? 1 : 0; //nt recreationPurpose = (purpose[nCallsForTour] == Global.Settings.Purposes.Recreation) ? 1 : 0; int votALSegment = householdDay.Household.GetVotALSegment(); int transitAccessSegment = householdDay.Household.ResidenceParcel.TransitAccessSegment(); double totalAggregateLogsum = Global.AggregateLogsums[householdDay.Household.ResidenceParcel.ZoneId] [Global.Settings.Purposes.HomeBasedComposite][carOwnership][votALSegment][transitAccessSegment]; PersonDayWrapper pPersonDay = null; bool[] pLessThan3NonMandatoryTours = new bool[6]; bool[] pLessThan3TourPurposes = new bool[6]; int[] pUsualLocationParcelId = new int[6]; int[] pUsualLocationZoneId = new int[6]; IParcelWrapper[] pUsualLocationParcel = new IParcelWrapper[6]; int[] pPatternType = new int[6]; int[] pConstant = new int[6]; int[,] pType = new int[9, 6]; int[] pAdult = new int[6]; int[] pChild = new int[6]; int[] pAge = new int[6]; //int[] pAdultMale = new int[6]; int[] pAdultFemale = new int[6]; int[] pAdultMandatory = new int[6]; int[] pNonMandatory = new int[6]; int[] pMandatory = new int[6]; int[] pAdultNonMandatory = new int[6]; int[] pAdultWithChildrenUnder16 = new int[6]; int[] pAge5To8 = new int[6]; int[] pAge9To12 = new int[6]; int[] pAge13To15 = new int[6]; int[] pAgeUnder13 = new int[6]; int[] pTransit = new int[6]; //int[] pJointNonMandatoryTours = new int[6]; int[] pJointEscortTours = new int[6]; int[] pMandatoryTours = new int[6]; int[] pJointSocialRecreationTours = new int[6]; //int[] pJointPersMedtours = new int[6]; int[] pNonMandatoryChild = new int[6]; int[] pMandatoryChild = new int[6]; //int[] pJointShopTours = new int[6]; int[] pJointMealTours = new int[6]; int count = 0; foreach (PersonDayWrapper personDay in orderedPersonDays) { count++; if (count <= 5) { if (count == 1) { pPersonDay = personDay; } for (int i = 1; i < 9; i++) { pType[personDay.Person.PersonType, count] = 1; } if (personDay.Person.IsFullOrPartTimeWorker && personDay.Person.UsualWorkParcel != null) { pUsualLocationParcelId[count] = personDay.Person.UsualWorkParcelId; pUsualLocationParcel[count] = personDay.Person.UsualWorkParcel; pUsualLocationZoneId[count] = personDay.Person.UsualWorkParcel.ZoneId; } else if (personDay.Person.IsStudent && personDay.Person.UsualSchoolParcel != null) { pUsualLocationParcelId[count] = personDay.Person.UsualSchoolParcelId; pUsualLocationParcel[count] = personDay.Person.UsualSchoolParcel; pUsualLocationZoneId[count] = personDay.Person.UsualSchoolParcel.ZoneId; } else if (personDay.Person.IsWorker && personDay.Person.IsNotFullOrPartTimeWorker && personDay.Person.UsualWorkParcel != null) { pUsualLocationParcelId[count] = personDay.Person.UsualWorkParcelId; pUsualLocationParcel[count] = personDay.Person.UsualWorkParcel; pUsualLocationZoneId[count] = personDay.Person.UsualWorkParcel.ZoneId; } else { pUsualLocationParcelId[count] = personDay.Household.ResidenceParcelId; pUsualLocationParcel[count] = personDay.Household.ResidenceParcel; pUsualLocationZoneId[count] = personDay.Household.ResidenceZoneId; } pLessThan3NonMandatoryTours[count] = personDay.GetCreatedNonMandatoryTours() < 3; pLessThan3TourPurposes[count] = personDay.GetTotalCreatedTourPurposes() < 3; pPatternType[count] = personDay.PatternType; pConstant[count] = 1; pAdult[count] = personDay.Person.IsAdult.ToFlag(); pChild[count] = (!(personDay.Person.IsAdult)).ToFlag(); pAdultWithChildrenUnder16[count] = (personDay.Person.IsAdult && personDay.Household.HasChildrenUnder16).ToFlag(); pAdultFemale[count] = personDay.Person.IsAdultFemale.ToFlag(); //pAdultMale[count] = personDay.Person.IsAdultMale.ToFlag(); pAdultMandatory[count] = personDay.Person.IsAdult.ToFlag() * (personDay.PatternType == Global.Settings.PatternTypes.Mandatory).ToFlag(); pNonMandatory[count] = (personDay.PatternType == Global.Settings.PatternTypes.Optional).ToFlag(); pAdultNonMandatory[count] = (personDay.PatternType == Global.Settings.PatternTypes.Optional).ToFlag() * personDay.Person.IsAdult.ToFlag(); pAgeUnder13[count] = (personDay.Person.Age < 13).ToFlag(); pAge5To8[count] = (personDay.Person.Age >= 5 && personDay.Person.Age <= 8).ToFlag(); //pAge9To12[count] = (personDay.Person.Age >= 9 && personDay.Person.Age <= 12).ToFlag(); pAge13To15[count] = (personDay.Person.Age >= 13 && personDay.Person.Age <= 15).ToFlag(); pTransit[count] = (personDay.Person.TransitPassOwnership == 1 ? 1 : 0); pMandatory[count] = (personDay.PatternType == Global.Settings.PatternTypes.Mandatory).ToFlag(); pMandatoryTours[count] = personDay.WorkTours + personDay.SchoolTours; pJointEscortTours[count] = personDay.CreatedEscortTours; pJointMealTours[count] = personDay.CreatedMealTours; //pJointShopTours[count]= personDay.CreatedShoppingTours; pJointSocialRecreationTours[count] = personDay.CreatedSocialTours + personDay.CreatedRecreationTours; pNonMandatoryChild[count] = (personDay.PatternType == Global.Settings.PatternTypes.Optional).ToFlag() * personDay.Person.IsChildUnder16.ToFlag(); pMandatoryChild[count] = (personDay.PatternType == Global.Settings.PatternTypes.Mandatory).ToFlag() * personDay.Person.IsChildUnder16.ToFlag(); } } int componentIndex = 0; //Create person utility components int[] componentPerson = new int[6]; for (int p = 1; p <= 5; p++) { // create component for basic person-purposes componentIndex++; componentPerson[p] = componentIndex; choiceProbabilityCalculator.CreateUtilityComponent(componentPerson[p]); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(01, pAge5To8[p]); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(02, pAdultFemale[p]); //choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(03, pAge9To12[p]); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(05, (pMandatoryTours[p] > 1).ToFlag()); //choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(06, (pJointNonMandatoryTours[p]>1).ToFlag()); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(07, pAdultMandatory[p]); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(08, pTransit[p]); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(21, pAdult[p] * escortPurpose); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(26, pType[6, p] * pNonMandatory[p] * escortPurpose); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(28, pType[8, p] * pNonMandatory[p] * escortPurpose); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(29, pType[6, p] * pMandatory[p] * escortPurpose); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(30, pType[7, p] * pMandatory[p] * escortPurpose); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(31, pType[8, p] * pMandatory[p] * escortPurpose); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(32, (pJointEscortTours[p] == 1).ToFlag() * escortPurpose); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(33, (pJointEscortTours[p] >= 2).ToFlag() * escortPurpose); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(41, pAdult[p] * personalBusinessMedicalPurpose); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(44, pNonMandatoryChild[p] * personalBusinessMedicalPurpose); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(45, pMandatoryChild[p] * personalBusinessMedicalPurpose); //choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(51, pAdultMandatory[p]* shopPurpose); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(52, pAdultNonMandatory[p] * shopPurpose); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(54, pNonMandatoryChild[p] * shopPurpose); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(56, pType[6, p] * pMandatory[p] * shopPurpose); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(57, pType[7, p] * pMandatory[p] * shopPurpose); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(58, pType[8, p] * pMandatory[p] * shopPurpose); //choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(59, (pJointShopTours[p]>1).ToFlag() * shopPurpose); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(71, pAdult[p] * meal); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(77, (pJointMealTours[p] > 0).ToFlag() * meal); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(92, pAdult[p] * socialRecreationPurpose); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(96, pType[6, p] * pMandatory[p] * socialRecreationPurpose); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(97, pType[7, p] * pMandatory[p] * socialRecreationPurpose); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(98, pType[8, p] * pMandatory[p] * socialRecreationPurpose); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(99, (pJointSocialRecreationTours[p] >= 1).ToFlag() * socialRecreationPurpose); } //create two-way match interaction utility components int[,] componentMatch = new int[6, 6]; int[,] iMatchAdult = new int[6, 6]; int[,] iMatchAdultWithChildrenUnder16 = new int[6, 6]; int[,] iMatchMandatoryAdults = new int[6, 6]; int[,] iMatchNonMandatoryAdults = new int[6, 6]; int[,] iMatchChild = new int[6, 6]; int[,] iMatchNonMandatoryKids = new int[6, 6]; int[,] iMatchMandatoryKids = new int[6, 6]; int[,] iMatchNonMandatory = new int[6, 6]; int[,] iMatchUsualLocation = new int[6, 6]; for (int t2 = 1; t2 <= 5; t2++) { for (int t1 = 1; t1 < t2; t1++) { //populate match variables iMatchAdultWithChildrenUnder16[t1, t2] = pAdultWithChildrenUnder16[t1] * pAdultWithChildrenUnder16[t2]; iMatchNonMandatoryAdults[t1, t2] = pAdultNonMandatory[t1] * pAdultNonMandatory[t2]; iMatchMandatoryAdults[t1, t2] = pAdultMandatory[t1] * pAdultMandatory[t2]; iMatchNonMandatory[t1, t2] = pNonMandatory[t1] * pNonMandatory[t2]; iMatchUsualLocation[t1, t2] = (pUsualLocationParcelId[t1] == pUsualLocationParcelId[t2]) ? 1 : 0; iMatchChild[t1, t2] = (1 - pAdult[t1]) * (1 - pAdult[t2]); iMatchNonMandatoryKids[t1, t2] = pNonMandatory[t1] * pAgeUnder13[t1] * pNonMandatory[t2] * pAgeUnder13[t2]; iMatchMandatoryKids[t1, t2] = pMandatory[t1] * pAgeUnder13[t1] * pMandatory[t2] * pAgeUnder13[t2]; //create and populate components componentIndex++; componentMatch[t1, t2] = componentIndex; choiceProbabilityCalculator.CreateUtilityComponent(componentMatch[t1, t2]); choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(109, iMatchNonMandatoryKids[t1, t2]); choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(110, iMatchMandatoryKids[t1, t2]); choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(111, iMatchMandatoryAdults[t1, t2]); //choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(113, iMatchAdultNonMandatorys[t1, t2]); choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(114, iMatchAdultWithChildrenUnder16[t1, t2]); choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(116, iMatchNonMandatory[t1, t2] * socialRecreationPurpose); choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(124, iMatchChild[t1, t2] * shopPurpose); choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(125, iMatchUsualLocation[t1, t2]); } } //create two-way cross interaction utility components int[,] componentCross = new int[6, 6]; int iCrossAgeUnder5AndNonMandatory; int iCrossAge5To12AndNonMandatory; int iCrossAge13To15AndNonMandatory; int iCrossDrivingAgeChildAndNonMandatory; int iCrossMandatoryAdAndChild; for (int t2 = 1; t2 <= 5; t2++) { for (int t1 = 1; t1 <= 5; t1++) { if (!(t1 == t2)) { //populate cross variables iCrossAge5To12AndNonMandatory = pAdultNonMandatory[t1] * (pAge5To8[t2] + pAge9To12[t2]); iCrossAgeUnder5AndNonMandatory = pAdultNonMandatory[t1] * pType[8, t2]; iCrossAge13To15AndNonMandatory = pNonMandatory[t1] * pAge13To15[t2]; iCrossDrivingAgeChildAndNonMandatory = pNonMandatory[t1] * pType[6, t2]; iCrossMandatoryAdAndChild = pAdultMandatory[t1] * pChild[t2]; //create and populate cross components componentIndex++; componentCross[t1, t2] = componentIndex; choiceProbabilityCalculator.CreateUtilityComponent(componentCross[t1, t2]); choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(133, iCrossAge13To15AndNonMandatory); choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(135, iCrossAgeUnder5AndNonMandatory * escortPurpose); choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(136, iCrossAgeUnder5AndNonMandatory * personalBusinessMedicalPurpose); choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(137, iCrossAgeUnder5AndNonMandatory * shopPurpose); choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(138, iCrossAgeUnder5AndNonMandatory * meal); choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(139, iCrossAgeUnder5AndNonMandatory * socialRecreationPurpose); choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(144, iCrossAge5To12AndNonMandatory * socialRecreationPurpose); //choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(145, iCrossMandatoryAdAndChild*escortPurpose); choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(146, iCrossMandatoryAdAndChild * personalBusinessMedicalPurpose); choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(147, iCrossMandatoryAdAndChild * shopPurpose); choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(148, iCrossMandatoryAdAndChild * meal); choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(149, iCrossMandatoryAdAndChild * socialRecreationPurpose); } } } //Generate utility funtions for the alternatives bool[] available = new bool[32]; bool[] chosen = new bool[32]; for (int alt = 0; alt < 32; alt++) { available[alt] = false; chosen[alt] = false; // set availability based on household size if (hhsize >= altParticipants[alt][6]) { available[alt] = true; } // restrict availability of alts that include less than 2 participants if (altParticipants[alt][7] < 2) { available[alt] = false; } // restrict availability if any participant has at-home patternType int numberAtHomePatternTypes = 0; for (int i = 1; i <= 5; i++) { if (altParticipants[alt][i] == 1 && pPatternType[i] == Global.Settings.PatternTypes.Home) { numberAtHomePatternTypes++; } } if (numberAtHomePatternTypes > 0) { available[alt] = false; } // restrict availability if any participant has 3 or more nonmandatory tours already for (int i = 1; i <= 5; i++) { if (altParticipants[alt][i] == 1 && !pLessThan3NonMandatoryTours[i]) { available[alt] = false; } } // restrict availability if any participant has 3 or more tour purposes already for (int i = 1; i <= 5; i++) { if (altParticipants[alt][i] == 1 && !pLessThan3TourPurposes[i]) { available[alt] = false; } } int numberOfParticipants = 0; int workersParticipating = 0; int numberOfParticipatingChildren = 0; int numberOfParticipatingAdults = 0; int numberOfAvailableChildren = 0; int numberOfAvailablePersons = 0; int numberOfAvailableAdults = 0; if (available[alt] == true) { for (int i = 1; i <= 5; i++) { if (pChild[i] == 1) { numberOfAvailableChildren++; numberOfAvailablePersons++; } if (pAdult[i] == 1) { numberOfAvailableChildren++; numberOfAvailableAdults++; } if (altParticipants[alt][i] == 1) { numberOfParticipants++; if (pType[0, i] == 1 || pType[1, i] == 1) { workersParticipating++; } if (pAdult[i] == 1) { numberOfParticipatingAdults++; } if (pChild[i] == 1) { numberOfParticipatingChildren++; } } } } // determine choice if (choice == alt) { chosen[alt] = true; } //Get the alternative ChoiceProbabilityCalculator.Alternative alternative = choiceProbabilityCalculator.GetAlternative(alt, available[alt], chosen[alt]); alternative.Choice = alt; //Add alt-specific utility terms alternative.AddUtilityTerm(160, (numberOfParticipatingAdults > 1 && numberOfParticipatingChildren > 0) ? 1 : 0); //alternative.AddUtilityTerm(161, (numberOfParticipatingChildren < numberOfAvailableChildren) ? 1 : 0); //alternative.AddUtilityTerm(162, (numberOfParticipatingAdults >1).ToFlag() *socialRecreationPurpose); //alternative.AddUtilityTerm(163, (numberOfParticipatingAdults == 1).ToFlag() *personalBusinessMedicalPurpose); for (int p = 1; p <= 5; p++) { if (altParticipants[alt][p] == 1) { alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p])); } } for (int t2 = 1; t2 <= 5; t2++) { for (int t1 = 1; t1 < t2; t1++) { if (altParticipants[alt][t1] == 1 && altParticipants[alt][t2] == 1) { alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2])); } } } for (int t2 = 1; t2 <= 5; t2++) { for (int t1 = 1; t1 <= 5; t1++) { if (!(t1 == t2)) { if (altParticipants[alt][t1] == 1 && altParticipants[alt][t2] == 1) { alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2])); } } } } } }
private void RunModel(ChoiceProbabilityCalculator choiceProbabilityCalculator, HouseholdDayWrapper householdDay, int jHTSimulated, int genChoice, bool[,] jHTAvailable, bool[] fHTAvailable, int[][] altParticipants, int choice = Constants.DEFAULT_VALUE) { IEnumerable <PersonDayWrapper> orderedPersonDays = householdDay.PersonDays.OrderBy(p => p.GetJointHalfTourParticipationPriority()).ToList().Cast <PersonDayWrapper>(); PersonDayWrapper pPersonDay = null; // set household characteristics here that don't depend on person characteristics int hhsize = householdDay.Household.Size; int hhinc1 = householdDay.Household.Income <= 300000 ? 1 : 0; int hhinc2 = (householdDay.Household.Income > 300000 && householdDay.Household.Income <= 600000) ? 1 : 0; int hhinc3 = (householdDay.Household.Income > 600000 && householdDay.Household.Income <= 900000) ? 1 : 0; //int hhinc4 = (householdDay.Household.Income > 900000 && householdDay.Household.Income <= 1200000) ? 1 : 0; int hhinc4 = (householdDay.Household.Income > 900000) ? 1 : 0; IParcelWrapper[] pUsualLocation = new IParcelWrapper[6]; int[] pPatternType = new int[6]; int[] pConstant = new int[6]; int[] pType9 = new int[6]; int[] pType8 = new int[6]; int[] pType7 = new int[6]; int[] pType6 = new int[6]; int[] pType5 = new int[6]; int[] pType4 = new int[6]; int[] pType3 = new int[6]; int[] pType2 = new int[6]; int[] pType1 = new int[6]; int[] pAdult = new int[6]; int[] pAdultWithChildrenUnder16 = new int[6]; int[] pAdultFemale = new int[6]; int[] pAdultNonMandatory = new int[6]; int[] pType7AgeUnder12 = new int[6]; int[] pType7Age12Plus = new int[6]; int[] pAgeUnder12 = new int[6]; int[] pType8Mandatory = new int[6]; int[] pType8NonMandatory = new int[6]; int[] pType7Mandatory = new int[6]; int[] pType7NonMandatory = new int[6]; int[] pAgeUnder16 = new int[6]; int[] pYouthMandatory = new int[6]; int[] pYouthNonMandatory = new int[6]; int[] pYouth = new int[6]; int[] pAdultMandatory = new int[6]; int[] pMandatory = new int[6]; int[] pNonMandatory = new int[6]; bool[] pHasMandatoryTourToUsualLocation = new bool[6]; bool[] pIsDrivingAge = new bool[6]; int count = 0; foreach (PersonDayWrapper personDay in orderedPersonDays) { count++; if (count <= 5) { if (count == 1) { pPersonDay = personDay; } // set characteristics here that depend on person characteristics if (personDay.Person.IsFullOrPartTimeWorker) { pUsualLocation[count] = personDay.Person.UsualWorkParcel; } else if (personDay.Person.IsStudent) { pUsualLocation[count] = personDay.Person.UsualSchoolParcel; } else if (personDay.Person.IsWorker && personDay.Person.IsNotFullOrPartTimeWorker) { pUsualLocation[count] = personDay.Person.UsualWorkParcel; } else { pUsualLocation[count] = personDay.Household.ResidenceParcel; } pPatternType[count] = personDay.PatternType; pConstant[count] = 1; pType9[count] = personDay.Person.IsChildUnder16.ToFlag(); // not one og Type 1 to 8 pType8[count] = personDay.Person.IsChildUnder5.ToFlag(); // All ACTUM TU persons are one of Type 1 to 8 pType7[count] = personDay.Person.IsChildAge5Through15.ToFlag(); pType6[count] = personDay.Person.IsDrivingAgeStudent.ToFlag(); pType5[count] = personDay.Person.IsUniversityStudent.ToFlag(); pType4[count] = personDay.Person.IsNonworkingAdult.ToFlag(); pType3[count] = personDay.Person.IsRetiredAdult.ToFlag(); pType2[count] = personDay.Person.IsPartTimeWorker.ToFlag(); pType1[count] = personDay.Person.IsFulltimeWorker.ToFlag(); pAdult[count] = personDay.Person.IsAdult.ToFlag(); pAdultWithChildrenUnder16[count] = (personDay.Person.IsAdult && personDay.Household.HasChildrenUnder16).ToFlag(); // THIS person is adult and HH has child. under 16 pAdultFemale[count] = personDay.Person.IsAdultFemale.ToFlag(); pAdultNonMandatory[count] = (personDay.Person.IsAdult && personDay.PatternType == Global.Settings.PatternTypes.Optional).ToFlag(); pType7AgeUnder12[count] = (personDay.Person.IsChildAge5Through15 && personDay.Person.Age < 12).ToFlag(); // THIS person is both 5-15 AND below 12 pType7Age12Plus[count] = (personDay.Person.IsChildAge5Through15 && personDay.Person.Age >= 12).ToFlag(); pAgeUnder12[count] = (personDay.Person.Age < 12).ToFlag(); pAgeUnder16[count] = (personDay.Person.Age < 16).ToFlag(); pType8Mandatory[count] = (personDay.Person.IsChildUnder5 && personDay.PatternType == Global.Settings.PatternTypes.Mandatory).ToFlag(); pType8NonMandatory[count] = (personDay.Person.IsChildUnder5 && personDay.PatternType == Global.Settings.PatternTypes.Optional).ToFlag(); pType7Mandatory[count] = (personDay.Person.IsChildAge5Through15 && personDay.PatternType == Global.Settings.PatternTypes.Mandatory).ToFlag(); pType7NonMandatory[count] = (personDay.Person.IsChildAge5Through15 && personDay.PatternType == Global.Settings.PatternTypes.Optional).ToFlag(); pYouthMandatory[count] = (!personDay.Person.IsChildUnder5 && !personDay.Person.IsAdult && personDay.PatternType == Global.Settings.PatternTypes.Mandatory).ToFlag(); pYouthNonMandatory[count] = (!personDay.Person.IsChildUnder5 && !personDay.Person.IsAdult && personDay.PatternType == Global.Settings.PatternTypes.Optional).ToFlag(); pYouth[count] = (!personDay.Person.IsChildUnder5 && !personDay.Person.IsAdult).ToFlag(); pAdultMandatory[count] = (personDay.Person.IsAdult && personDay.PatternType == Global.Settings.PatternTypes.Mandatory).ToFlag(); pMandatory[count] = (personDay.PatternType == Global.Settings.PatternTypes.Mandatory).ToFlag(); pNonMandatory[count] = (personDay.PatternType == Global.Settings.PatternTypes.Optional).ToFlag(); pHasMandatoryTourToUsualLocation[count] = personDay.HasMandatoryTourToUsualLocation; pIsDrivingAge[count] = personDay.Person.IsDrivingAge; } } int componentIndex = 0; //Create person utility components int[] componentPerson = new int[6]; for (int p = 1; p <= 5; p++) { // create component for basic person-purposes componentIndex++; componentPerson[p] = componentIndex; choiceProbabilityCalculator.CreateUtilityComponent(componentPerson[p]); // these are dummies compared to base one, i.e. Type 5+6 in one. // OBS! - We apply "Adult Mandatory" as the base //choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(1, pAdultMandatory[p]); // impact of adult with mandatory travel choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(2, pAdultNonMandatory[p]); // impact of adult with non-mandatory travel choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(3, pType8Mandatory[p]); // impact of child under 5 with mandatory travel //GV: not significant, 14. june 2016 //choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(4, pType8NonMandatory[p]); // impact of child under 5 with non-mandatory travel //choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(04, pYouthMandatory[p]); // impact of youth with mandatory travel //choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(05, pYouthNonMandatory[p]); // impact of youth with non-mandatory travel choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(5, pType7Mandatory[p]); // impact of Child5-16 with mandatory travel //GV: not significant, 14. june 2016 //choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(6, pType7NonMandatory[p]); // impact of Child5-16 with non-mandatory travel choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(7, pAdultFemale[p]); //female } //create two-way match interaction utility components int[,] componentMatch = new int[6, 6]; int[,] iMatchAgeUnder12 = new int[6, 6]; int[,] iMatchAgeUnder16 = new int[6, 6]; int[,] iMatchAgeUnder5 = new int[6, 6]; int[,] iMatchAge5to16 = new int[6, 6]; int[,] iMatchAdult = new int[6, 6]; int[,] iMatchAdultWithChildrenUnder16 = new int[6, 6]; int[,] iMatchAdultWithChildrenUnder5 = new int[6, 6]; int[,] iMatchAdultMandatory = new int[6, 6]; int[,] iMatchAdultNonMandatory = new int[6, 6]; int[,] iMatchMandatory = new int[6, 6]; int[,] iMatchNonMandatory = new int[6, 6]; int[,] iMatchAdultMandatoryAndAdultMandatory = new int[6, 6]; int[,] iMatchAdultNonMandatoryAndAdultNonMandatory = new int[6, 6]; for (int t2 = 1; t2 <= 5; t2++) { for (int t1 = 1; t1 < t2; t1++) { // iMatch joints only persons of the same type // lets the base alt, be adult*adult iMatchAgeUnder12[t1, t2] = pAgeUnder12[t1] * pAgeUnder12[t2]; // children under 12 iMatchAgeUnder16[t1, t2] = pAgeUnder16[t1] * pAgeUnder16[t2]; // children under 16 iMatchAgeUnder5[t1, t2] = pType8[t1] * pType8[t2]; // children under 5 iMatchAge5to16[t1, t2] = pType7[t1] * pType7[t2]; // children 5 to 16 iMatchAdult[t1, t2] = pAdult[t1] * pAdult[t2]; // two adults (very important but difficult to understand) iMatchAdultMandatory[t1, t2] = pAdultMandatory[t1] * pAdultMandatory[t2]; // two adults with mandatory travel iMatchAdultNonMandatory[t1, t2] = pAdultNonMandatory[t1] * pAdultNonMandatory[t2]; // two adults with non-mandatory travel iMatchMandatory[t1, t2] = pMandatory[t1] * pMandatory[t2]; //those with mandatory iMatchNonMandatory[t1, t2] = pNonMandatory[t1] * pNonMandatory[t2]; //those tith non-mandatory //iMatchAdultWithChildrenUnder16[t1, t2] = pAdultWithChildrenUnder16[t1] * pAdultWithChildrenUnder16[t2]; iMatchAdultWithChildrenUnder16[t1, t2] = pAdult[t1] * pType7[t2]; //adult plus child 5-16 iMatchAdultWithChildrenUnder5[t1, t2] = pAdult[t1] * pType8[t2]; //adult plus child5 iMatchAdultMandatoryAndAdultMandatory[t1, t2] = pAdultMandatory[t1] * pAdultMandatory[t2]; //2 adults with Mandatory iMatchAdultNonMandatoryAndAdultNonMandatory[t1, t2] = pAdultNonMandatory[t1] * pAdultNonMandatory[t2]; //2 adults with Mandatory //create and populate components // OBS! - We apply "Adult * Adult" as the base componentIndex++; componentMatch[t1, t2] = componentIndex; choiceProbabilityCalculator.CreateUtilityComponent(componentMatch[t1, t2]); choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(21, iMatchAgeUnder5[t1, t2]); //GV: 14. jine 2016, not sign. //choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(22, iMatchAge5to16[t1, t2]); //choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(23, iMatchAdultMandatoryAndAdultMandatory[t1, t2]); //choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(24, iMatchAdultNonMandatoryAndAdultNonMandatory[t1, t2]); //choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(23, iMatchAdult[t1, t2]); //choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(24, iMatchAdultMandatory[t1, t2]); //choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(25, iMatchAdultNonMandatory[t1, t2]); // commented out 22nd, but they work well //choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(26, iMatchMandatory[t1, t2]); //choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(27, iMatchNonMandatory[t1, t2]); } } //create two-way cross interaction utility components int[,] componentCross = new int[6, 6]; int[,] iCrossAgeUnderTwelveAndAdult = new int[6, 6]; int[,] iCrossAgeUnderTwelveAndAdultNonMandatory = new int[6, 6]; int[,] iCrossAdultWithChildUnder5 = new int[6, 6]; int[,] iCrossAdultWithChild5to16 = new int[6, 6]; int[,] iCrossAdultFemaleWithChildUnder5 = new int[6, 6]; int[,] iCrossAdultFemaleWithChild5to16 = new int[6, 6]; int[,] iCrossAdultMandatoryAndAdultNonMandatory = new int[6, 6]; int[,] iCrossAdultMandatoryAndAdultMandatory = new int[6, 6]; int[,] iCrossAdultNonMandatoryAndAdultNonMandatory = new int[6, 6]; int[,] iCrossYouthAndChildUnder5 = new int[6, 6]; int[,] iCrossChild5to16AndChildUnder5 = new int[6, 6]; for (int t2 = 1; t2 <= 5; t2++) { for (int t1 = 1; t1 <= 5; t1++) { if (!(t1 == t2)) { //populate cross variables // again, one is base, all others are dummies iCrossAdultWithChildUnder5[t1, t2] = pAdult[t1] * pType8[t2]; //adult plus child5 iCrossAdultWithChild5to16[t1, t2] = pAdult[t1] * pType7[t2]; //adult plus child 5-16 iCrossAdultFemaleWithChildUnder5[t1, t2] = pAdultFemale[t1] * pType8[t2]; //adult mom plus child5 iCrossAdultFemaleWithChild5to16[t1, t2] = pAdult[t1] * pType7[t2]; //adult mom plus child 5-16 iCrossAgeUnderTwelveAndAdult[t1, t2] = pAgeUnder12[t1] * pAdult[t2]; iCrossAgeUnderTwelveAndAdultNonMandatory[t1, t2] = pAgeUnder12[t1] * pAdultNonMandatory[t2]; iCrossAdultMandatoryAndAdultNonMandatory[t1, t2] = pAdultMandatory[t1] * pAdultNonMandatory[t2]; iCrossAdultMandatoryAndAdultMandatory[t1, t2] = pAdultMandatory[t1] * pAdultMandatory[t2]; iCrossAdultNonMandatoryAndAdultNonMandatory[t1, t2] = pAdultNonMandatory[t1] * pAdultNonMandatory[t2]; iCrossYouthAndChildUnder5[t1, t2] = pYouth[t1] * pType8[t2]; iCrossChild5to16AndChildUnder5[t1, t2] = pType7[t1] * pType8[t2]; //create and populate cross components // OBS! - We apply "Adult Mandatory * Adult Non-mandatory" as the base componentIndex++; componentCross[t1, t2] = componentIndex; choiceProbabilityCalculator.CreateUtilityComponent(componentCross[t1, t2]); choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(41, iCrossAdultWithChildUnder5[t1, t2]); choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(42, iCrossAdultWithChild5to16[t1, t2]); //choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(43, iCrossAdultMandatoryAndAdultNonMandatory[t1, t2]); //GV: 14. june 2016, not sign. //choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(46, iCrossAdultFemaleWithChildUnder5[t1, t2]); //choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(47, iCrossYouthAndChildUnder5[t1, t2]); choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(47, iCrossChild5to16AndChildUnder5[t1, t2]); //choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(45, iCrossAdultFemaleWithChild5to16[t1, t2]); //choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(41, iCrossAgeUnderTwelveAndAdult[t1, t2]); //choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(42, iCrossAgeUnderTwelveAndAdultNonMandatory[t1, t2]); } } } //Generate utility funtions for the alternatives bool[] available = new bool[32]; bool[] chosen = new bool[32]; bool[] threeParticipants = new bool[32]; bool[] fourPlusParticipants = new bool[32]; for (int alt = 0; alt < 32; alt++) { available[alt] = false; chosen[alt] = false; // set availability based on household size if (hhsize >= altParticipants[alt][6]) { available[alt] = true; } // restrict availability based on person unavailability for (int i = 1; i <= 5; i++) { if (altParticipants[alt][i] == 1 && (jHTAvailable[genChoice - 1, i] == false || fHTAvailable[i] == false)) { available[alt] = false; } } // restrict availability to cases where all non-adult participants have same usual location // first determine first non-adult's usual location IParcelWrapper sameUsualLocation = householdDay.Household.ResidenceParcel; for (int i = 1; i <= 5; i++) { if (altParticipants[alt][i] == 1 && pPatternType[i] == 1 && pUsualLocation[i] != null && pUsualLocation[i].Id > 0 && !(pAdult[i] == 1)) { sameUsualLocation = pUsualLocation[i]; break; } } // then make alt unavailable if any M-Usual participant has a different usualLocation for (int i = 1; i <= 5; i++) { if (altParticipants[alt][i] == 1 && pHasMandatoryTourToUsualLocation[i] && !(pUsualLocation[i] == sameUsualLocation) && !(pAdult[i] == 1)) { available[alt] = false; break; } } // restrict availability of alts that include less than 2 participants if (altParticipants[alt][7] < 2) { available[alt] = false; } // restrict availability if 2+ participants lack tour to usual location int numberLackMandatoryTourToUsualLocation = 0; for (int i = 1; i <= 5; i++) { if (altParticipants[alt][i] == 1 && !pHasMandatoryTourToUsualLocation[i]) { numberLackMandatoryTourToUsualLocation++; } } if (numberLackMandatoryTourToUsualLocation > 1) { available[alt] = false; } // require at least one driving age (as chauffeur) //GV:out july 2013 //int numberDrivingAge = 0; //for (int i = 1; i <= 5; i++) { // if (altParticipants[alt][i] == 1 && pIsDrivingAge[i]) { // numberDrivingAge++; // } //} //if (numberDrivingAge == 0) { // available[alt] = false; //} double tourLogsum; int destinationArrivalTime = ChoiceModelUtility.GetDestinationArrivalTime(Global.Settings.Models.WorkTourModeModel); int destinationDepartureTime = ChoiceModelUtility.GetDestinationDepartureTime(Global.Settings.Models.WorkTourModeModel); //var nestedAlternative = ActumWorkTourModeModel.RunNested(pPersonDay, pPersonDay.Household.ResidenceParcel, sameUsualLocation, destinationArrivalTime, destinationDepartureTime, pPersonDay.Household.VehiclesAvailable); //var nestedAlternative = (Global.ChoiceModelDictionary.Get("ActumWorkTourModeModel") as ActumWorkTourModeModel).RunNested(personDay, residenceParcel, person.UsualWorkParcel, destinationArrivalTime, destinationDepartureTime, household.VehiclesAvailable); //JLB 201406 //var nestedAlternative = Global.ChoiceModelSession.Get<WorkTourModeModel>().RunNested(pPersonDay, pPersonDay.Household.ResidenceParcel, sameUsualLocation, destinationArrivalTime, destinationDepartureTime, pPersonDay.Household.VehiclesAvailable); //JLB 201602 //var nestedAlternative = Global.ChoiceModelSession.Get<WorkTourModeTimeModel>().RunNested(pPersonDay, pPersonDay.Household.ResidenceParcel, sameUsualLocation, destinationArrivalTime, destinationDepartureTime, pPersonDay.Household.VehiclesAvailable); ChoiceProbabilityCalculator.Alternative nestedAlternative = Global.ChoiceModelSession.Get <TourModeTimeModel>().RunNested(pPersonDay, pPersonDay.Household.ResidenceParcel, sameUsualLocation, destinationArrivalTime, destinationDepartureTime, pPersonDay.Household.VehiclesAvailable, Global.Settings.Purposes.Work); tourLogsum = nestedAlternative == null ? 0 : nestedAlternative.ComputeLogsum(); // determine choice if (choice == alt) { chosen[alt] = true; } //Get the alternative ChoiceProbabilityCalculator.Alternative alternative = choiceProbabilityCalculator.GetAlternative(alt, available[alt], chosen[alt]); alternative.Choice = alt; //Add utility terms that are not in components //alternative.AddUtilityTerm(399, 0); // OBS!!! This is new - 21nd January 2013 - it sais that these tris are less expected to be done with 3 or 4+ persons (compared to to people) alternative.AddUtilityTerm(59, altParticipants[alt][7] >= 3 ? 1 : 0); //alternative.AddUtilityTerm(60, altParticipants[alt][7] >= 4 ? 1 : 0); // OBS! no observations with 4+ HHsize alternative.AddUtilityTerm(58, tourLogsum); //Add utility components for (int p = 1; p <= 5; p++) { if (altParticipants[alt][p] == 1) { alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p])); } } for (int t2 = 1; t2 <= 5; t2++) { for (int t1 = 1; t1 < t2; t1++) { if (altParticipants[alt][t1] == 1 && altParticipants[alt][t2] == 1) { alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2])); } } } for (int t2 = 1; t2 <= 5; t2++) { for (int t1 = 1; t1 <= 5; t1++) { if (!(t1 == t2)) { if (altParticipants[alt][t1] == 1 && altParticipants[alt][t2] == 1) { alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2])); } } } } } }
private void RunModel(ChoiceProbabilityCalculator choiceProbabilityCalculator, IHouseholdDayWrapper householdDay, ITourWrapper tour, IParcelWrapper destinationParcel, int householdCars, int constrainedMode, int constrainedArrivalTime, int constrainedDepartureTime, HTourModeTime choice = null) { IHouseholdWrapper household = tour.Household; IPersonWrapper person = tour.Person; IPersonDayWrapper personDay = tour.PersonDay; Framework.DomainModels.Models.IHouseholdTotals householdTotals = household.HouseholdTotals; // household inputs int childrenUnder5 = householdTotals.ChildrenUnder5; int childrenAge5Through15 = householdTotals.ChildrenAge5Through15; int nonworkingAdults = householdTotals.NonworkingAdults; int retiredAdults = householdTotals.RetiredAdults; int onePersonHouseholdFlag = household.IsOnePersonHousehold.ToFlag(); int twoPersonHouseholdFlag = household.IsTwoPersonHousehold.ToFlag(); //var householdCars = household.VehiclesAvailable; MABADD now an input parameter int noCarsInHouseholdFlag = household.GetFlagForNoCarsInHousehold(householdCars); int carsLessThanDriversFlag = household.GetFlagForCarsLessThanDrivers(householdCars); int carsLessThanWorkersFlag = household.GetFlagForCarsLessThanWorkers(householdCars); int income0To25KFlag = household.Has0To25KIncome.ToFlag(); int income100KPlusFlag = household.Has100KPlusIncome.ToFlag(); // person inputs int partTimeWorkerFlag = person.IsPartTimeWorker.ToFlag(); int nonworkingAdultFlag = person.IsNonworkingAdult.ToFlag(); int universityStudentFlag = person.IsUniversityStudent.ToFlag(); int retiredAdultFlag = person.IsRetiredAdult.ToFlag(); int drivingAgeStudentFlag = person.IsDrivingAgeStudent.ToFlag(); int fulltimeWorkerFlag = person.IsFulltimeWorker.ToFlag(); int childAge5Through15Flag = person.IsChildAge5Through15.ToFlag(); int childUnder5Flag = person.IsChildUnder5.ToFlag(); int maleFlag = person.IsMale.ToFlag(); int ageUnder30Flag = person.AgeIsLessThan30.ToFlag(); int ageBetween51And98Flag = person.AgeIsBetween51And98.ToFlag(); int adultFlag = person.IsAdult.ToFlag(); // person-day inputs int homeBasedToursOnlyFlag = (personDay == null) ? 1 : personDay.OnlyHomeBasedToursExist().ToFlag(); int firstSimulatedHomeBasedTourFlag = (personDay == null) ? 1 : personDay.IsFirstSimulatedHomeBasedTour().ToFlag(); int laterSimulatedHomeBasedTourFlag = (personDay == null) ? 0 : personDay.IsLaterSimulatedHomeBasedTour().ToFlag(); int totalStops = (personDay == null) ? 0 : personDay.GetTotalStops(); int totalSimulatedStops = (personDay == null) ? 0 : personDay.GetTotalSimulatedStops(); int escortStops = (personDay == null) ? 0 : personDay.EscortStops; int homeBasedTours = (personDay == null) ? 1 : personDay.HomeBasedTours; int simulatedHomeBasedTours = (personDay == null) ? 0 : personDay.SimulatedHomeBasedTours; // tour inputs int escortTourFlag = tour.IsEscortPurpose().ToFlag(); int shoppingTourFlag = tour.IsShoppingPurpose().ToFlag(); int mealTourFlag = tour.IsMealPurpose().ToFlag(); int socialTourFlag = tour.IsSocialPurpose().ToFlag(); int personalBusinessTourFlag = tour.IsPersonalBusinessPurpose().ToFlag(); int recreationTourFlag = tour.IsRecreationPurpose().ToFlag(); int medicalTourFlag = tour.IsMedicalPurpose().ToFlag(); IParcelWrapper originParcel = tour.OriginParcel; //var destinationParcel = tour.DestinationParcel; MABADD now an input parameter int jointTourFlag = (tour.JointTourSequence > 0) ? 1 : 0; int partialHalfTour1Flag = (tour.PartialHalfTour1Sequence > 0) ? 1 : 0; int partialHalfTour2Flag = (tour.PartialHalfTour2Sequence > 0) ? 1 : 0; int fullHalfTour1Flag = (tour.FullHalfTour1Sequence > 0) ? 1 : 0; int fullHalfTour2Flag = (tour.FullHalfTour2Sequence > 0) ? 1 : 0; int parentTourMode = tour.ParentTour == null ? 0 : tour.ParentTour.Mode; // remaining inputs // Higher priority tour of 2+ tours for the same purpose int highPrioritySameFlag = (personDay == null) ? 1 : (tour.GetTotalToursByPurpose() > tour.GetTotalSimulatedToursByPurpose() && tour.GetTotalSimulatedToursByPurpose() == 1).ToFlag(); // Lower priority tour(s) of 2+ tours for the same purpose int lowPrioritySameFlag = (personDay == null) ? 0 : (tour.GetTotalSimulatedToursByPurpose() > 1).ToFlag(); // Higher priority tour of 2+ tours for different purposes int highPriorityDifferentFlag = (personDay == null) ? 0 : (personDay.IsFirstSimulatedHomeBasedTour() && personDay.HomeBasedToursExist()).ToFlag() * (1 - highPrioritySameFlag); // Lower priority tour of 2+ tours for different purposes int lowPriorityDifferentFlag = (personDay == null) ? 0 : (personDay.IsLaterSimulatedHomeBasedTour() && personDay.HomeBasedToursExist()).ToFlag() * (1 - lowPrioritySameFlag); ITimeWindow timeWindow = (householdDay == null) ? new TimeWindow() : tour.GetRelevantTimeWindow(householdDay); int totalMinutesAvailableInDay = timeWindow.TotalAvailableMinutes(1, 1440); int bigPeriodCount = DayPeriod.H_BIG_DAY_PERIOD_TOTAL_TOUR_TIMES; int nPeriodCombs = bigPeriodCount * (bigPeriodCount + 1) / 2; //set components int componentIndex = 0; int periodComb = -1; bool useTimeComponents = Global.Configuration.IsInEstimationMode || constrainedArrivalTime == 0 || constrainedDepartureTime == 0; if (useTimeComponents) { for (int arrivalPeriodIndex = 0; arrivalPeriodIndex < bigPeriodCount; arrivalPeriodIndex++) { MinuteSpan arrivalPeriod = DayPeriod.HBigDayPeriods[arrivalPeriodIndex]; int arrivalPeriodAvailableMinutes = timeWindow.TotalAvailableMinutes(arrivalPeriod.Start, arrivalPeriod.End); for (int departurePeriodIndex = arrivalPeriodIndex; departurePeriodIndex < bigPeriodCount; departurePeriodIndex++) { MinuteSpan departurePeriod = DayPeriod.HBigDayPeriods[departurePeriodIndex]; int departurePeriodAvailableMinutes = timeWindow.TotalAvailableMinutes(departurePeriod.Start, departurePeriod.End); if (arrivalPeriod == departurePeriod) { componentIndex = arrivalPeriodIndex; choiceProbabilityCalculator.CreateUtilityComponent(componentIndex); ChoiceProbabilityCalculator.Component arrivalComponent = choiceProbabilityCalculator.GetUtilityComponent(componentIndex); if (arrivalPeriodAvailableMinutes > 0) { double hoursArrival = arrivalPeriod.Middle / 60.0; int firstCoef = 300; arrivalComponent.AddUtilityTerm(300, Math.Log(arrivalPeriodAvailableMinutes)); //arrival shift variables arrivalComponent.AddUtilityTerm(firstCoef + 2, partTimeWorkerFlag * hoursArrival); arrivalComponent.AddUtilityTerm(firstCoef + 3, nonworkingAdultFlag * hoursArrival); arrivalComponent.AddUtilityTerm(firstCoef + 4, universityStudentFlag * hoursArrival); arrivalComponent.AddUtilityTerm(firstCoef + 5, retiredAdultFlag * hoursArrival); arrivalComponent.AddUtilityTerm(firstCoef + 6, drivingAgeStudentFlag * hoursArrival); arrivalComponent.AddUtilityTerm(firstCoef + 7, childAge5Through15Flag * hoursArrival); arrivalComponent.AddUtilityTerm(firstCoef + 8, childUnder5Flag * hoursArrival); arrivalComponent.AddUtilityTerm(firstCoef + 9, escortTourFlag * hoursArrival); arrivalComponent.AddUtilityTerm(firstCoef + 10, shoppingTourFlag * hoursArrival); arrivalComponent.AddUtilityTerm(firstCoef + 11, mealTourFlag * hoursArrival); arrivalComponent.AddUtilityTerm(firstCoef + 12, socialTourFlag * hoursArrival); arrivalComponent.AddUtilityTerm(firstCoef + 13, personalBusinessTourFlag * hoursArrival); arrivalComponent.AddUtilityTerm(firstCoef + 14, recreationTourFlag * hoursArrival); arrivalComponent.AddUtilityTerm(firstCoef + 15, medicalTourFlag * hoursArrival); arrivalComponent.AddUtilityTerm(firstCoef + 16, income0To25KFlag * hoursArrival); arrivalComponent.AddUtilityTerm(firstCoef + 17, income100KPlusFlag * hoursArrival); arrivalComponent.AddUtilityTerm(firstCoef + 18, highPrioritySameFlag * hoursArrival); arrivalComponent.AddUtilityTerm(firstCoef + 19, lowPrioritySameFlag * hoursArrival); arrivalComponent.AddUtilityTerm(firstCoef + 20, highPriorityDifferentFlag * hoursArrival); arrivalComponent.AddUtilityTerm(firstCoef + 21, lowPriorityDifferentFlag * hoursArrival); arrivalComponent.AddUtilityTerm(firstCoef + 22, jointTourFlag * hoursArrival); arrivalComponent.AddUtilityTerm(firstCoef + 23, partialHalfTour1Flag * hoursArrival); arrivalComponent.AddUtilityTerm(firstCoef + 24, fullHalfTour1Flag * hoursArrival); arrivalComponent.AddUtilityTerm(firstCoef + 25, partialHalfTour2Flag * hoursArrival); arrivalComponent.AddUtilityTerm(firstCoef + 26, fullHalfTour2Flag * hoursArrival); } componentIndex = bigPeriodCount + departurePeriodIndex; choiceProbabilityCalculator.CreateUtilityComponent(componentIndex); ChoiceProbabilityCalculator.Component departureComponent = choiceProbabilityCalculator.GetUtilityComponent(componentIndex); if (departurePeriodAvailableMinutes > 0) { departureComponent.AddUtilityTerm(300, Math.Log(departurePeriodAvailableMinutes)); } } // set period combination component periodComb++; componentIndex = 2 * bigPeriodCount + periodComb; choiceProbabilityCalculator.CreateUtilityComponent(componentIndex); ChoiceProbabilityCalculator.Component combinationComponent = choiceProbabilityCalculator.GetUtilityComponent(componentIndex); if (arrivalPeriodAvailableMinutes > 0 && departurePeriodAvailableMinutes > 0) { double hoursDuration = (departurePeriod.Middle - arrivalPeriod.Middle) / 60.0; int firstCoef = 700; //combination constants combinationComponent.AddUtilityTerm(firstCoef + periodComb, 1.0); // duration shift variables combinationComponent.AddUtilityTerm(firstCoef + 31, escortTourFlag * hoursDuration); combinationComponent.AddUtilityTerm(firstCoef + 32, shoppingTourFlag * hoursDuration); combinationComponent.AddUtilityTerm(firstCoef + 33, mealTourFlag * hoursDuration); combinationComponent.AddUtilityTerm(firstCoef + 34, socialTourFlag * hoursDuration); combinationComponent.AddUtilityTerm(firstCoef + 35, personalBusinessTourFlag * hoursDuration); combinationComponent.AddUtilityTerm(firstCoef + 36, recreationTourFlag * hoursDuration); combinationComponent.AddUtilityTerm(firstCoef + 37, medicalTourFlag * hoursDuration); combinationComponent.AddUtilityTerm(firstCoef + 38, highPrioritySameFlag * hoursDuration); combinationComponent.AddUtilityTerm(firstCoef + 39, lowPrioritySameFlag * hoursDuration); combinationComponent.AddUtilityTerm(firstCoef + 40, highPriorityDifferentFlag * hoursDuration); combinationComponent.AddUtilityTerm(firstCoef + 41, lowPriorityDifferentFlag * hoursDuration); combinationComponent.AddUtilityTerm(firstCoef + 42, partTimeWorkerFlag * hoursDuration); combinationComponent.AddUtilityTerm(firstCoef + 43, jointTourFlag * hoursDuration); combinationComponent.AddUtilityTerm(firstCoef + 44, partialHalfTour1Flag * hoursDuration); combinationComponent.AddUtilityTerm(firstCoef + 45, fullHalfTour1Flag * hoursDuration); combinationComponent.AddUtilityTerm(firstCoef + 46, partialHalfTour2Flag * hoursDuration); combinationComponent.AddUtilityTerm(firstCoef + 47, fullHalfTour2Flag * hoursDuration); // peak-to-peak variables if (arrivalPeriod.Index == DayPeriod.AM_PEAK && departurePeriod.Index == DayPeriod.PM_PEAK) { combinationComponent.AddUtilityTerm(firstCoef + 48, fulltimeWorkerFlag); combinationComponent.AddUtilityTerm(firstCoef + 49, income0To25KFlag); combinationComponent.AddUtilityTerm(firstCoef + 50, income100KPlusFlag); } } } } } for (int mode = Global.Settings.Modes.Walk; mode <= Global.Settings.Modes.SchoolBus; mode++) { componentIndex = 2 * bigPeriodCount + nPeriodCombs + mode - 1; choiceProbabilityCalculator.CreateUtilityComponent(componentIndex); ChoiceProbabilityCalculator.Component modeComponent = choiceProbabilityCalculator.GetUtilityComponent(componentIndex); if (mode == Global.Settings.Modes.SchoolBus) { modeComponent.AddUtilityTerm(10, 1); modeComponent.AddUtilityTerm(11, childUnder5Flag); modeComponent.AddUtilityTerm(12, adultFlag); } else if (mode == Global.Settings.Modes.ParkAndRide) { modeComponent.AddUtilityTerm(10, 1); modeComponent.AddUtilityTerm(16, noCarsInHouseholdFlag); modeComponent.AddUtilityTerm(17, carsLessThanWorkersFlag); modeComponent.AddUtilityTerm(129, destinationParcel.MixedUse2Index1()); modeComponent.AddUtilityTerm(129, destinationParcel.TotalEmploymentDensity1() / 5000.0); modeComponent.AddUtilityTerm(129, destinationParcel.NetIntersectionDensity1() / 50.0); //modeComponent.AddUtilityTerm(123, Math.Log(destinationParcel.StopsTransitBuffer1 + 1)); } else if (mode == Global.Settings.Modes.Transit) { modeComponent.AddUtilityTerm(20, 1); // modeComponent.AddUtilityTerm(21, maleFlag); modeComponent.AddUtilityTerm(22, ageUnder30Flag); // modeComponent.AddUtilityTerm(23, ageBetween51And98Flag); modeComponent.AddUtilityTerm(24, income0To25KFlag); // modeComponent.AddUtilityTerm(25, income100KPlusFlag); modeComponent.AddUtilityTerm(26, noCarsInHouseholdFlag); modeComponent.AddUtilityTerm(27, carsLessThanDriversFlag); modeComponent.AddUtilityTerm(129, destinationParcel.MixedUse2Index1()); modeComponent.AddUtilityTerm(129, destinationParcel.TotalEmploymentDensity1() / 5000.0); modeComponent.AddUtilityTerm(129, destinationParcel.NetIntersectionDensity1() / 50.0); // modeComponent.AddUtilityTerm(124, originParcel.NetIntersectionDensity1()/50.0); // modeComponent.AddUtilityTerm(124, originParcel.HouseholdDensity1()/1000.0); // modeComponent.AddUtilityTerm(124, originParcel.MixedUse2Index1()); //modeComponent.AddUtilityTerm(123, Math.Log(destinationParcel.StopsTransitBuffer1 + 1)); //modeComponent.AddUtilityTerm(122, Math.Log(originParcel.StopsTransitBuffer1 + 1)); } else if (mode == Global.Settings.Modes.Hov3) { modeComponent.AddUtilityTerm(30, 1); modeComponent.AddUtilityTerm(31, childrenUnder5); modeComponent.AddUtilityTerm(32, childrenAge5Through15); modeComponent.AddUtilityTerm(34, nonworkingAdults + retiredAdults); modeComponent.AddUtilityTerm(38, onePersonHouseholdFlag); modeComponent.AddUtilityTerm(39, twoPersonHouseholdFlag); modeComponent.AddUtilityTerm(36, noCarsInHouseholdFlag); modeComponent.AddUtilityTerm(37, carsLessThanDriversFlag); } else if (mode == Global.Settings.Modes.Hov2) { modeComponent.AddUtilityTerm(31, childrenUnder5); modeComponent.AddUtilityTerm(32, childrenAge5Through15); modeComponent.AddUtilityTerm(34, nonworkingAdults + retiredAdults); modeComponent.AddUtilityTerm(36, noCarsInHouseholdFlag); modeComponent.AddUtilityTerm(37, carsLessThanDriversFlag); modeComponent.AddUtilityTerm(40, 1); modeComponent.AddUtilityTerm(41, onePersonHouseholdFlag); } else if (mode == Global.Settings.Modes.Sov) { // modeComponent.AddUtilityTerm(50, 1); // modeComponent.AddUtilityTerm(54, income0To25KFlag); modeComponent.AddUtilityTerm(55, income100KPlusFlag); modeComponent.AddUtilityTerm(57, carsLessThanWorkersFlag); } else if (mode == Global.Settings.Modes.Bike) { modeComponent.AddUtilityTerm(60, 1); modeComponent.AddUtilityTerm(61, maleFlag); modeComponent.AddUtilityTerm(62, ageUnder30Flag); modeComponent.AddUtilityTerm(63, ageBetween51And98Flag); // modeComponent.AddUtilityTerm(64, income0To25KFlag); // modeComponent.AddUtilityTerm(65, income100KPlusFlag); modeComponent.AddUtilityTerm(66, noCarsInHouseholdFlag); modeComponent.AddUtilityTerm(67, carsLessThanDriversFlag); modeComponent.AddUtilityTerm(169, destinationParcel.MixedUse4Index2()); modeComponent.AddUtilityTerm(169, destinationParcel.TotalEmploymentDensity2() / 20000.0); modeComponent.AddUtilityTerm(169, destinationParcel.NetIntersectionDensity2() / 200.0); modeComponent.AddUtilityTerm(164, originParcel.NetIntersectionDensity2() / 200.0); modeComponent.AddUtilityTerm(164, originParcel.HouseholdDensity2() / 4000.0); modeComponent.AddUtilityTerm(164, originParcel.MixedUse4Index2()); } else if (mode == Global.Settings.Modes.Walk) { modeComponent.AddUtilityTerm(70, 1.0); modeComponent.AddUtilityTerm(71, maleFlag); modeComponent.AddUtilityTerm(72, ageUnder30Flag); // modeComponent.AddUtilityTerm(73, ageBetween51And98Flag); // modeComponent.AddUtilityTerm(74, income0To25KFlag); modeComponent.AddUtilityTerm(75, income100KPlusFlag); // modeComponent.AddUtilityTerm(76, noCarsInHouseholdFlag); modeComponent.AddUtilityTerm(77, carsLessThanDriversFlag); modeComponent.AddUtilityTerm(179, destinationParcel.MixedUse4Index1()); modeComponent.AddUtilityTerm(179, destinationParcel.TotalEmploymentDensity1() / 5000.0); modeComponent.AddUtilityTerm(179, destinationParcel.NetIntersectionDensity1() / 50.0); modeComponent.AddUtilityTerm(179, originParcel.NetIntersectionDensity1() / 50.0); modeComponent.AddUtilityTerm(179, originParcel.HouseholdDensity1() / 1000.0); modeComponent.AddUtilityTerm(179, originParcel.MixedUse4Index1()); } if (mode == Global.Settings.Modes.Walk || mode == Global.Settings.Modes.Bike || mode == Global.Settings.Modes.Hov2 || mode == Global.Settings.Modes.Hov3 || mode == Global.Settings.Modes.Transit) { int firstCoef = 200 + 10 * mode; //modeComponent.AddUtilityTerm(firstCoef + 0, escortTourFlag); //modeComponent.AddUtilityTerm(firstCoef + 1, shoppingTourFlag); //modeComponent.AddUtilityTerm(firstCoef + 2, mealTourFlag); //modeComponent.AddUtilityTerm(firstCoef + 3, socialTourFlag); //modeComponent.AddUtilityTerm(firstCoef + 4, personalBusinessTourFlag); //modeComponent.AddUtilityTerm(firstCoef + 5, recreationTourFlag); // modeComponent.AddUtilityTerm(firstCoef + 6, medicalTourFlag); //modeComponent.AddUtilityTerm(firstCoef + 7, jointTourFlag); modeComponent.AddUtilityTerm(firstCoef + 8, Math.Min(partialHalfTour1Flag + partialHalfTour2Flag, 1.0)); modeComponent.AddUtilityTerm(firstCoef + 9, Math.Min(fullHalfTour1Flag + fullHalfTour2Flag, 1.0)); modeComponent.AddUtilityTerm(290 + mode, mode == parentTourMode ? 1 : 0); } modeComponent.AddUtilityTerm(298, mode >= Global.Settings.Modes.Sov && mode <= Global.Settings.Modes.Hov3 && parentTourMode == Global.Settings.Modes.Sov ? 1 : 0); modeComponent.AddUtilityTerm(299, mode >= Global.Settings.Modes.Sov && mode <= Global.Settings.Modes.Hov3 && parentTourMode >= Global.Settings.Modes.Hov2 && parentTourMode <= Global.Settings.Modes.Hov3 ? 1 : 0); } //loop on all alternatives, using modeTimes objects { foreach (HTourModeTime modeTimes in HTourModeTime.ModeTimes[ParallelUtility.threadLocalAssignedIndex.Value]) { MinuteSpan arrivalPeriod = modeTimes.ArrivalPeriod; int arrivalPeriodAvailableMinutes = timeWindow.TotalAvailableMinutes(arrivalPeriod.Start, arrivalPeriod.End); MinuteSpan departurePeriod = modeTimes.DeparturePeriod; int departurePeriodAvailableMinutes = timeWindow.TotalAvailableMinutes(departurePeriod.Start, departurePeriod.End); periodComb = modeTimes.PeriodCombinationIndex; int mode = modeTimes.Mode; int altIndex = modeTimes.Index; //set availabillity based on time window variables and any constrained choices bool available = (modeTimes.LongestFeasibleWindow != null) && (mode > 0) && (mode != Global.Settings.Modes.Sov || (tour.Person.IsDrivingAge && tour.Household.VehiclesAvailable > 0)) && (constrainedMode <= 0 || constrainedMode == mode) && (constrainedArrivalTime <= 0 || (constrainedArrivalTime >= arrivalPeriod.Start && constrainedArrivalTime <= arrivalPeriod.End)) && (constrainedDepartureTime <= 0 || (constrainedDepartureTime >= departurePeriod.Start && constrainedDepartureTime <= departurePeriod.End)); ChoiceProbabilityCalculator.Alternative alternative = choiceProbabilityCalculator.GetAlternative(altIndex, available, choice != null && choice.Index == altIndex); alternative.Choice = modeTimes; // JLB added 20130420 //alternative.AddNestedAlternative(HTourModeTime.TOTAL_TOUR_MODE_TIMES + periodComb + 1, periodComb, THETA_PARAMETER); if (Global.Configuration.IsInEstimationMode && choice != null && altIndex == choice.Index) { Global.PrintFile.WriteLine("Aper Dper Mode {0} {1} {2} Travel Times {3} {4} Window {5} {6}", arrivalPeriod.Index, departurePeriod.Index, mode, modeTimes.ModeAvailableToDestination ? modeTimes.TravelTimeToDestination : -1, modeTimes.ModeAvailableFromDestination ? modeTimes.TravelTimeFromDestination : -1, modeTimes.LongestFeasibleWindow != null ? modeTimes.LongestFeasibleWindow.Start : -1, modeTimes.LongestFeasibleWindow != null ? modeTimes.LongestFeasibleWindow.End : -1); } /* if (altIndex == 0) * { * alternative.AddUtilityTerm(991, tour.Household.Id); * alternative.AddUtilityTerm(992, tour.Person.Id); * alternative.AddUtilityTerm(993, tour.PersonDay.Day); * alternative.AddUtilityTerm(994, tour.Sequence); * alternative.AddUtilityTerm(995, constrainedMode); * alternative.AddUtilityTerm(996, constrainedArrivalTime); * alternative.AddUtilityTerm(997, constrainedDepartureTime); * alternative.AddUtilityTerm(998, tour.DestinationPurpose); * alternative.AddUtilityTerm(999, (tour.ParentTour == null) ? 0 : 1); * } */ //if in application mode and combination is not available, can skip the rest if (!Global.Configuration.IsInEstimationMode && !alternative.Available) { continue; } if (useTimeComponents) { // arrival period utility component alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(arrivalPeriod.Index)); // departure period utility component alternative.AddUtilityComponent( choiceProbabilityCalculator.GetUtilityComponent(bigPeriodCount + departurePeriod.Index)); // period combination utility component alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(2 * bigPeriodCount + periodComb)); } // mode utility component alternative.AddUtilityComponent( choiceProbabilityCalculator.GetUtilityComponent(2 * bigPeriodCount + nPeriodCombs + mode - 1)); //even in estimation mode, do not need the rest of the code if not available if (!alternative.Available) { continue; } // set parking cost for period combination double parkingDuration = (departurePeriod == arrivalPeriod ? (arrivalPeriod.End - arrivalPeriod.Start) / 2.0 : departurePeriod.Middle - arrivalPeriod.Middle) / 60.0; // parking at work is free if no paid parking at work and tour goes to usual workplace double destinationParkingCost = (!Global.Configuration.IsInEstimationMode && Global.Configuration.ShouldRunPayToParkAtWorkplaceModel && tour.Person.UsualWorkParcel != null && destinationParcel == tour.Person.UsualWorkParcel && person.PaidParkingAtWorkplace == 0) ? 0.0 : destinationParcel.ParkingCostBuffer1(parkingDuration); double parkingCostFraction = (mode == Global.Settings.Modes.Sov) ? 1.0 : (mode == Global.Settings.Modes.Hov2) ? 1.0 / Global.Configuration.Coefficients_HOV2CostDivisor_Work : (mode == Global.Settings.Modes.Hov3) ? 1.0 / Global.Configuration.Coefficients_HOV3CostDivisor_Work : 0.0; double minimumTimeNeeded = modeTimes.TravelTimeToDestination + modeTimes.TravelTimeFromDestination + Global.Settings.Times.MinimumActivityDuration; alternative.AddUtilityTerm(1, modeTimes.GeneralizedTimeToDestination + modeTimes.GeneralizedTimeFromDestination); //alternative.AddUtilityTerm(2, destinationParkingCost*parkingCostFraction); //alternative.AddUtilityTerm(3, // Math.Log(Math.Min(1140, modeTimes.LongestFeasibleWindow.End - modeTimes.LongestFeasibleWindow.Start - // minimumTimeNeeded + 1.0 ))); // JLB 20140204 replaced coeff 3 with a different time window formulation: time pressure // instead of having positive utility for increasing time window, have negative utility for decreasing time window alternative.AddUtilityTerm(3, Math.Log(Math.Max(Constants.EPSILON, 1 - Math.Pow(minimumTimeNeeded / (Math.Min(1140, modeTimes.LongestFeasibleWindow.End - modeTimes.LongestFeasibleWindow.Start)), 0.3) ))); //alternative.AddUtilityTerm(4, Math.Log((totalMinutesAvailableInDay + 1.0)/(minimumTimeNeeded + 1.0))); //alternative.AddUtilityTerm(4, // Math.Log(Math.Max(Constants.EPSILON, 1 - minimumTimeNeeded/(Math.Min(1140, totalMinutesAvailableInDay))))); //alternative.AddUtilityTerm(5, // (maleFlag == 0 && mode == Global.Settings.Modes.Walk && // arrivalPeriod.Index >= DayPeriod.EVENING) // ? 1 // : 0); // alternative.AddUtilityTerm(5, // (maleFlag == 0 && mode == Global.Settings.Modes.Walk && // departurePeriod.Index >= DayPeriod.EVENING) // ? 1 // : 0); } } }
private void RunModel(ChoiceProbabilityCalculator choiceProbabilityCalculator, IPersonDayWrapper personDay, DayPattern choice = null) { IHouseholdWrapper household = personDay.Household; IParcelWrapper residenceParcel = household.ResidenceParcel; IPersonWrapper person = personDay.Person; int carsPerDriver = household.GetCarsPerDriver(); double mixedDensity = residenceParcel.MixedUse3Index2(); double intersectionDensity = residenceParcel.IntersectionDensity34Minus1Buffer2(); double[] purposeLogsums = new double[Global.Settings.Purposes.TotalPurposes]; double[] atUsualLogsums = new double[3]; int carOwnership = person.GetCarOwnershipSegment(); int votSegment = person.Household.GetVotALSegment(); int transitAccess = residenceParcel.TransitAccessSegment(); if (person.UsualWorkParcel == null || person.UsualWorkParcelId == household.ResidenceParcelId) { purposeLogsums[Global.Settings.Purposes.Work] = 0; } else { int destinationArrivalTime = ChoiceModelUtility.GetDestinationArrivalTime(Global.Settings.Models.WorkTourModeModel); int destinationDepartureTime = ChoiceModelUtility.GetDestinationDepartureTime(Global.Settings.Models.WorkTourModeModel); ChoiceProbabilityCalculator.Alternative nestedAlternative = Global.ChoiceModelSession.Get <WorkTourModeModel>().RunNested(personDay, residenceParcel, person.UsualWorkParcel, destinationArrivalTime, destinationDepartureTime, household.VehiclesAvailable); purposeLogsums[Global.Settings.Purposes.Work] = nestedAlternative == null ? 0 : nestedAlternative.ComputeLogsum(); atUsualLogsums[Global.Settings.Purposes.Work] = Global.AggregateLogsums[person.UsualWorkParcel.ZoneId][Global.Settings.Purposes.HomeBasedComposite][carOwnership][votSegment][person.UsualWorkParcel.TransitAccessSegment()]; } if (person.UsualSchoolParcel == null || person.UsualSchoolParcelId == household.ResidenceParcelId) { purposeLogsums[Global.Settings.Purposes.School] = 0; } else { int destinationArrivalTime = ChoiceModelUtility.GetDestinationArrivalTime(Global.Settings.Models.SchoolTourModeModel); int destinationDepartureTime = ChoiceModelUtility.GetDestinationDepartureTime(Global.Settings.Models.SchoolTourModeModel); ChoiceProbabilityCalculator.Alternative nestedAlternative = Global.ChoiceModelSession.Get <SchoolTourModeModel>().RunNested(personDay, residenceParcel, person.UsualSchoolParcel, destinationArrivalTime, destinationDepartureTime, household.VehiclesAvailable); purposeLogsums[Global.Settings.Purposes.School] = nestedAlternative == null ? 0 : nestedAlternative.ComputeLogsum(); atUsualLogsums[Global.Settings.Purposes.School] = Global.AggregateLogsums[person.UsualSchoolParcel.ZoneId][Global.Settings.Purposes.HomeBasedComposite][carOwnership][votSegment][person.UsualSchoolParcel.TransitAccessSegment()]; } double compositeLogsum = Global.AggregateLogsums[household.ResidenceZoneId][Global.Settings.Purposes.HomeBasedComposite][carOwnership][votSegment][transitAccess]; purposeLogsums[Global.Settings.Purposes.Escort] = Global.AggregateLogsums[household.ResidenceZoneId][Global.Settings.Purposes.Escort][carOwnership][votSegment][transitAccess]; purposeLogsums[Global.Settings.Purposes.PersonalBusiness] = Global.AggregateLogsums[household.ResidenceZoneId][Global.Settings.Purposes.PersonalBusiness][carOwnership][votSegment][transitAccess]; purposeLogsums[Global.Settings.Purposes.Shopping] = Global.AggregateLogsums[household.ResidenceZoneId][Global.Settings.Purposes.Shopping][carOwnership][votSegment][transitAccess]; purposeLogsums[Global.Settings.Purposes.Meal] = Global.AggregateLogsums[household.ResidenceZoneId][Global.Settings.Purposes.Meal][carOwnership][votSegment][transitAccess]; purposeLogsums[Global.Settings.Purposes.Social] = Global.AggregateLogsums[household.ResidenceZoneId][Global.Settings.Purposes.Social][carOwnership][votSegment][transitAccess]; purposeLogsums[Global.Settings.Purposes.Recreation] = compositeLogsum; purposeLogsums[Global.Settings.Purposes.Medical] = compositeLogsum; for (int xPurpose = Global.Settings.Purposes.Work; xPurpose <= Global.Settings.Purposes.Social + 10; xPurpose++) { // extra components 1-5 are for 2,3,4,5,6 tour purposes // extra components 6-10 are for 2,3,4,5,6 stop puroposes // recode purpose to match coefficients int purpose = xPurpose <= Global.Settings.Purposes.Social ? xPurpose : xPurpose <= Global.Settings.Purposes.Social + 5 ? Global.Settings.Purposes.Social + 1 : Global.Settings.Purposes.Social + 2; // get correct multiplier on coefficients. double xMultiplier = xPurpose <= Global.Settings.Purposes.Social ? 1.0 : xPurpose <= Global.Settings.Purposes.Social + 5 ? Math.Log(xPurpose - Global.Settings.Purposes.Social + 1) : Math.Log(xPurpose - Global.Settings.Purposes.Social - 5 + 1); choiceProbabilityCalculator.CreateUtilityComponent(xPurpose); ChoiceProbabilityCalculator.Component component = choiceProbabilityCalculator.GetUtilityComponent(xPurpose); component.AddUtilityTerm(100 * purpose + 51, xMultiplier * person.IsFulltimeWorker.ToFlag()); component.AddUtilityTerm(100 * purpose + 2, xMultiplier * person.IsPartTimeWorker.ToFlag()); component.AddUtilityTerm(100 * purpose + 3, xMultiplier * person.IsRetiredAdult.ToFlag()); component.AddUtilityTerm(100 * purpose + 4, xMultiplier * person.IsNonworkingAdult.ToFlag()); component.AddUtilityTerm(100 * purpose + 5, xMultiplier * person.IsUniversityStudent.ToFlag()); component.AddUtilityTerm(100 * purpose + 6, xMultiplier * person.IsDrivingAgeStudent.ToFlag()); component.AddUtilityTerm(100 * purpose + 7, xMultiplier * person.IsChildAge5Through15.ToFlag()); component.AddUtilityTerm(100 * purpose + 8, xMultiplier * person.IsChildUnder5.ToFlag()); component.AddUtilityTerm(100 * purpose + 9, xMultiplier * household.Has0To25KIncome.ToFlag()); component.AddUtilityTerm(100 * purpose + 10, xMultiplier * household.Has25To45KIncome.ToFlag()); component.AddUtilityTerm(100 * purpose + 11, xMultiplier * household.Has75KPlusIncome.ToFlag()); component.AddUtilityTerm(100 * purpose + 12, xMultiplier * carsPerDriver); component.AddUtilityTerm(100 * purpose + 13, xMultiplier * person.IsOnlyAdult().ToFlag()); component.AddUtilityTerm(100 * purpose + 14, xMultiplier * person.IsOnlyFullOrPartTimeWorker().ToFlag()); component.AddUtilityTerm(100 * purpose + 15, xMultiplier * 0); component.AddUtilityTerm(100 * purpose + 16, xMultiplier * person.IsFemale.ToFlag() * person.IsAdult.ToFlag() * (!household.HasChildrenUnder16).ToFlag()); component.AddUtilityTerm(100 * purpose + 17, xMultiplier * person.IsFemale.ToFlag() * person.IsAdult.ToFlag() * household.HasChildrenUnder5.ToFlag()); component.AddUtilityTerm(100 * purpose + 18, xMultiplier * person.IsFemale.ToFlag() * person.IsAdult.ToFlag() * household.HasChildrenAge5Through15.ToFlag()); component.AddUtilityTerm(100 * purpose + 19, xMultiplier * person.IsMale.ToFlag() * person.IsAdult.ToFlag() * household.HasChildrenUnder5.ToFlag()); component.AddUtilityTerm(100 * purpose + 20, xMultiplier * person.IsMale.ToFlag() * person.IsAdult.ToFlag() * household.HasChildrenAge5Through15.ToFlag()); component.AddUtilityTerm(100 * purpose + 21, xMultiplier * person.AgeIsBetween18And25.ToFlag()); component.AddUtilityTerm(100 * purpose + 22, xMultiplier * person.AgeIsBetween26And35.ToFlag()); component.AddUtilityTerm(100 * purpose + 23, xMultiplier * person.AgeIsBetween51And65.ToFlag()); component.AddUtilityTerm(100 * purpose + 24, xMultiplier * person.WorksAtHome().ToFlag()); component.AddUtilityTerm(100 * purpose + 25, xMultiplier * mixedDensity); component.AddUtilityTerm(100 * purpose + 26, xMultiplier * intersectionDensity); component.AddUtilityTerm(100 * purpose + 27, xMultiplier * purposeLogsums[purpose]); component.AddUtilityTerm(100 * purpose + 28, xMultiplier * person.TransitPassOwnership); } // tour utility int tourComponentIndex = Global.Settings.Purposes.Social + 11; choiceProbabilityCalculator.CreateUtilityComponent(tourComponentIndex); ChoiceProbabilityCalculator.Component tourComponent = choiceProbabilityCalculator.GetUtilityComponent(tourComponentIndex); tourComponent.AddUtilityTerm(1401, carsPerDriver); tourComponent.AddUtilityTerm(1402, person.WorksAtHome().ToFlag()); tourComponent.AddUtilityTerm(1403, mixedDensity); tourComponent.AddUtilityTerm(1404, mixedDensity * person.IsChildAge5Through15.ToFlag()); tourComponent.AddUtilityTerm(1405, compositeLogsum); tourComponent.AddUtilityTerm(1406, person.TransitPassOwnership); // stop utility int stopComponentIndex = Global.Settings.Purposes.Social + 12; choiceProbabilityCalculator.CreateUtilityComponent(stopComponentIndex); ChoiceProbabilityCalculator.Component stopComponent = choiceProbabilityCalculator.GetUtilityComponent(stopComponentIndex); stopComponent.AddUtilityTerm(1411, carsPerDriver); stopComponent.AddUtilityTerm(1412, person.WorksAtHome().ToFlag()); stopComponent.AddUtilityTerm(1413, mixedDensity); stopComponent.AddUtilityTerm(1414, mixedDensity * person.IsChildAge5Through15.ToFlag()); stopComponent.AddUtilityTerm(1415, compositeLogsum); stopComponent.AddUtilityTerm(1416, person.TransitPassOwnership); for (int alternativeIndex = 0; alternativeIndex < TOTAL_ALTERNATIVES; alternativeIndex++) { DayPattern dayPattern = _dayPatterns[alternativeIndex]; bool available = // work tours and stops only available for workers (person.IsWorker || (dayPattern.WorkTours <= 0 && dayPattern.WorkStops <= 0)) && // school tours and stops only available for students with usual school parcel not at home ((person.IsStudent && person.UsualSchoolParcel != null && person.UsualSchoolParcel != person.Household.ResidenceParcel) || (dayPattern.SchoolTours <= 0 && dayPattern.SchoolStops <= 0)) && // school stops not available if usual school parcel is same as usual work parcel ((person.IsStudent && person.UsualSchoolParcel != null && person.UsualSchoolParcel != person.UsualWorkParcel) || (dayPattern.SchoolStops <= 0)); ChoiceProbabilityCalculator.Alternative alternative = choiceProbabilityCalculator.GetAlternative(alternativeIndex, available, choice != null && choice.Equals(dayPattern)); if (!Global.Configuration.IsInEstimationMode && !alternative.Available) { continue; } alternative.Choice = dayPattern; // components for the purposes for (int purpose = Global.Settings.Purposes.Work; purpose <= Global.Settings.Purposes.Social; purpose++) { if (dayPattern.Tours[purpose] > 0 || dayPattern.Stops[purpose] > 0) { alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(purpose)); if (dayPattern.Tours[purpose] > 0) { alternative.AddUtilityTerm(100 * purpose, 1); // tour purpose ASC alternative.AddUtilityTerm(100 * purpose + 29, purposeLogsums[purpose]); // tour purpose logsum alternative.AddUtilityTerm(100 * purpose + 30, person.PaidParkingAtWorkplace); // only use for work purpose } if (dayPattern.Stops[purpose] > 0) { alternative.AddUtilityTerm(100 * purpose + 1, 1); // stop purpose ASC alternative.AddUtilityTerm(100 * purpose + 31, purposeLogsums[purpose]); // stop purpose logsum } if (Global.Configuration.IsInEstimationMode) { alternative.AddUtilityTerm(100 * purpose + 32, 1 - person.PaperDiary); alternative.AddUtilityTerm(100 * purpose + 33, person.ProxyResponse); } } } // multiple tour purposes component if (dayPattern.TotalTours > 1) { alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(Global.Settings.Purposes.Social + (dayPattern.TotalTours - 1))); } // multiple stop purposes component if (dayPattern.TotalStops > 1) { alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(Global.Settings.Purposes.Social + 5 + (dayPattern.TotalStops - 1))); } for (int tourPurpose = Global.Settings.Purposes.Work; tourPurpose <= Global.Settings.Purposes.Social; tourPurpose++) { for (int stopPurpose = Global.Settings.Purposes.Work; stopPurpose <= Global.Settings.Purposes.Social - 1; stopPurpose++) { if (tourPurpose > Global.Settings.Purposes.School && stopPurpose <= Global.Settings.Purposes.School) { continue; } if (dayPattern.Tours[tourPurpose] > 0 && dayPattern.Stops[stopPurpose] > 0) { alternative.AddUtilityTerm(1000 + 10 * tourPurpose + stopPurpose, 1); // tour-stop comb. utility } } } for (int tourPurpose = Global.Settings.Purposes.Work; tourPurpose <= Global.Settings.Purposes.School; tourPurpose++) { if (dayPattern.Tours[tourPurpose] == 1 && dayPattern.TotalStops >= 1) { alternative.AddUtilityTerm(1000 + 10 * tourPurpose, purposeLogsums[tourPurpose]); // usual location logsum x presence of stops in work or school pattern alternative.AddUtilityTerm(1000 + 10 * tourPurpose + 8, compositeLogsum); // home aggregate logsum x presence of stops in work or school pattern alternative.AddUtilityTerm(1000 + 10 * tourPurpose + 9, atUsualLogsums[tourPurpose]); // at usual location aggregate logsum x presence of stops in work or school pattern } } for (int tourPurpose = Global.Settings.Purposes.Work; tourPurpose <= Global.Settings.Purposes.Social - 2; tourPurpose++) { for (int tourPurpose2 = tourPurpose + 1; tourPurpose2 <= Global.Settings.Purposes.Social; tourPurpose2++) { if (dayPattern.Tours[tourPurpose] > 0 && dayPattern.Tours[tourPurpose2] > 0) { alternative.AddUtilityTerm(1100 + 10 * tourPurpose + tourPurpose2, 1); // tour-tour comb. utility } } } for (int stopPurpose = Global.Settings.Purposes.Work; stopPurpose <= Global.Settings.Purposes.Social - 2; stopPurpose++) { for (int stopPurpose2 = stopPurpose + 1; stopPurpose2 <= Global.Settings.Purposes.Social; stopPurpose2++) { if (dayPattern.Stops[stopPurpose] > 0 && dayPattern.Stops[stopPurpose2] > 0) { alternative.AddUtilityTerm(1200 + 10 * stopPurpose + stopPurpose2, 1); // stop-stop comb. utility } } } if (dayPattern.TotalTours > 0 && dayPattern.TotalStops > 0) { int totalStops = dayPattern.TotalStops; if (totalStops > 3) { totalStops = 3; } alternative.AddUtilityTerm(1300 + 10 * dayPattern.TotalTours + totalStops, 1); // nttour-ntstop utility } if (dayPattern.TotalTours - dayPattern.Tours[Global.Settings.Purposes.Work] - dayPattern.Tours[Global.Settings.Purposes.School] > 0) { // tour utility alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(tourComponentIndex)); } if (dayPattern.TotalStops - dayPattern.Stops[Global.Settings.Purposes.Work] - dayPattern.Stops[Global.Settings.Purposes.School] > 0) { // stop utility alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(stopComponentIndex)); } } }
private void RunModel(ChoiceProbabilityCalculator choiceProbabilityCalculator, ITourWrapper tour, TourTime choice = null) { IHouseholdWrapper household = tour.Household; IPersonWrapper person = tour.Person; IPersonDayWrapper personDay = tour.PersonDay; // household inputs int income0To25KFlag = household.Has0To25KIncome.ToFlag(); int income100KPlusFlag = household.Has100KPlusIncome.ToFlag(); // person inputs int partTimeWorkerFlag = person.IsPartTimeWorker.ToFlag(); int nonworkingAdultFlag = person.IsNonworkingAdult.ToFlag(); int universityStudentFlag = person.IsUniversityStudent.ToFlag(); int retiredAdultFlag = person.IsRetiredAdult.ToFlag(); int drivingAgeStudentFlag = person.IsDrivingAgeStudent.ToFlag(); int fulltimeWorkerFlag = person.IsFulltimeWorker.ToFlag(); int childAge5Through15Flag = person.IsChildAge5Through15.ToFlag(); int childUnder5Flag = person.IsChildUnder5.ToFlag(); // person-day inputs int homeBasedToursOnlyFlag = personDay.OnlyHomeBasedToursExist().ToFlag(); int firstSimulatedHomeBasedTourFlag = personDay.IsFirstSimulatedHomeBasedTour().ToFlag(); int laterSimulatedHomeBasedTourFlag = personDay.IsLaterSimulatedHomeBasedTour().ToFlag(); int totalStopPurposes = personDay.GetTotalStopPurposes(); // JLB 20150401 changed from GetTotalStops to assure consistent definition in apply and estimate int totalSimulatedStops = personDay.GetTotalSimulatedStops(); int escortStops = personDay.EscortStops; int homeBasedTours = personDay.HomeBasedTours; int simulatedHomeBasedTours = personDay.SimulatedHomeBasedTours; // tour inputs int escortTourFlag = tour.IsEscortPurpose().ToFlag(); int shoppingTourFlag = tour.IsShoppingPurpose().ToFlag(); int mealTourFlag = tour.IsMealPurpose().ToFlag(); int socialTourFlag = tour.IsSocialPurpose().ToFlag(); int personalBusinessTourFlag = tour.IsPersonalBusinessPurpose().ToFlag(); int sovOrHovTourFlag = tour.IsAnAutoMode().ToFlag(); int transitTourFlag = tour.UsesTransitModes().ToFlag(); // remaining inputs // Higher priority tour of 2+ tours for the same purpose int highPrioritySameFlag = (tour.GetTotalToursByPurpose() > tour.GetTotalSimulatedToursByPurpose() && tour.GetTotalSimulatedToursByPurpose() == 1).ToFlag(); // Lower priority tour(s) of 2+ tours for the same purpose int lowPrioritySameFlag = (tour.GetTotalSimulatedToursByPurpose() > 1).ToFlag(); // Higher priority tour of 2+ tours for different purposes int highPriorityDifferentFlag = (personDay.IsFirstSimulatedHomeBasedTour() && personDay.HomeBasedToursExist()).ToFlag() * (1 - highPrioritySameFlag); // Lower priority tour of 2+ tours for different purposes int lowPriorityDifferentFlag = (personDay.IsLaterSimulatedHomeBasedTour() && personDay.HomeBasedToursExist()).ToFlag() * (1 - lowPrioritySameFlag); ITimeWindow timeWindow = tour.ParentTour == null ? personDay.TimeWindow : tour.ParentTour.TimeWindow; ITourModeImpedance[] impedances = tour.GetTourModeImpedances(); int period1Middle = 15; int smallPeriodCount = DayPeriod.SmallDayPeriods.Count(); for (int periodIndex = 0; periodIndex < smallPeriodCount; periodIndex++) { // set arrival period component int arrivalPeriodIndex = periodIndex; double arrivalPeriodShift = arrivalPeriodIndex * (48.0 / DayPeriod.SMALL_DAY_PERIOD_TOTAL_TRIP_TIMES); //adjust shift amount if period lengths change MinuteSpan arrivalPeriod = DayPeriod.SmallDayPeriods[arrivalPeriodIndex]; int earlyArriveFlag = arrivalPeriod.Middle.IsBetween(Global.Settings.Times.ThreeAM, Global.Settings.Times.SevenAM).ToFlag(); ITourModeImpedance arrivalImpedance = impedances[arrivalPeriodIndex]; int arrivalPeriodAvailableMinutes = timeWindow.TotalAvailableMinutes(arrivalPeriod.Start, arrivalPeriod.End); choiceProbabilityCalculator.CreateUtilityComponent(3 * periodIndex + 0); ChoiceProbabilityCalculator.Component arrivalComponent = choiceProbabilityCalculator.GetUtilityComponent(3 * periodIndex + 0); if (arrivalPeriodAvailableMinutes > 0 || Global.Configuration.IsInEstimationMode) { arrivalComponent.AddUtilityTerm(11, arrivalPeriod.Middle.IsBetween(Global.Settings.Times.ThreeAM, Global.Settings.Times.SixAM).ToFlag()); arrivalComponent.AddUtilityTerm(12, arrivalPeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.SixAM, Global.Settings.Times.SevenAM).ToFlag()); arrivalComponent.AddUtilityTerm(13, arrivalPeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.SevenAM, Global.Settings.Times.EightAM).ToFlag()); arrivalComponent.AddUtilityTerm(14, arrivalPeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.EightAM, Global.Settings.Times.NineAM).ToFlag()); arrivalComponent.AddUtilityTerm(15, arrivalPeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.NineAM, Global.Settings.Times.TenAM).ToFlag()); arrivalComponent.AddUtilityTerm(16, arrivalPeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.TenAM, Global.Settings.Times.OnePM).ToFlag()); arrivalComponent.AddUtilityTerm(17, arrivalPeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.OnePM, Global.Settings.Times.FourPM).ToFlag()); arrivalComponent.AddUtilityTerm(18, arrivalPeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.FourPM, Global.Settings.Times.SevenPM).ToFlag()); arrivalComponent.AddUtilityTerm(19, arrivalPeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.SevenPM, Global.Settings.Times.TenPM).ToFlag()); arrivalComponent.AddUtilityTerm(20, arrivalPeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.TenPM, Global.Settings.Times.MinutesInADay).ToFlag()); arrivalComponent.AddUtilityTerm(41, partTimeWorkerFlag * arrivalPeriodShift); arrivalComponent.AddUtilityTerm(43, nonworkingAdultFlag * arrivalPeriodShift); arrivalComponent.AddUtilityTerm(45, universityStudentFlag * arrivalPeriodShift); arrivalComponent.AddUtilityTerm(47, retiredAdultFlag * arrivalPeriodShift); arrivalComponent.AddUtilityTerm(49, drivingAgeStudentFlag * arrivalPeriodShift); arrivalComponent.AddUtilityTerm(139, fulltimeWorkerFlag * arrivalPeriodShift); arrivalComponent.AddUtilityTerm(141, childAge5Through15Flag * arrivalPeriodShift); arrivalComponent.AddUtilityTerm(143, childUnder5Flag * arrivalPeriodShift); arrivalComponent.AddUtilityTerm(145, escortTourFlag * arrivalPeriodShift); arrivalComponent.AddUtilityTerm(147, shoppingTourFlag * arrivalPeriodShift); arrivalComponent.AddUtilityTerm(149, mealTourFlag * arrivalPeriodShift); arrivalComponent.AddUtilityTerm(151, socialTourFlag * arrivalPeriodShift); arrivalComponent.AddUtilityTerm(153, personalBusinessTourFlag * arrivalPeriodShift); arrivalComponent.AddUtilityTerm(51, income0To25KFlag * arrivalPeriodShift); arrivalComponent.AddUtilityTerm(53, income100KPlusFlag * arrivalPeriodShift); arrivalComponent.AddUtilityTerm(55, highPrioritySameFlag * arrivalPeriodShift); arrivalComponent.AddUtilityTerm(57, lowPrioritySameFlag * arrivalPeriodShift); arrivalComponent.AddUtilityTerm(155, highPriorityDifferentFlag * arrivalPeriodShift); arrivalComponent.AddUtilityTerm(157, lowPriorityDifferentFlag * arrivalPeriodShift); arrivalComponent.AddUtilityTerm(59, homeBasedToursOnlyFlag * arrivalPeriodShift); arrivalComponent.AddUtilityTerm(61, totalStopPurposes * homeBasedToursOnlyFlag * arrivalPeriodShift); arrivalComponent.AddUtilityTerm(63, totalStopPurposes * (1 - homeBasedToursOnlyFlag) * arrivalPeriodShift); arrivalComponent.AddUtilityTerm(65, (Math.Max(totalStopPurposes - totalSimulatedStops, 0)) * (1 - homeBasedToursOnlyFlag) * arrivalPeriodShift); arrivalComponent.AddUtilityTerm(67, escortStops * arrivalPeriodShift); arrivalComponent.AddUtilityTerm(69, tour.TotalSubtours * arrivalPeriodShift); arrivalComponent.AddUtilityTerm(72, income100KPlusFlag * earlyArriveFlag); arrivalComponent.AddUtilityTerm(175, escortTourFlag * earlyArriveFlag); arrivalComponent.AddUtilityTerm(176, shoppingTourFlag * earlyArriveFlag); arrivalComponent.AddUtilityTerm(177, mealTourFlag * earlyArriveFlag); arrivalComponent.AddUtilityTerm(85, sovOrHovTourFlag * arrivalImpedance.GeneralizedTimeFromOrigin * tour.TimeCoefficient); arrivalComponent.AddUtilityTerm(87, transitTourFlag * Math.Max(0, arrivalImpedance.GeneralizedTimeFromOrigin) * tour.TimeCoefficient); arrivalComponent.AddUtilityTerm(89, transitTourFlag * (arrivalImpedance.GeneralizedTimeFromOrigin < 0).ToFlag()); arrivalComponent.AddUtilityTerm(91, Math.Log(Math.Max(1, arrivalPeriodAvailableMinutes))); arrivalComponent.AddUtilityTerm(93, arrivalImpedance.AdjacentMinutesBefore * firstSimulatedHomeBasedTourFlag); arrivalComponent.AddUtilityTerm(95, arrivalImpedance.AdjacentMinutesBefore * laterSimulatedHomeBasedTourFlag); arrivalComponent.AddUtilityTerm(99, (Math.Max(totalStopPurposes - totalSimulatedStops, 0)) / (1D + arrivalImpedance.AdjacentMinutesBefore)); } // set departure period component int departurePeriodIndex = periodIndex; double departurePeriodShift = departurePeriodIndex * (48.0 / DayPeriod.SMALL_DAY_PERIOD_TOTAL_TRIP_TIMES); //adjust shift amount if period lengths change MinuteSpan departurePeriod = DayPeriod.SmallDayPeriods[departurePeriodIndex]; int lateDepartFlag = departurePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.NinePM, Global.Settings.Times.MinutesInADay).ToFlag(); ITourModeImpedance departureImpedance = impedances[departurePeriodIndex]; int departurePeriodAvailableMinutes = timeWindow.TotalAvailableMinutes(departurePeriod.Start, departurePeriod.End); choiceProbabilityCalculator.CreateUtilityComponent(3 * periodIndex + 1); ChoiceProbabilityCalculator.Component departureComponent = choiceProbabilityCalculator.GetUtilityComponent(3 * periodIndex + 1); if (departurePeriodAvailableMinutes > 0 || Global.Configuration.IsInEstimationMode) { departureComponent.AddUtilityTerm(21, departurePeriod.Middle.IsBetween(Global.Settings.Times.ThreeAM, Global.Settings.Times.SevenAM).ToFlag()); departureComponent.AddUtilityTerm(22, departurePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.SevenAM, Global.Settings.Times.TenAM).ToFlag()); departureComponent.AddUtilityTerm(23, departurePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.TenAM, Global.Settings.Times.OnePM).ToFlag()); departureComponent.AddUtilityTerm(24, departurePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.OnePM, Global.Settings.Times.ThreePM).ToFlag()); departureComponent.AddUtilityTerm(124, departurePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.ThreePM, Global.Settings.Times.FourPM).ToFlag()); departureComponent.AddUtilityTerm(25, departurePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.FourPM, Global.Settings.Times.FivePM).ToFlag()); departureComponent.AddUtilityTerm(26, departurePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.FivePM, Global.Settings.Times.SixPM).ToFlag()); departureComponent.AddUtilityTerm(27, departurePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.SixPM, Global.Settings.Times.SevenPM).ToFlag()); departureComponent.AddUtilityTerm(28, departurePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.SevenPM, Global.Settings.Times.NinePM).ToFlag()); departureComponent.AddUtilityTerm(29, departurePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.NinePM, Global.Settings.Times.Midnight).ToFlag()); departureComponent.AddUtilityTerm(30, departurePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.Midnight, Global.Settings.Times.MinutesInADay).ToFlag()); //added departureComponent.AddUtilityTerm(136, transitTourFlag * departurePeriodShift); departureComponent.AddUtilityTerm(137, transitTourFlag * lateDepartFlag); // departureComponent.AddUtilityTerm(73, income100KPlusFlag * lateDepartFlag); departureComponent.AddUtilityTerm(178, escortTourFlag * lateDepartFlag); departureComponent.AddUtilityTerm(179, shoppingTourFlag * lateDepartFlag); departureComponent.AddUtilityTerm(180, mealTourFlag * lateDepartFlag); departureComponent.AddUtilityTerm(86, sovOrHovTourFlag * departureImpedance.GeneralizedTimeFromDestination * tour.TimeCoefficient); departureComponent.AddUtilityTerm(88, transitTourFlag * Math.Max(0, departureImpedance.GeneralizedTimeFromDestination) * tour.TimeCoefficient); departureComponent.AddUtilityTerm(89, transitTourFlag * (departureImpedance.GeneralizedTimeFromDestination < 0).ToFlag()); departureComponent.AddUtilityTerm(92, Math.Log(Math.Max(1, departurePeriodAvailableMinutes))); departureComponent.AddUtilityTerm(94, departureImpedance.AdjacentMinutesAfter * firstSimulatedHomeBasedTourFlag); departureComponent.AddUtilityTerm(96, departureImpedance.AdjacentMinutesAfter * laterSimulatedHomeBasedTourFlag); departureComponent.AddUtilityTerm(100, (Math.Max(totalStopPurposes - totalSimulatedStops, 0)) / (1D + departureImpedance.AdjacentMinutesAfter)); } // set duration component (relative to period 1) double periodSpan = periodIndex * (48.0 / DayPeriod.SMALL_DAY_PERIOD_TOTAL_TRIP_TIMES); //adjust shift amount if period lengths change; if (arrivalPeriodIndex == 0) { period1Middle = arrivalPeriod.Middle; } int duration = departurePeriod.Middle - period1Middle; int durationUnder1HourFlag = ChoiceModelUtility.GetDurationUnder1HourFlag(duration); int duration1To2HoursFlag = ChoiceModelUtility.GetDuration1To2HoursFlag(duration); int durationUnder4HoursFlag = ChoiceModelUtility.GetDurationUnder4HoursFlag(duration); int durationUnder8HoursFlag = ChoiceModelUtility.GetDurationUnder8HoursFlag(duration); int durationUnder9HoursFlag = ChoiceModelUtility.GetDurationUnder9HoursFlag(duration); choiceProbabilityCalculator.CreateUtilityComponent(3 * periodIndex + 2); ChoiceProbabilityCalculator.Component durationComponent = choiceProbabilityCalculator.GetUtilityComponent(3 * periodIndex + 2); if (tour.IsWorkPurpose() || tour.IsSchoolPurpose()) { durationComponent.AddUtilityTerm(31, duration.IsRightExclusiveBetween(Global.Settings.Times.ZeroHours, Global.Settings.Times.ThreeHours).ToFlag()); durationComponent.AddUtilityTerm(32, duration.IsRightExclusiveBetween(Global.Settings.Times.ThreeHours, Global.Settings.Times.FiveHours).ToFlag()); durationComponent.AddUtilityTerm(33, duration.IsRightExclusiveBetween(Global.Settings.Times.FiveHours, Global.Settings.Times.SevenHours).ToFlag()); durationComponent.AddUtilityTerm(34, duration.IsRightExclusiveBetween(Global.Settings.Times.SevenHours, Global.Settings.Times.NineHours).ToFlag()); durationComponent.AddUtilityTerm(35, duration.IsRightExclusiveBetween(Global.Settings.Times.NineHours, Global.Settings.Times.TenHours).ToFlag()); durationComponent.AddUtilityTerm(36, duration.IsRightExclusiveBetween(Global.Settings.Times.TenHours, Global.Settings.Times.ElevenHours).ToFlag()); durationComponent.AddUtilityTerm(37, duration.IsRightExclusiveBetween(Global.Settings.Times.ElevenHours, Global.Settings.Times.TwelveHours).ToFlag()); durationComponent.AddUtilityTerm(38, duration.IsRightExclusiveBetween(Global.Settings.Times.TwelveHours, Global.Settings.Times.FourteenHours).ToFlag()); durationComponent.AddUtilityTerm(39, duration.IsRightExclusiveBetween(Global.Settings.Times.FourteenHours, Global.Settings.Times.EighteenHours).ToFlag()); durationComponent.AddUtilityTerm(40, (duration >= Global.Settings.Times.EighteenHours).ToFlag()); } else { durationComponent.AddUtilityTerm(31, duration.IsRightExclusiveBetween(Global.Settings.Times.ZeroHours, Global.Settings.Times.OneHour).ToFlag()); durationComponent.AddUtilityTerm(32, duration.IsRightExclusiveBetween(Global.Settings.Times.OneHour, Global.Settings.Times.TwoHours).ToFlag()); durationComponent.AddUtilityTerm(33, duration.IsRightExclusiveBetween(Global.Settings.Times.TwoHours, Global.Settings.Times.ThreeHours).ToFlag()); durationComponent.AddUtilityTerm(34, duration.IsRightExclusiveBetween(Global.Settings.Times.ThreeHours, Global.Settings.Times.FiveHours).ToFlag()); durationComponent.AddUtilityTerm(35, duration.IsRightExclusiveBetween(Global.Settings.Times.FiveHours, Global.Settings.Times.SevenHours).ToFlag()); durationComponent.AddUtilityTerm(36, duration.IsRightExclusiveBetween(Global.Settings.Times.SevenHours, Global.Settings.Times.NineHours).ToFlag()); durationComponent.AddUtilityTerm(37, duration.IsRightExclusiveBetween(Global.Settings.Times.NineHours, Global.Settings.Times.TwelveHours).ToFlag()); durationComponent.AddUtilityTerm(38, duration.IsRightExclusiveBetween(Global.Settings.Times.TwelveHours, Global.Settings.Times.FourteenHours).ToFlag()); durationComponent.AddUtilityTerm(39, duration.IsRightExclusiveBetween(Global.Settings.Times.FourteenHours, Global.Settings.Times.EighteenHours).ToFlag()); durationComponent.AddUtilityTerm(40, (duration >= Global.Settings.Times.EighteenHours).ToFlag()); } durationComponent.AddUtilityTerm(42, partTimeWorkerFlag * periodSpan); durationComponent.AddUtilityTerm(44, nonworkingAdultFlag * periodSpan); durationComponent.AddUtilityTerm(46, universityStudentFlag * periodSpan); durationComponent.AddUtilityTerm(48, retiredAdultFlag * periodSpan); durationComponent.AddUtilityTerm(50, drivingAgeStudentFlag * periodSpan); durationComponent.AddUtilityTerm(140, fulltimeWorkerFlag * periodSpan); durationComponent.AddUtilityTerm(142, childAge5Through15Flag * periodSpan); durationComponent.AddUtilityTerm(144, childUnder5Flag * periodSpan); durationComponent.AddUtilityTerm(146, escortTourFlag * periodSpan); durationComponent.AddUtilityTerm(148, shoppingTourFlag * periodSpan); durationComponent.AddUtilityTerm(150, mealTourFlag * periodSpan); durationComponent.AddUtilityTerm(152, socialTourFlag * periodSpan); durationComponent.AddUtilityTerm(154, personalBusinessTourFlag * periodSpan); durationComponent.AddUtilityTerm(52, income0To25KFlag * periodSpan); durationComponent.AddUtilityTerm(54, income100KPlusFlag * periodSpan); durationComponent.AddUtilityTerm(56, highPrioritySameFlag * periodSpan); durationComponent.AddUtilityTerm(58, lowPrioritySameFlag * periodSpan); durationComponent.AddUtilityTerm(156, highPriorityDifferentFlag * periodSpan); durationComponent.AddUtilityTerm(158, lowPriorityDifferentFlag * periodSpan); durationComponent.AddUtilityTerm(60, homeBasedToursOnlyFlag * periodSpan); durationComponent.AddUtilityTerm(62, totalStopPurposes * homeBasedToursOnlyFlag * periodSpan); durationComponent.AddUtilityTerm(64, totalStopPurposes * (1 - homeBasedToursOnlyFlag) * periodSpan); durationComponent.AddUtilityTerm(66, (Math.Max(totalStopPurposes - totalSimulatedStops, 0)) * (1 - homeBasedToursOnlyFlag) * periodSpan); durationComponent.AddUtilityTerm(68, escortStops * periodSpan); durationComponent.AddUtilityTerm(70, tour.TotalSubtours * periodSpan); durationComponent.AddUtilityTerm(71, fulltimeWorkerFlag * durationUnder9HoursFlag); durationComponent.AddUtilityTerm(169, escortTourFlag * durationUnder1HourFlag); durationComponent.AddUtilityTerm(170, shoppingTourFlag * durationUnder1HourFlag); durationComponent.AddUtilityTerm(171, mealTourFlag * durationUnder1HourFlag); durationComponent.AddUtilityTerm(172, escortTourFlag * duration1To2HoursFlag); durationComponent.AddUtilityTerm(173, shoppingTourFlag * duration1To2HoursFlag); durationComponent.AddUtilityTerm(174, mealTourFlag * duration1To2HoursFlag); durationComponent.AddUtilityTerm(81, highPrioritySameFlag * durationUnder8HoursFlag); durationComponent.AddUtilityTerm(82, lowPrioritySameFlag * durationUnder8HoursFlag); durationComponent.AddUtilityTerm(83, highPriorityDifferentFlag * durationUnder8HoursFlag); durationComponent.AddUtilityTerm(84, lowPriorityDifferentFlag * durationUnder4HoursFlag); } foreach (TourTime time in TourTime.Times) { bool available = (time.ArrivalPeriod.Index < time.DeparturePeriod.Index && timeWindow.EntireSpanIsAvailable(time.ArrivalPeriod.End, time.DeparturePeriod.Start)) || (time.ArrivalPeriod.Index == time.DeparturePeriod.Index && timeWindow.TotalAvailableMinutes(time.ArrivalPeriod.Start, time.ArrivalPeriod.End) > 1); ChoiceProbabilityCalculator.Alternative alternative = choiceProbabilityCalculator.GetAlternative(time.Index, available, choice != null && choice.Equals(time)); if (!alternative.Available && !Global.Configuration.IsInEstimationMode) { continue; } int arrivalPeriodIndex = time.ArrivalPeriod.Index; ITourModeImpedance arrivalImpedance = impedances[arrivalPeriodIndex]; int departurePeriodIndex = time.DeparturePeriod.Index; ITourModeImpedance departureImpedance = impedances[departurePeriodIndex]; alternative.Choice = time; // arrival period utility component alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(3 * time.ArrivalPeriod.Index + 0)); // departure period utility component alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(3 * time.DeparturePeriod.Index + 1)); // duration utility components alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(3 * (time.DeparturePeriod.Index - time.ArrivalPeriod.Index) + 2)); alternative.AddUtilityTerm(97, Math.Min(0.3, (homeBasedTours - simulatedHomeBasedTours) / (1.0 + arrivalImpedance.TotalMinutesBefore + departureImpedance.TotalMinutesAfter))); alternative.AddUtilityTerm(98, Math.Min(0.3, (homeBasedTours - simulatedHomeBasedTours) / (1.0 + Math.Max(arrivalImpedance.MaxMinutesBefore, departureImpedance.MaxMinutesAfter)))); } }
private void RunModel(ChoiceProbabilityCalculator choiceProbabilityCalculator, HouseholdDayWrapper householdDay, int jHTSimulated, int genChoice, bool[,] jHTAvailable, bool[] pHTAvailable, int[][] altParticipants, int choice = Constants.DEFAULT_VALUE) { IEnumerable <PersonDayWrapper> orderedPersonDays = householdDay.PersonDays.OrderBy(p => p.GetJointHalfTourParticipationPriority()).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; 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[] pType8Mandatory = new int[6]; int[] pType8NonMandatory = new int[6]; int[] pType7Mandatory = new int[6]; int[] pType7NonMandatory = new int[6]; int[] pType7Age12Plus = new int[6]; int[] pAgeUnder12 = 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]; 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; } 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(); } } 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 //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 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; goes to infinity //choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(22, iMatchAge5to16[t1, t2]); //choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(24, iMatchAdultNonMandatoryAndAdultNonMandatory[t1, t2]); //choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(23, iMatchAdult[t1, t2]); //base alt. //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]); //base alt. 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 || pHTAvailable[i] == false)) { available[alt] = false; } } // restrict availability if nobody is an adult bool altHasAdult = false; for (int i = 1; i <= 5; i++) { if (altParticipants[alt][i] == 1 && pAdult[i] > 0) { altHasAdult = true; } } if (!altHasAdult) { available[alt] = false; } // restrict availability if anybody has nonMandatory pattern type bool altHasNonMandatoryPatternType = false; for (int i = 1; i <= 5; i++) { if (altParticipants[alt][i] == 1 && !(pPatternType[i] == Global.Settings.PatternTypes.Mandatory)) { altHasNonMandatoryPatternType = true; } } if (altHasNonMandatoryPatternType) { available[alt] = false; } // restrict availability of alts that include less than 2 participants if (altParticipants[alt][7] < 2) { available[alt] = false; } // 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); //GV;; no observations, 18. april 2013 //alternative.AddUtilityTerm(60, altParticipants[alt][7] >= 4 ? 1 : 0); //no observations for 4+ HHsize //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 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>(); int pairedHalfTour = genChoice == 1 ? 1 : 0; int firstHalfTour = genChoice == 2 ? 1 : 0; int secondHalfTour = genChoice == 3 ? 1 : 0; // 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 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]; IPersonDayWrapper pPersonDay = null; IParcelWrapper[] pUsualLocation = new IParcelWrapper[6]; int[] pUsualLocationId = new int[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[] pAdultFemale = new int[6]; int[] pAdultMandatory = new int[6]; int[] pNonMandatory = new int[6]; int[] pFemaleNonMandatory = new int[6]; int[] pAdultWithChildrenUnder16 = new int[6]; int[] pType7AgeUnder12 = new int[6]; int[] pType7Age12Plus = new int[6]; int[] pAgeUnder13 = new int[6]; int[] pAge5To8 = new int[6]; int[] pAge9To12 = new int[6]; int[] pAge13To15 = new int[6]; int[] pTransitAdult = new int[6]; int[] pTransitChild = new int[6]; int[] pDrivingAge = 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 && personDay.Person.UsualWorkParcel != null) { pUsualLocation[count] = personDay.Person.UsualWorkParcel; } else if (personDay.Person.IsStudent && personDay.Person.UsualSchoolParcel != null) { pUsualLocation[count] = personDay.Person.UsualSchoolParcel; } else if (personDay.Person.IsWorker && personDay.Person.IsNotFullOrPartTimeWorker && personDay.Person.UsualWorkParcel != null) { pUsualLocation[count] = personDay.Person.UsualWorkParcel; } else { pUsualLocation[count] = personDay.Household.ResidenceParcel; } for (int i = 1; i < 9; i++) { pType[personDay.Person.PersonType, count] = 1; } 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(); pAdultMandatory[count] = personDay.Person.IsAdult.ToFlag() * (personDay.PatternType == Global.Settings.PatternTypes.Mandatory).ToFlag(); pNonMandatory[count] = (personDay.PatternType == Global.Settings.PatternTypes.Optional).ToFlag(); pFemaleNonMandatory[count] = personDay.Person.IsAdultFemale.ToFlag() * (personDay.PatternType == Global.Settings.PatternTypes.Optional).ToFlag(); pType7AgeUnder12[count] = (personDay.Person.IsChildAge5Through15 && personDay.Person.Age < 12).ToFlag(); pType7Age12Plus[count] = (personDay.Person.IsChildAge5Through15 && personDay.Person.Age >= 12).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(); pTransitAdult[count] = (personDay.Person.TransitPassOwnership == 1 ? 1 : 0) * (personDay.Person.IsAdult.ToFlag()); pTransitChild[count] = (personDay.Person.TransitPassOwnership == 1 ? 1 : 0) * ((!personDay.Person.IsAdult).ToFlag()); pDrivingAge[count] = personDay.Person.IsDrivingAge.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]); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(01, pType[1, p]); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(02, pType[2, p]); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(03, pType[3, p]); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(04, pType[4, p]); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(05, pType[5, p]); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(06, pType[6, p]); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(07, pType[7, p]); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(08, pType[8, p]); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(09, pAge5To8[p]); //choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(10, pAge9To12[p]); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(11, pAdultFemale[p]); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(12, pNonMandatory[p]); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(13, pFemaleNonMandatory[p]); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(14, pTransitAdult[p]); //choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(15, pTransitChild[p]); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(21, pType[1, p] * secondHalfTour); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(22, pType[2, p] * secondHalfTour); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(23, pType[3, p] * secondHalfTour); //choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(24, pType[4, p] * secondHalfTour); //choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(25, pType[5, p] * secondHalfTour); //choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(26, pType[6, p] * secondHalfTour); //choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(27, pType[7, p] * secondHalfTour); //choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(28, pType[8, p] * secondHalfTour); //choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(29, pAge5To8[p] * secondHalfTour); //choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(30, pAge9To12[p] * secondHalfTour); //choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(31, pAdultFemale[p] * secondHalfTour); //choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(32, pNonMandatory[p] * secondHalfTour); //choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(33, pFemaleNonMandatory[p] * secondHalfTour); //choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(34, pTransitAdult[p] * secondHalfTour); //choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(35, pTransitChild[p] * secondHalfTour); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(41, pType[1, p] * pairedHalfTour); //choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(42, pType[2, p] * pairedHalfTour); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(43, pType[3, p] * pairedHalfTour); //choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(44, pType[4, p] * pairedHalfTour); //choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(45, pType[5, p] * pairedHalfTour); //choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(46, pType[6, p] * pairedHalfTour); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(47, pType[7, p] * pairedHalfTour); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(48, pType[8, p] * pairedHalfTour); //choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(49, pAge5To8[p] * pairedHalfTour); //choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(50, pAge9To12[p] * pairedHalfTour); //choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(51, pAdultFemale[p] * pairedHalfTour); //choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(52, pNonMandatory[p] * pairedHalfTour); //choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(53, pFemaleNonMandatory[p] * pairedHalfTour); //choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(54, pTransitAdult[p] * pairedHalfTour); //choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(55, pTransitChild[p] * pairedHalfTour); } //create two-way match interaction utility components int[,] componentMatch = new int[6, 6]; int[,] iMatchAgeUnder13 = new int[6, 6]; int[,] iMatchAdult = new int[6, 6]; int[,] iMatchAdultWithChildrenUnder16 = new int[6, 6]; int[,] iMatchMandatoryAdults = new int[6, 6]; int[,] iMatchChild = new int[6, 6]; int[,] iMatchNonMandatory = new int[6, 6]; int[,] iMatchAdultsCarDeficit = new int[6, 6]; int[,] iMatchAdultCountAtHome = new int[6, 6]; for (int t2 = 1; t2 <= 5; t2++) { for (int t1 = 1; t1 < t2; t1++) { //populate match variables iMatchAgeUnder13[t1, t2] = pAgeUnder13[t1] * pAgeUnder13[t2]; iMatchAdult[t1, t2] = pAdult[t1] * pAdult[t2]; iMatchAdultWithChildrenUnder16[t1, t2] = pAdultWithChildrenUnder16[t1] * pAdultWithChildrenUnder16[t2]; iMatchMandatoryAdults[t1, t2] = pAdultMandatory[t1] * pAdultMandatory[t2]; iMatchChild[t1, t2] = (1 - pAdult[t1]) * (1 - pAdult[t2]); iMatchNonMandatory[t1, t2] = pNonMandatory[t1] * pNonMandatory[t2]; iMatchAdultsCarDeficit[t1, t2] = pAdult[t1] * pAdult[t2] * (carCompetitionFlag + noCarsFlag); //create and populate components componentIndex++; componentMatch[t1, t2] = componentIndex; choiceProbabilityCalculator.CreateUtilityComponent(componentMatch[t1, t2]); choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(61, iMatchAgeUnder13[t1, t2]); choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(62, iMatchAdult[t1, t2]); choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(63, iMatchMandatoryAdults[t1, t2]); choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(64, iMatchNonMandatory[t1, t2]); //choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(65, iMatchAdultWithChildrenUnder16[t1, t2]); choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(66, iMatchChild[t1, t2]); //choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(67, iMatchAdultsCarDeficit[t1, t2]); //choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(71, iMatchAgeUnder13[t1, t2] * secondHalfTour); //choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(72, iMatchAdult[t1, t2] * secondHalfTour); //choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(73, iMatchMandatoryAdults[t1, t2] * secondHalfTour); //choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(74, iMatchNonMandatory[t1, t2] * secondHalfTour); //choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(75, iMatchAdultWithChildrenUnder16[t1, t2] * secondHalfTour); //choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(76, iMatchChild[t1, t2] * secondHalfTour); //choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(77, iMatchAdultsCarDeficit[t1, t2] * secondHalfTour); //choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(81, iMatchAgeUnder13[t1, t2] * pairedHalfTour); //choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(82, iMatchAdult[t1, t2] * pairedHalfTour); choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(83, iMatchMandatoryAdults[t1, t2] * pairedHalfTour); //choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(84, iMatchNonMandatory[t1, t2] * pairedHalfTour); //choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(85, iMatchAdultWithChildrenUnder16[t1, t2] * pairedHalfTour); //choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(86, iMatchChild[t1, t2] * pairedHalfTour); //choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(87, iMatchAdultsCarDeficit[t1, t2] * pairedHalfTour); } } //create two-way cross interaction utility components int[,] componentCross = new int[6, 6]; int iCrossAgeUnder5AndNonMandatory; int iCrossAge5To12AndNonMandatory; int iCrossAge13To15AndNonMandatory; int iCrossDrivingAgeChildAndNonMandatory; for (int t2 = 1; t2 <= 5; t2++) { for (int t1 = 1; t1 <= 5; t1++) { if (!(t1 == t2)) { //populate cross variables iCrossAge5To12AndNonMandatory = pNonMandatory[t1] * (pAge5To8[t2] + pAge9To12[t2]); iCrossAgeUnder5AndNonMandatory = pNonMandatory[t1] * pType[8, t2]; iCrossAge13To15AndNonMandatory = pNonMandatory[t1] * pAge13To15[t2]; iCrossDrivingAgeChildAndNonMandatory = pNonMandatory[t1] * pType[6, t2]; //create and populate cross components componentIndex++; componentCross[t1, t2] = componentIndex; choiceProbabilityCalculator.CreateUtilityComponent(componentCross[t1, t2]); choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(91, iCrossAgeUnder5AndNonMandatory); //choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(92, iCrossAge5To12AndNonMandatory); choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(93, iCrossAge13To15AndNonMandatory); //choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(94, iCrossDrivingAgeChildAndNonMandatory); //choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(95, iCrossAgeUnder5AndNonMandatory * secondHalfTour); //choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(96, iCrossAgeUnder5AndNonMandatory * pairedHalfTour); } } } //Generate utility funtions for the alternatives bool[] available = new bool[32]; bool[] chosen = new bool[32]; int numberOfParticipants; int workersParticipating; int numberOfParticipatingChildren; int numberOfParticipatingAdults; int numberOfAvailableChildren; int numberOfAvailablePersons; int numberOfAvailableAdults; 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-driving age 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].Id > 0 && !(pDrivingAge[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].Id == sameUsualLocation.Id) && !(pDrivingAge[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; } //JLB 20140404 remove the drivign age requirement because children can walk, bik or take bus to/from school without an adult. // require at least one driving age (as chauffeur) //int numberDrivingAge = 0; //for (int i = 1; i <= 5; i++) { // if (altParticipants[alt][i] == 1 && pIsDrivingAge[i]) { // numberDrivingAge++; // } //} //if (numberDrivingAge == 0) { // available[alt] = false; //} // Generate alt-specific variables numberOfParticipants = 0; workersParticipating = 0; numberOfParticipatingChildren = 0; numberOfParticipatingAdults = 0; numberOfAvailableChildren = 0; numberOfAvailablePersons = 0; numberOfAvailableAdults = 0; if (available[alt] == true) { for (int i = 1; i <= 5; i++) { if (pChild[i] == 1 && pUsualLocation[i].Id == sameUsualLocation.Id) { numberOfAvailableChildren++; numberOfAvailablePersons++; } if (pAdult[i] == 1 && (pPatternType[i] == Global.Settings.PatternTypes.Optional || pUsualLocation[i].Id == sameUsualLocation.Id)) { 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++; } } } } double tourLogsum = 0; int destinationArrivalTime = ChoiceModelUtility.GetDestinationArrivalTime(Global.Settings.Models.WorkTourModeModel); int destinationDepartureTime = ChoiceModelUtility.GetDestinationDepartureTime(Global.Settings.Models.WorkTourModeModel); ChoiceProbabilityCalculator.Alternative nestedAlternative = Global.ChoiceModelSession.Get <WorkTourModeTimeModel>().RunNested(pPersonDay, pPersonDay.Household.ResidenceParcel, sameUsualLocation, destinationArrivalTime, destinationDepartureTime, pPersonDay.Household.VehiclesAvailable); 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 alt-specific utility terms alternative.AddUtilityTerm(101, (numberOfParticipatingAdults > 1 && numberOfParticipatingChildren > 0) ? 1 : 0); alternative.AddUtilityTerm(102, (numberOfParticipatingChildren < numberOfAvailableChildren) ? 1 : 0); alternative.AddUtilityTerm(103, (numberOfParticipatingAdults == 0) ? 1 : 0); //alternative.AddUtilityTerm(104, (numberOfParticipants < numberOfAvailablePersons) ? 1 : 0); alternative.AddUtilityTerm(105, tourLogsum); //alternative.AddUtilityTerm(105, ((numberOfParticipatingAdults > 1 && numberOfParticipatingChildren > 0) ? 1 : 0) * secondHalfTour); //alternative.AddUtilityTerm(106, ((numberOfParticipatingAdults > 1 && numberOfParticipatingChildren > 0) ? 1 : 0) * pairedHalfTour); //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 choice = Constants.DEFAULT_VALUE) { Framework.DomainModels.Wrappers.IHouseholdWrapper household = householdDay.Household; Framework.DomainModels.Wrappers.IParcelWrapper residenceParcel = household.ResidenceParcel; // set household characteristics here that don't depend on person characteristics int hasAdultEducLevel12 = 0; int youngestAge = 999; double firstWorkLogsum = 0; double secondWorkLogsum = 0; bool firstWorkLogsumIsSet = false; bool secondWorkLogsumIsSet = false; int numberWorkers = 0; int numberAdults = 0; int numberChildren = 0; int numberChildrenUnder5 = 0; // set characteristics here that depend on person characteristics foreach (PersonDayWrapper personDay in householdDay.PersonDays) { double workLogsum = 0; PersonWrapper person = (PersonWrapper)personDay.Person; if (person.UsualWorkParcel == null || person.UsualWorkParcelId == household.ResidenceParcelId || (person.PersonType != Global.Settings.PersonTypes.FullTimeWorker && person.PersonType != Global.Settings.PersonTypes.PartTimeWorker)) // || household.VehiclesAvailable == 0) { } else { int destinationArrivalTime = ChoiceModelUtility.GetDestinationArrivalTime(Global.Settings.Models.WorkTourModeModel); int destinationDepartureTime = ChoiceModelUtility.GetDestinationDepartureTime(Global.Settings.Models.WorkTourModeModel); //JLB 201406 //var nestedAlternative = Global.ChoiceModelSession.Get<WorkTourModeModel>().RunNested(personDay, residenceParcel, person.UsualWorkParcel, destinationArrivalTime, destinationDepartureTime, household.VehiclesAvailable); //JLB 201602 //var nestedAlternative = Global.ChoiceModelSession.Get<TourModeTimeModel>().RunNested(personDay, residenceParcel, person.UsualWorkParcel, destinationArrivalTime, destinationDepartureTime, household.VehiclesAvailable); ChoiceProbabilityCalculator.Alternative nestedAlternative = Global.ChoiceModelSession.Get <TourModeTimeModel>().RunNested(personDay, residenceParcel, person.UsualWorkParcel, destinationArrivalTime, destinationDepartureTime, household.VehiclesAvailable, Global.Settings.Purposes.Work); workLogsum = nestedAlternative == null ? 0 : nestedAlternative.ComputeLogsum(); } //if (person.Age >= 18 && person.EducationLevel >= 12) { // hasAdultEducLevel12 = 1; //} //if (person.Age >= 18 && person.EducationLevel < 12) { //} if (person.Age < youngestAge) { youngestAge = person.Age; } if (workLogsum != 0 && !firstWorkLogsumIsSet) { firstWorkLogsum = workLogsum; firstWorkLogsumIsSet = true; } else if (workLogsum != 0 && !secondWorkLogsumIsSet) { secondWorkLogsum = workLogsum; secondWorkLogsumIsSet = true; } if (person.Age >= 18) { numberAdults++; if (person.PersonType == Global.Settings.PersonTypes.FullTimeWorker //|| person.PersonType == Constants.PersonType.PART_TIME_WORKER ) { numberWorkers++; } } else { numberChildren++; if (person.PersonType == Global.Settings.PersonTypes.ChildUnder5) { numberChildrenUnder5++; } } } bool singleWorkerWithChildUnder5 = (numberAdults == numberWorkers && numberAdults == 1 && numberChildrenUnder5 > 0) ? true : false; bool workingCoupleNoChildren = (numberAdults == numberWorkers && numberAdults == 2 && numberChildren == 0) ? true : false; bool workingCoupleAllChildrenUnder5 = (numberAdults == numberWorkers && numberAdults == 2 && numberChildren > 0 && numberChildren == numberChildrenUnder5) ? true : false; bool otherHouseholdWithPTFTWorkers = false; if (!workingCoupleNoChildren && !workingCoupleAllChildrenUnder5 && firstWorkLogsum != 0) { otherHouseholdWithPTFTWorkers = true; } if (!workingCoupleNoChildren && !workingCoupleAllChildrenUnder5 && !otherHouseholdWithPTFTWorkers) { } // var votSegment = household.VotALSegment; //var taSegment = household.ResidenceParcel.TransitAccessSegment(); //var aggregateLogsumDifference = // full car ownership vs. no car ownership // Global.AggregateLogsums[household.ResidenceZoneId][Global.Settings.Purposes.HomeBasedComposite][Global.Settings.CarOwnerships.OneOrMoreCarsPerAdult][votSegment][taSegment] - // Global.AggregateLogsums[household.ResidenceZoneId][Global.Settings.Purposes.HomeBasedComposite][Global.Settings.CarOwnerships.NoCars][votSegment][taSegment]; //var householdDay = (ActumHouseholdDayWrapper)tour.HouseholdDay; int carOwnership = household.VehiclesAvailable == 0 ? Global.Settings.CarOwnerships.NoCars : household.VehiclesAvailable < household.HouseholdTotals.DrivingAgeMembers ? Global.Settings.CarOwnerships.LtOneCarPerAdult : Global.Settings.CarOwnerships.OneOrMoreCarsPerAdult; int noCarsFlag = FlagUtility.GetNoCarsFlag(carOwnership); int carCompetitionFlag = FlagUtility.GetCarCompetitionFlag(carOwnership); int votALSegment = Global.Settings.VotALSegments.Medium; // TODO: calculate a VOT segment that depends on household income int transitAccessSegment = household.ResidenceParcel.TransitAccessSegment(); double personalBusinessAggregateLogsum = Global.AggregateLogsums[household.ResidenceParcel.ZoneId] [Global.Settings.Purposes.PersonalBusiness][carOwnership][votALSegment][transitAccessSegment]; double shoppingAggregateLogsum = Global.AggregateLogsums[household.ResidenceParcel.ZoneId] [Global.Settings.Purposes.Shopping][carOwnership][votALSegment][transitAccessSegment]; double mealAggregateLogsum = Global.AggregateLogsums[household.ResidenceParcel.ZoneId] [Global.Settings.Purposes.Meal][carOwnership][votALSegment][transitAccessSegment]; double 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]; double compositeLogsum = Global.AggregateLogsums[household.ResidenceZoneId][Global.Settings.Purposes.HomeBasedComposite][Global.Settings.CarOwnerships.NoCars][votALSegment][transitAccessSegment]; int componentIndex = 0; for (int pfpt = 0; pfpt < 2; pfpt++) { if (pfpt == 1) { componentIndex = 1; choiceProbabilityCalculator.CreateUtilityComponent(componentIndex); ChoiceProbabilityCalculator.Component pfptComponent = choiceProbabilityCalculator.GetUtilityComponent(componentIndex); pfptComponent.AddUtilityTerm(1, (householdDay.Household.Size == 3).ToFlag()); pfptComponent.AddUtilityTerm(2, (householdDay.Household.Size >= 4).ToFlag()); pfptComponent.AddUtilityTerm(3, householdDay.Household.HasChildrenUnder5.ToFlag()); pfptComponent.AddUtilityTerm(4, (householdDay.AdultsInSharedHomeStay == 1 && householdDay.Household.HasChildrenAge5Through15).ToFlag()); pfptComponent.AddUtilityTerm(5, (householdDay.AdultsInSharedHomeStay == 2 && householdDay.Household.HouseholdTotals.FullAndPartTimeWorkers >= 2).ToFlag()); pfptComponent.AddUtilityTerm(6, (householdDay.AdultsInSharedHomeStay == 2 && hasAdultEducLevel12 == 1).ToFlag()); pfptComponent.AddUtilityTerm(7, (householdDay.Household.VehiclesAvailable == 1 && household.Has2Drivers).ToFlag()); pfptComponent.AddUtilityTerm(8, (householdDay.Household.VehiclesAvailable >= 2 && household.Has2Drivers).ToFlag()); pfptComponent.AddUtilityTerm(11, (householdDay.Household.Income >= 300000 && householdDay.Household.Income < 600000).ToFlag()); pfptComponent.AddUtilityTerm(12, (householdDay.Household.Income >= 600000 && householdDay.Household.Income < 900000).ToFlag()); pfptComponent.AddUtilityTerm(13, (householdDay.Household.Income >= 900000).ToFlag()); // OBS; 27. aug., work tour mode logsum does not work - see what happens in the old PFPT model // GV, sep. 1st - it is not significant pfptComponent.AddUtilityTerm(15, (firstWorkLogsum + secondWorkLogsum) * (workingCoupleNoChildren || workingCoupleAllChildrenUnder5).ToFlag()); pfptComponent.AddUtilityTerm(15, (firstWorkLogsum + secondWorkLogsum) * otherHouseholdWithPTFTWorkers.ToFlag()); // dette er gamle at-work logsum - it should be plus and significant //alternative.AddUtilityTerm(31, (firstWorkLogsum + secondWorkLogsum) * //(workingCoupleNoChildren || workingCoupleAllChildrenUnder5).ToFlag()); //alternative.AddUtilityTerm(31, (firstWorkLogsum + secondWorkLogsum) * otherHouseholdWithPTFTWorkers.ToFlag()); // at-home logsum works pfptComponent.AddUtilityTerm(16, compositeLogsum); //pfpt constant pfptComponent.AddUtilityTerm(51, 1); } } for (int jointTourFlag = 0; jointTourFlag < 2; jointTourFlag++) { if (jointTourFlag == 1) { componentIndex = 2; choiceProbabilityCalculator.CreateUtilityComponent(componentIndex); ChoiceProbabilityCalculator.Component jointComponent = choiceProbabilityCalculator.GetUtilityComponent(componentIndex); jointComponent.AddUtilityTerm(21, (householdDay.Household.Size == 3).ToFlag()); jointComponent.AddUtilityTerm(22, (householdDay.Household.Size >= 4).ToFlag()); // GV: 1st sep. //jointComponent.AddUtilityTerm(23, (householdDay.Household.Size == 2 && householdDay.Household.HasChildren).ToFlag()); //jointComponent.AddUtilityTerm(23, (householdDay.Household.Size >= 2 && householdDay.Household.HasChildren).ToFlag()); jointComponent.AddUtilityTerm(23, (householdDay.Household.HasChildren).ToFlag()); //jointComponent.AddUtilityTerm(21, householdDay.Household.HasChildrenUnder5.ToFlag()); //jointComponent.AddUtilityTerm(22, householdDay.Household.HasChildrenAge5Through15.ToFlag()); //jointComponent.AddUtilityTerm(23, householdDay.Household.HasChildren.ToFlag()); jointComponent.AddUtilityTerm(24, (householdDay.Household.Size == 2 && householdDay.AdultsInSharedHomeStay == 2).ToFlag()); //jointComponent.AddUtilityTerm(25, (householdDay.AdultsInSharedHomeStay == 2 && householdDay.Household.HouseholdTotals.FullAndPartTimeWorkers >= 2).ToFlag()); jointComponent.AddUtilityTerm(26, (householdDay.AdultsInSharedHomeStay == 2 && hasAdultEducLevel12 == 1).ToFlag()); //jointComponent.AddUtilityTerm(27, (householdDay.Household.Size == 2 && householdDay.Household.HasChildrenUnder5).ToFlag()); //jointComponent.AddUtilityTerm(28, (householdDay.Household.Size == 2 && householdDay.Household.HasChildrenAge5Through15).ToFlag()); //jointComponent.AddUtilityTerm(27, (householdDay.Household.Size == 2 && householdDay.Household.HasChildrenUnder16).ToFlag()); jointComponent.AddUtilityTerm(29, (householdDay.AdultsInSharedHomeStay == 1 && householdDay.Household.HasChildrenUnder16).ToFlag()); //jointComponent.AddUtilityTerm(37, (householdDay.Household.VehiclesAvailable == 1 && household.Has2Drivers).ToFlag()); //jointComponent.AddUtilityTerm(38, (householdDay.Household.VehiclesAvailable >= 2 && household.Has2Drivers).ToFlag()); jointComponent.AddUtilityTerm(30, (householdDay.Household.VehiclesAvailable >= 1 && household.Has2Drivers).ToFlag()); jointComponent.AddUtilityTerm(31, (householdDay.Household.Income >= 300000 && householdDay.Household.Income < 600000).ToFlag()); jointComponent.AddUtilityTerm(32, (householdDay.Household.Income >= 600000 && householdDay.Household.Income < 900000).ToFlag()); jointComponent.AddUtilityTerm(33, (householdDay.Household.Income >= 900000).ToFlag()); // GV, sep. 1st - it is not significant //jointComponent.AddUtilityTerm(41, compositeLogsum); // joint non-mandatory tour constant jointComponent.AddUtilityTerm(61, 1); } } bool available = true; for (int pfpt = 0; pfpt < 2; pfpt++) { for (int jointTourFlag = 0; jointTourFlag < 2; jointTourFlag++) { int altIndex = pfpt + jointTourFlag * 2; if (household.Size < 2 && altIndex > 0) { available = false; } else { available = true; } ChoiceProbabilityCalculator.Alternative alternative = choiceProbabilityCalculator.GetAlternative(altIndex, available, choice == altIndex); alternative.Choice = altIndex; //NESTING WAS REJECTED BY TESTS //GV: PFPT on top - cannot be estimated //alternative.AddNestedAlternative(5 + pfpt, pfpt, THETA_PARAMETER); //alternative.AddNestedAlternative(5 + jointTourFlag, jointTourFlag, THETA_PARAMETER); //jointTourFlag on top if (pfpt == 1) { alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(1)); //alternative.AddUtilityTerm(20, 1); } if (jointTourFlag == 1) { alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(2)); //alternative.AddUtilityTerm(40, 1); } if (pfpt == 1 && jointTourFlag == 1) { alternative.AddUtilityTerm(71, 1); //alternative.AddUtilityTerm(72, (householdDay.Household.Size == 2 && householdDay.AdultsInSharedHomeStay == 2).ToFlag()); // GV: comented out sep. 1st //GV: coeff. 73 is with a wrong sign - 13. june 2016 //alternative.AddUtilityTerm(73, householdDay.Household.HasChildren.ToFlag()); //alternative.AddUtilityTerm(74, householdDay.Household.HasChildrenUnder16.ToFlag()); } } } }
private void RunModel(ChoiceProbabilityCalculator choiceProbabilityCalculator, HouseholdDayWrapper householdDay, TourWrapper tour, IParcelWrapper destinationParcel, int householdCars, int constrainedMode, int constrainedArrivalTime, int constrainedDepartureTime, HTourModeTime choice = null) { //private void RunModel(ChoiceProbabilityCalculator choiceProbabilityCalculator, HouseholdDayWrapper householdDay, TourWrapper tour, // int constrainedMode, int constrainedArrivalTime, int constrainedDepartureTime, HTourModeTime choice = null) { IHouseholdWrapper household = tour.Household; IPersonWrapper person = tour.Person; IPersonDayWrapper personDay = tour.PersonDay; IHouseholdTotals householdTotals = household.HouseholdTotals; // household inputs int childrenUnder5 = householdTotals.ChildrenUnder5; int childrenAge5Through15 = householdTotals.ChildrenAge5Through15; int nonworkingAdults = householdTotals.NonworkingAdults; int retiredAdults = householdTotals.RetiredAdults; int onePersonHouseholdFlag = household.IsOnePersonHousehold.ToFlag(); int twoPersonHouseholdFlag = household.IsTwoPersonHousehold.ToFlag(); //var householdCars = household.VehiclesAvailable; int noCarsInHouseholdFlag = household.GetFlagForNoCarsInHousehold(householdCars); int carsLessThanDriversFlag = household.GetFlagForCarsLessThanDrivers(householdCars); int carsLessThanWorkersFlag = household.GetFlagForCarsLessThanWorkers(householdCars); int HHwithChildrenFlag = household.HasChildren.ToFlag(); int HHwithSmallChildrenFlag = household.HasChildrenUnder5.ToFlag(); int HHwithLowIncomeFlag = (household.Income >= 300000 && household.Income < 600000).ToFlag(); int HHwithMidleIncomeFlag = (household.Income >= 600000 && household.Income < 900000).ToFlag(); int HHwithHighIncomeFlag = (household.Income >= 900000).ToFlag(); int primaryFamilyTimeFlag = (householdDay == null) ? 0 : householdDay.PrimaryPriorityTimeFlag; // person inputs int partTimeWorkerFlag = person.IsPartTimeWorker.ToFlag(); int nonworkingAdultFlag = person.IsNonworkingAdult.ToFlag(); int universityStudentFlag = person.IsUniversityStudent.ToFlag(); int retiredAdultFlag = person.IsRetiredAdult.ToFlag(); int fullTimeWorkerFlag = person.IsFulltimeWorker.ToFlag(); int childAge5Through15Flag = person.IsChildAge5Through15.ToFlag(); int childUnder5Flag = person.IsChildUnder5.ToFlag(); int adultFlag = person.IsAdult.ToFlag(); int maleFlag = person.IsMale.ToFlag(); int femaleFlag = person.IsFemale.ToFlag(); int PTpass = person.TransitPassOwnership; // person-day inputs int homeBasedToursOnlyFlag = 1; int firstSimulatedHomeBasedTourFlag = 1; int laterSimulatedHomeBasedTourFlag = 0; int totalStops = 0; int totalSimulatedStops = 0; int escortStops = 0; int homeBasedTours = 1; int simulatedHomeBasedTours = 0; if (!(personDay == null)) { homeBasedToursOnlyFlag = personDay.OnlyHomeBasedToursExist().ToFlag(); firstSimulatedHomeBasedTourFlag = personDay.IsFirstSimulatedHomeBasedTour().ToFlag(); laterSimulatedHomeBasedTourFlag = personDay.IsLaterSimulatedHomeBasedTour().ToFlag(); totalStops = personDay.GetTotalStops(); totalSimulatedStops = personDay.GetTotalSimulatedStops(); escortStops = personDay.EscortStops; homeBasedTours = personDay.HomeBasedTours; simulatedHomeBasedTours = personDay.SimulatedHomeBasedTours; } // tour inputs int escortTourFlag = tour.IsEscortPurpose().ToFlag(); int shoppingTourFlag = tour.IsShoppingPurpose().ToFlag(); int socialTourFlag = tour.IsSocialPurpose().ToFlag(); int personalBusinessTourFlag = tour.IsPersonalBusinessPurpose().ToFlag(); int workTourFlag = tour.IsWorkPurpose().ToFlag(); int educationTourFlag = tour.IsSchoolPurpose().ToFlag(); int businessTourFlag = tour.IsBusinessPurpose().ToFlag(); IParcelWrapper originParcel = tour.OriginParcel; //var destinationParcel = tour.DestinationParcel; int jointTourFlag = (tour.JointTourSequence > 0) ? 1 : 0; int partialHalfTour1Flag = (tour.PartialHalfTour1Sequence > 0) ? 1 : 0; int partialHalfTour2Flag = (tour.PartialHalfTour2Sequence > 0) ? 1 : 0; bool partialHalfTour = (tour.PartialHalfTour1Sequence > 0 || tour.PartialHalfTour2Sequence > 0); int fullHalfTour1Flag = (tour.FullHalfTour1Sequence > 0) ? 1 : 0; int fullHalfTour2Flag = (tour.FullHalfTour2Sequence > 0) ? 1 : 0; // remaining inputs //Initialize a few variables in case personDay is null // Higher priority tour of 2+ tours for the same purpose int highPrioritySameFlag = 0; // Lower priority tour(s) of 2+ tours for the same purpose int lowPrioritySameFlag = 0; // Higher priority tour of 2+ tours for different purposes int highPriorityDifferentFlag = 0; // Lower priority tour of 2+ tours for different purposes int lowPriorityDifferentFlag = 0; if (!(personDay == null)) { // Higher priority tour of 2+ tours for the same purpose highPrioritySameFlag = (tour.GetTotalToursByPurpose() > tour.GetTotalSimulatedToursByPurpose() && tour.GetTotalSimulatedToursByPurpose() == 1).ToFlag(); // Lower priority tour(s) of 2+ tours for the same purpose lowPrioritySameFlag = (tour.GetTotalSimulatedToursByPurpose() > 1).ToFlag(); // Higher priority tour of 2+ tours for different purposes highPriorityDifferentFlag = (personDay.IsFirstSimulatedHomeBasedTour() && personDay.HomeBasedToursExist()).ToFlag() * (1 - highPrioritySameFlag); // Lower priority tour of 2+ tours for different purposes lowPriorityDifferentFlag = (personDay.IsLaterSimulatedHomeBasedTour() && personDay.HomeBasedToursExist()).ToFlag() * (1 - lowPrioritySameFlag); } ITimeWindow timeWindow = (householdDay == null) ? new TimeWindow() : tour.GetRelevantTimeWindow(householdDay); int totalMinutesAvailableInDay = timeWindow.TotalAvailableMinutes(1, 1440); if (totalMinutesAvailableInDay < 0) { if (!Global.Configuration.IsInEstimationMode) { householdDay.IsValid = false; } totalMinutesAvailableInDay = 0; } int bigPeriodCount = DayPeriod.H_BIG_DAY_PERIOD_TOTAL_TOUR_TIMES; int nPeriodCombs = bigPeriodCount * (bigPeriodCount + 1) / 2; bool useTimeComponents = Global.Configuration.IsInEstimationMode || constrainedArrivalTime == 0 || constrainedDepartureTime == 0; int componentIndex = 0; int periodComb = -1; //set components if (useTimeComponents) { for (int arrivalPeriodIndex = 0; arrivalPeriodIndex < bigPeriodCount; arrivalPeriodIndex++) { MinuteSpan arrivalPeriod = DayPeriod.HBigDayPeriods[arrivalPeriodIndex]; int arrivalPeriodAvailableMinutes = timeWindow.TotalAvailableMinutes(arrivalPeriod.Start, arrivalPeriod.End); for (int departurePeriodIndex = arrivalPeriodIndex; departurePeriodIndex < bigPeriodCount; departurePeriodIndex++) { MinuteSpan departurePeriod = DayPeriod.HBigDayPeriods[departurePeriodIndex]; int departurePeriodAvailableMinutes = timeWindow.TotalAvailableMinutes(departurePeriod.Start, departurePeriod.End); if (arrivalPeriod == departurePeriod) { componentIndex = arrivalPeriodIndex; choiceProbabilityCalculator.CreateUtilityComponent(componentIndex); ChoiceProbabilityCalculator.Component arrivalComponent = choiceProbabilityCalculator.GetUtilityComponent(componentIndex); if (arrivalPeriodAvailableMinutes > 0) { double hoursArrival = arrivalPeriod.Middle / 60.0; int firstCoef = 300; arrivalComponent.AddUtilityTerm(300, Math.Log(arrivalPeriodAvailableMinutes)); //arrival shift variables arrivalComponent.AddUtilityTerm(firstCoef + 2, partTimeWorkerFlag * hoursArrival); arrivalComponent.AddUtilityTerm(firstCoef + 3, nonworkingAdultFlag * hoursArrival); arrivalComponent.AddUtilityTerm(firstCoef + 4, universityStudentFlag * hoursArrival); arrivalComponent.AddUtilityTerm(firstCoef + 5, retiredAdultFlag * hoursArrival); arrivalComponent.AddUtilityTerm(firstCoef + 6, childAge5Through15Flag * hoursArrival); arrivalComponent.AddUtilityTerm(firstCoef + 7, childUnder5Flag * hoursArrival); arrivalComponent.AddUtilityTerm(firstCoef + 8, educationTourFlag * hoursArrival); arrivalComponent.AddUtilityTerm(firstCoef + 9, escortTourFlag * hoursArrival); arrivalComponent.AddUtilityTerm(firstCoef + 10, shoppingTourFlag * hoursArrival); arrivalComponent.AddUtilityTerm(firstCoef + 11, businessTourFlag * hoursArrival); arrivalComponent.AddUtilityTerm(firstCoef + 12, personalBusinessTourFlag * hoursArrival); arrivalComponent.AddUtilityTerm(firstCoef + 13, socialTourFlag * hoursArrival); arrivalComponent.AddUtilityTerm(firstCoef + 14, workTourFlag * hoursArrival); arrivalComponent.AddUtilityTerm(firstCoef + 15, primaryFamilyTimeFlag * hoursArrival); arrivalComponent.AddUtilityTerm(firstCoef + 16, HHwithLowIncomeFlag * hoursArrival); arrivalComponent.AddUtilityTerm(firstCoef + 17, HHwithMidleIncomeFlag * hoursArrival); arrivalComponent.AddUtilityTerm(firstCoef + 18, HHwithHighIncomeFlag * hoursArrival); arrivalComponent.AddUtilityTerm(firstCoef + 19, highPrioritySameFlag * hoursArrival); arrivalComponent.AddUtilityTerm(firstCoef + 20, lowPrioritySameFlag * hoursArrival); arrivalComponent.AddUtilityTerm(firstCoef + 21, highPriorityDifferentFlag * hoursArrival); arrivalComponent.AddUtilityTerm(firstCoef + 22, lowPriorityDifferentFlag * hoursArrival); arrivalComponent.AddUtilityTerm(firstCoef + 23, jointTourFlag * hoursArrival); arrivalComponent.AddUtilityTerm(firstCoef + 24, partialHalfTour1Flag * hoursArrival); arrivalComponent.AddUtilityTerm(firstCoef + 25, fullHalfTour1Flag * hoursArrival); arrivalComponent.AddUtilityTerm(firstCoef + 26, partialHalfTour2Flag * hoursArrival); arrivalComponent.AddUtilityTerm(firstCoef + 27, fullHalfTour2Flag * hoursArrival); } componentIndex = bigPeriodCount + departurePeriodIndex; choiceProbabilityCalculator.CreateUtilityComponent(componentIndex); ChoiceProbabilityCalculator.Component departureComponent = choiceProbabilityCalculator.GetUtilityComponent(componentIndex); if (departurePeriodAvailableMinutes > 0) { departureComponent.AddUtilityTerm(300, Math.Log(departurePeriodAvailableMinutes)); } } // set period combination component periodComb++; componentIndex = 2 * bigPeriodCount + periodComb; choiceProbabilityCalculator.CreateUtilityComponent(componentIndex); ChoiceProbabilityCalculator.Component combinationComponent = choiceProbabilityCalculator.GetUtilityComponent(componentIndex); if (arrivalPeriodAvailableMinutes > 0 && departurePeriodAvailableMinutes > 0) { double hoursDuration = (departurePeriod.Middle - arrivalPeriod.Middle) / 60.0; int firstCoef = 700; //combination constants combinationComponent.AddUtilityTerm(firstCoef + periodComb, 1.0); // duration shift variables combinationComponent.AddUtilityTerm(firstCoef + 30, primaryFamilyTimeFlag * hoursDuration); combinationComponent.AddUtilityTerm(firstCoef + 31, escortTourFlag * hoursDuration); combinationComponent.AddUtilityTerm(firstCoef + 32, shoppingTourFlag * hoursDuration); combinationComponent.AddUtilityTerm(firstCoef + 33, educationTourFlag * hoursDuration); combinationComponent.AddUtilityTerm(firstCoef + 34, socialTourFlag * hoursDuration); combinationComponent.AddUtilityTerm(firstCoef + 35, personalBusinessTourFlag * hoursDuration); combinationComponent.AddUtilityTerm(firstCoef + 36, businessTourFlag * hoursDuration); combinationComponent.AddUtilityTerm(firstCoef + 37, workTourFlag * hoursDuration); combinationComponent.AddUtilityTerm(firstCoef + 38, highPrioritySameFlag * hoursDuration); combinationComponent.AddUtilityTerm(firstCoef + 39, lowPrioritySameFlag * hoursDuration); combinationComponent.AddUtilityTerm(firstCoef + 40, highPriorityDifferentFlag * hoursDuration); combinationComponent.AddUtilityTerm(firstCoef + 41, lowPriorityDifferentFlag * hoursDuration); combinationComponent.AddUtilityTerm(firstCoef + 42, partTimeWorkerFlag * hoursDuration); combinationComponent.AddUtilityTerm(firstCoef + 43, jointTourFlag * hoursDuration); combinationComponent.AddUtilityTerm(firstCoef + 44, partialHalfTour1Flag * hoursDuration); combinationComponent.AddUtilityTerm(firstCoef + 45, fullHalfTour1Flag * hoursDuration); combinationComponent.AddUtilityTerm(firstCoef + 46, partialHalfTour2Flag * hoursDuration); combinationComponent.AddUtilityTerm(firstCoef + 47, fullHalfTour2Flag * hoursDuration); // peak-to-peak variables if (arrivalPeriod.Index == DayPeriod.AM_PEAK && departurePeriod.Index == DayPeriod.PM_PEAK) { combinationComponent.AddUtilityTerm(firstCoef + 48, fullTimeWorkerFlag); combinationComponent.AddUtilityTerm(firstCoef + 49, partTimeWorkerFlag); combinationComponent.AddUtilityTerm(firstCoef + 50, maleFlag); } } } } } //for (var mode = Global.Settings.Modes.Walk; mode <= Global.Settings.Modes.WalkRideBike; mode++) { replaced 20171120 JLB for (int mode = Global.Settings.Modes.Walk; mode <= Global.Settings.Modes.PaidRideShare; mode++) { componentIndex = 2 * bigPeriodCount + nPeriodCombs + mode - 1; choiceProbabilityCalculator.CreateUtilityComponent(componentIndex); ChoiceProbabilityCalculator.Component modeComponent = choiceProbabilityCalculator.GetUtilityComponent(componentIndex); //if (mode == Global.Settings.Modes.SchoolBus) { // modeComponent.AddUtilityTerm(10, 1); //} if (mode == Global.Settings.Modes.Transit) { modeComponent.AddUtilityTerm(20, 1); modeComponent.AddUtilityTerm(21, femaleFlag); //modeComponent.AddUtilityTerm(22, retiredAdultFlag); modeComponent.AddUtilityTerm(22, PTpass); //GV: one person HH; 8. juni 2016 //modeComponent.AddUtilityTerm(23, onePersonHouseholdFlag); //GV: income effect is not with a correct sign //modeComponent.AddUtilityTerm(23, HHwithLowIncomeFlag); //modeComponent.AddUtilityTerm(24, HHwithMidleIncomeFlag); //modeComponent.AddUtilityTerm(25, HHwithHighIncomeFlag); //GV: not significant //modeComponent.AddUtilityTerm(26, childrenUnder5); //modeComponent.AddUtilityTerm(27, childrenAge5Through15); modeComponent.AddUtilityTerm(28, nonworkingAdults + retiredAdults); //modeComponent.AddUtilityTerm(26, noCarsInHouseholdFlag); modeComponent.AddUtilityTerm(29, carsLessThanDriversFlag); } else if (mode == Global.Settings.Modes.Hov3) { modeComponent.AddUtilityTerm(30, 1); modeComponent.AddUtilityTerm(31, childrenUnder5); modeComponent.AddUtilityTerm(32, childrenAge5Through15); modeComponent.AddUtilityTerm(33, nonworkingAdults + retiredAdults); modeComponent.AddUtilityTerm(34, femaleFlag); //modeComponent.AddUtilityTerm(38, onePersonHouseholdFlag); modeComponent.AddUtilityTerm(36, twoPersonHouseholdFlag); //GV: commented out 7. june 2016 //modeComponent.AddUtilityTerm(37, noCarsInHouseholdFlag); modeComponent.AddUtilityTerm(38, carsLessThanDriversFlag); } else if (mode == Global.Settings.Modes.Hov2) { modeComponent.AddUtilityTerm(40, 1); modeComponent.AddUtilityTerm(41, maleFlag); //modeComponent.AddUtilityTerm(41, onePersonHouseholdFlag); //GV: Testing coeff. 42-44 again, 26. may 2016, coeff. numbering changed modeComponent.AddUtilityTerm(42, childrenUnder5); modeComponent.AddUtilityTerm(43, childrenAge5Through15); modeComponent.AddUtilityTerm(44, nonworkingAdults + retiredAdults); //GV: these are significant and plus; 8. juni 2016 //modeComponent.AddUtilityTerm(45, HHwithLowIncomeFlag); //modeComponent.AddUtilityTerm(46, HHwithMidleIncomeFlag); //modeComponent.AddUtilityTerm(47, HHwithHighIncomeFlag); //GV coeff. numbering changed; 8. june 2016 - not significant //modeComponent.AddUtilityTerm(48, noCarsInHouseholdFlag); //modeComponent.AddUtilityTerm(49, carsLessThanDriversFlag); } else if (mode == Global.Settings.Modes.Sov) { modeComponent.AddUtilityTerm(50, 1); //not significant: modeComponent.AddUtilityTerm(51, maleFlag); modeComponent.AddUtilityTerm(52, fullTimeWorkerFlag); modeComponent.AddUtilityTerm(53, partTimeWorkerFlag); modeComponent.AddUtilityTerm(54, onePersonHouseholdFlag); //GV: these are NOT significant //modeComponent.AddUtilityTerm(55, HHwithLowIncomeFlag); //modeComponent.AddUtilityTerm(56, HHwithMidleIncomeFlag); //modeComponent.AddUtilityTerm(57, HHwithHighIncomeFlag); //GV: coeff. numbering changed, 26. may 2016 modeComponent.AddUtilityTerm(58, carsLessThanWorkersFlag); } else if (mode == Global.Settings.Modes.Bike) { modeComponent.AddUtilityTerm(60, 1); modeComponent.AddUtilityTerm(61, femaleFlag); //modeComponent.AddUtilityTerm(62, childrenUnder5); //GV: changed small kids to retired; 3. june 2016 modeComponent.AddUtilityTerm(62, retiredAdults); modeComponent.AddUtilityTerm(63, childAge5Through15Flag); //GV: 3. june 2016 - added "no cars in HH" for full/part_time workers modeComponent.AddUtilityTerm(64, fullTimeWorkerFlag + noCarsInHouseholdFlag); modeComponent.AddUtilityTerm(65, partTimeWorkerFlag + noCarsInHouseholdFlag); //modeComponent.AddUtilityTerm(66, noCarsInHouseholdFlag); modeComponent.AddUtilityTerm(67, carsLessThanDriversFlag); //GV: university students; 3. june 2016 - not significant //modeComponent.AddUtilityTerm(68, universityStudentFlag); //GV: one person HH; 8. juni 2016 modeComponent.AddUtilityTerm(69, onePersonHouseholdFlag); } else if (mode == Global.Settings.Modes.Walk) { modeComponent.AddUtilityTerm(70, 1.0); //GV: Testing female variable again; 26. may 2016 - not sign. //modeComponent.AddUtilityTerm(71, femaleFlag); modeComponent.AddUtilityTerm(72, nonworkingAdults); //not sign.: modeComponent.AddUtilityTerm(73, retiredAdults); //GV: one person HH modeComponent.AddUtilityTerm(74, onePersonHouseholdFlag); //GV: not significant //modeComponent.AddUtilityTerm(76, noCarsInHouseholdFlag); //modeComponent.AddUtilityTerm(77, carsLessThanDriversFlag); } else if (mode == Global.Settings.Modes.ParkAndRide) { modeComponent.AddUtilityTerm(80, 1.0); } else if (mode == Global.Settings.Modes.CarKissRideWalk) { modeComponent.AddUtilityTerm(90, 1.0); } else if (mode == Global.Settings.Modes.BikeParkRideWalk) { modeComponent.AddUtilityTerm(100, 1.0); } else if (mode == Global.Settings.Modes.BikeParkRideBike) { modeComponent.AddUtilityTerm(110, 1.0); } else if (mode == Global.Settings.Modes.BikeOnTransit) { modeComponent.AddUtilityTerm(120, 1.0); } else if (mode == Global.Settings.Modes.CarParkRideBike) { modeComponent.AddUtilityTerm(130, 1.0); } else if (mode == Global.Settings.Modes.WalkRideBike) { modeComponent.AddUtilityTerm(140, 1.0); } else if (mode == Global.Settings.Modes.PaidRideShare) { //modeComponent.AddUtilityTerm(150, 1.0); double modeConstant = Global.Configuration.AV_PaidRideShareModeUsesAVs ? Global.Configuration.AV_PaidRideShare_ModeConstant + Global.Configuration.AV_PaidRideShare_DensityCoefficient * Math.Min(originParcel.HouseholdsBuffer2 + originParcel.StudentsUniversityBuffer2 + originParcel.EmploymentTotalBuffer2, 6000) + Global.Configuration.AV_PaidRideShare_AVOwnerCoefficient * (household.OwnsAutomatedVehicles > 0).ToFlag() : Global.Configuration.PaidRideShare_ModeConstant + Global.Configuration.PaidRideShare_DensityCoefficient * Math.Min(originParcel.HouseholdsBuffer2 + originParcel.StudentsUniversityBuffer2 + originParcel.EmploymentTotalBuffer2, 6000); modeComponent.AddUtilityTerm(150, modeConstant); modeComponent.AddUtilityTerm(150, Global.Configuration.PaidRideShare_Age26to35Coefficient * tour.Person.AgeIsBetween26And35.ToFlag()); modeComponent.AddUtilityTerm(150, Global.Configuration.PaidRideShare_Age18to25Coefficient * tour.Person.AgeIsBetween18And25.ToFlag()); modeComponent.AddUtilityTerm(150, Global.Configuration.PaidRideShare_AgeOver65Coefficient * (tour.Person.Age >= 65).ToFlag()); } //GV: Estimation of importance of "purpose" per mode - SOV is zero-alt and Work is zero-alt if (mode == Global.Settings.Modes.Walk || mode == Global.Settings.Modes.Bike || mode == Global.Settings.Modes.Hov2 || mode == Global.Settings.Modes.Hov3 || mode == Global.Settings.Modes.Transit) { int firstCoef = 200 + 10 * mode; modeComponent.AddUtilityTerm(firstCoef + 0, escortTourFlag); modeComponent.AddUtilityTerm(firstCoef + 1, shoppingTourFlag); modeComponent.AddUtilityTerm(firstCoef + 2, educationTourFlag); modeComponent.AddUtilityTerm(firstCoef + 3, socialTourFlag); modeComponent.AddUtilityTerm(firstCoef + 4, personalBusinessTourFlag); modeComponent.AddUtilityTerm(firstCoef + 5, businessTourFlag); //modeComponent.AddUtilityTerm(firstCoef + 6, workTourFlag); //GV: "work" is zero alternative modeComponent.AddUtilityTerm(firstCoef + 7, jointTourFlag); modeComponent.AddUtilityTerm(firstCoef + 8, Math.Min(partialHalfTour1Flag + partialHalfTour2Flag, 1.0)); modeComponent.AddUtilityTerm(firstCoef + 9, Math.Min(fullHalfTour1Flag + fullHalfTour2Flag, 1.0)); } } //loop on all alternatives, using modeTimes objects { foreach (HTourModeTime modeTimes in HTourModeTime.ModeTimes[ParallelUtility.threadLocalAssignedIndex.Value]) { MinuteSpan arrivalPeriod = modeTimes.ArrivalPeriod; int arrivalPeriodAvailableMinutes = timeWindow.TotalAvailableMinutes(arrivalPeriod.Start, arrivalPeriod.End); MinuteSpan departurePeriod = modeTimes.DeparturePeriod; int departurePeriodAvailableMinutes = timeWindow.TotalAvailableMinutes(departurePeriod.Start, departurePeriod.End); periodComb = modeTimes.PeriodCombinationIndex; int mode = modeTimes.Mode; int altIndex = modeTimes.Index; //limit availability based on mode and tour purpose bool available = (mode == Global.Settings.Modes.BikeParkRideBike || mode == Global.Settings.Modes.CarParkRideBike || mode == Global.Settings.Modes.WalkRideBike) && (!(tour.IsWorkPurpose() || tour.IsSchoolPurpose())) ? false : true; //further limit availability on mode if (mode == Global.Settings.Modes.PaidRideShare && !Global.Configuration.PaidRideShareModeIsAvailable) { available = false; } //further limit availability if tour includes joint travel if ((tour.JointTourSequence > 0 || tour.FullHalfTour1Sequence > 0 || tour.FullHalfTour2Sequence > 0 || tour.PartialHalfTour1Sequence > 0 || tour.PartialHalfTour2Sequence > 0) && (mode > Global.Settings.Modes.Transit)) { available = false; } //further limit availability: kissAndRide and carParkRideBike are not supported available = (available == true) && (mode != Global.Settings.Modes.CarKissRideWalk) && (mode != Global.Settings.Modes.CarParkRideBike); //further limit availabillity based on time window variables and any constrained choices available = (available == true) && (modeTimes.LongestFeasibleWindow != null) && (mode > 0) //&& (mode <= Global.Settings.Modes.Transit) && (person.Age >= 18 || (modeTimes.Mode != Global.Settings.Modes.Sov && modeTimes.Mode != Global.Settings.Modes.HovDriver)) && (constrainedMode > 0 || mode == Global.Settings.Modes.Walk || mode == Global.Settings.Modes.Bike || mode == Global.Settings.Modes.HovDriver || mode == Global.Settings.Modes.Transit || !partialHalfTour) && (constrainedMode <= 0 || constrainedMode == mode) && (constrainedArrivalTime <= 0 || (constrainedArrivalTime >= arrivalPeriod.Start && constrainedArrivalTime <= arrivalPeriod.End)) && (constrainedDepartureTime <= 0 || (constrainedDepartureTime >= departurePeriod.Start && constrainedDepartureTime <= departurePeriod.End)); ChoiceProbabilityCalculator.Alternative alternative = choiceProbabilityCalculator.GetAlternative(altIndex, available, choice != null && choice.Index == altIndex); alternative.Choice = modeTimes; // JLB added 20130420 //alternative.AddNestedAlternative(HTourModeTime.TOTAL_TOUR_MODE_TIMES + periodComb + 1, periodComb, THETA_PARAMETER); alternative.AddNestedAlternative(HTourModeTime.TotalTourModeTimes + mode, mode - 1, THETA_PARAMETER); //if (Global.Configuration.IsInEstimationMode && altIndex == choice.Index) { // Global.PrintFile.WriteLine("Aper Dper Mode {0} {1} {2} Travel Times {3} {4} Window {5} {6}", // arrivalPeriod.Index, departurePeriod.Index, mode, // modeTimes.ModeAvailableToDestination ? modeTimes.TravelTimeToDestination : -1, // modeTimes.ModeAvailableFromDestination ? modeTimes.TravelTimeFromDestination : -1, // modeTimes.LongestFeasibleWindow != null ? modeTimes.LongestFeasibleWindow.Start : -1, // modeTimes.LongestFeasibleWindow != null ? modeTimes.LongestFeasibleWindow.End : -1); //} //Following code was used to test handling of partially joint half tours (JLB 20140603) //if (partialHalfTour) { // Global.PrintFile.WriteLine("HH pers {0} {1} avail {2} Aper Dper Mode {3} {4} {5} Travel Times {6} {7} Window {8} {9}", // household.Id, person.Sequence, // available, // arrivalPeriod.Index, departurePeriod.Index, mode, // modeTimes.ModeAvailableToDestination ? modeTimes.TravelTimeToDestination : -1, // modeTimes.ModeAvailableFromDestination ? modeTimes.TravelTimeFromDestination : -1, // modeTimes.LongestFeasibleWindow != null ? modeTimes.LongestFeasibleWindow.Start : -1, // modeTimes.LongestFeasibleWindow != null ? modeTimes.LongestFeasibleWindow.End : -1); //} //if in application mode and combination is not available, can skip the rest if (!Global.Configuration.IsInEstimationMode && !alternative.Available) { continue; } if (useTimeComponents) { // arrival period utility component alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(arrivalPeriod.Index)); // departure period utility component alternative.AddUtilityComponent( choiceProbabilityCalculator.GetUtilityComponent(bigPeriodCount + departurePeriod.Index)); // period combination utility component alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(2 * bigPeriodCount + periodComb)); } // mode utility component alternative.AddUtilityComponent( choiceProbabilityCalculator.GetUtilityComponent(2 * bigPeriodCount + nPeriodCombs + mode - 1)); //even in estimation mode, do not need the rest of the code if not available if (!alternative.Available) { continue; } //GV and JB: the parking cost are handled as part of genaralised time double minimumTimeNeeded = modeTimes.TravelTimeToDestination + modeTimes.TravelTimeFromDestination + Global.Settings.Times.MinimumActivityDuration; alternative.AddUtilityTerm(1, modeTimes.GeneralizedTimeToDestination + modeTimes.GeneralizedTimeFromDestination); //alternative.AddUtilityTerm(3, // Math.Log(modeTimes.LongestFeasibleWindow.End - modeTimes.LongestFeasibleWindow.Start - // minimumTimeNeeded + 1.0)); // JLB 20140204 replaced coeff 3 with a different time window formulation: time pressure // instead of having positive utility for increasing time window, have negative utility for decreasing time window alternative.AddUtilityTerm(3, Math.Log(Math.Max(Constants.EPSILON, 1 - Math.Pow(minimumTimeNeeded / (Math.Min(840, modeTimes.LongestFeasibleWindow.End - modeTimes.LongestFeasibleWindow.Start)), 0.8) ))); alternative.AddUtilityTerm(4, Math.Log((totalMinutesAvailableInDay + 1.0) / (minimumTimeNeeded + 1.0))); alternative.AddUtilityTerm(5, (maleFlag == 0 && mode == Global.Settings.Modes.Walk && arrivalPeriod.Index >= DayPeriod.EVENING) ? 1 : 0); if (altIndex == 0) { alternative.AddUtilityTerm(998, tour.DestinationPurpose); alternative.AddUtilityTerm(999, (tour.ParentTour == null) ? 0 : 1); } } } }
private void RunModel(ChoiceProbabilityCalculator choiceProbabilityCalculator, PersonDayWrapper personDay, HouseholdDayWrapper householdDay, DayPattern[] dayPatterns, DayPattern choice = null) { Framework.DomainModels.Wrappers.IHouseholdWrapper household = personDay.Household; Framework.DomainModels.Wrappers.IParcelWrapper residenceParcel = household.ResidenceParcel; Framework.DomainModels.Wrappers.IPersonWrapper person = personDay.Person; int carsPerDriver = household.GetCarsPerDriver(); double mixedDensity = residenceParcel.MixedUse3Index2(); double intersectionDensity = residenceParcel.IntersectionDensity34Minus1Buffer2(); double[] purposeLogsums = new double[Global.Settings.Purposes.TotalPurposes + 2]; double[] atUsualLogsums = new double[3]; //var carOwnership = person.CarOwnershipSegment; //GV: sat car ownership not to impact logsums int carOwnership = 0; int votSegment = person.Household.GetVotALSegment(); int transitAccess = residenceParcel.TransitAccessSegment(); //GV: input 26. july 2013 // household inputs //var childrenUnder5 = householdTotals.ChildrenUnder5; //var childrenAge5Through15 = householdTotals.ChildrenAge5Through15; //var nonworkingAdults = householdTotals.NonworkingAdults; //var retiredAdults = householdTotals.RetiredAdults; int onePersonHouseholdFlag = household.IsOnePersonHousehold.ToFlag(); int twoPersonHouseholdFlag = household.IsTwoPersonHousehold.ToFlag(); int householdCars = household.VehiclesAvailable; //var noCarsInHouseholdFlag = HouseholdWrapper.GetNoCarsInHouseholdFlag(householdCars); //var carsLessThanDriversFlag = household.GetCarsLessThanDriversFlag(householdCars); //var carsLessThanWorkersFlag = household.GetCarsLessThanWorkersFlag(householdCars); int HHwithChildrenFlag = household.HasChildren.ToFlag(); int HHwithSmallChildrenFlag = household.HasChildrenUnder5.ToFlag(); int HHwithLowIncomeFlag = (household.Income >= 300000 && household.Income < 600000).ToFlag(); int HHwithMidleIncomeFlag = (household.Income >= 600000 && household.Income < 900000).ToFlag(); int HHwithHighIncomeFlag = (household.Income >= 900000).ToFlag(); int primaryFamilyTimeFlag = householdDay.PrimaryPriorityTimeFlag; //GV: input 26. july 2013 // person inputs int partTimeWorkerFlag = person.IsPartTimeWorker.ToFlag(); int nonworkingAdultFlag = person.IsNonworkingAdult.ToFlag(); int universityStudentFlag = person.IsUniversityStudent.ToFlag(); int retiredAdultFlag = person.IsRetiredAdult.ToFlag(); int fullTimeWorkerFlag = person.IsFulltimeWorker.ToFlag(); int childAge5Through15Flag = person.IsChildAge5Through15.ToFlag(); int childUnder5Flag = person.IsChildUnder5.ToFlag(); int adultFlag = person.IsAdult.ToFlag(); int maleFlag = person.IsMale.ToFlag(); int femaleFlag = person.IsFemale.ToFlag(); if (person.UsualWorkParcel == null || person.UsualWorkParcelId == household.ResidenceParcelId) { purposeLogsums[Global.Settings.Purposes.Work] = 0; } else { int destinationArrivalTime = ChoiceModelUtility.GetDestinationArrivalTime(Global.Settings.Models.WorkTourModeModel); int destinationDepartureTime = ChoiceModelUtility.GetDestinationDepartureTime(Global.Settings.Models.WorkTourModeModel); //JLB 201406 //var nestedAlternative = Global.ChoiceModelSession.Get<WorkTourModeModel>().RunNested(personDay, residenceParcel, person.UsualWorkParcel, destinationArrivalTime, destinationDepartureTime, household.VehiclesAvailable); //JLB 201602 //var nestedAlternative = Global.ChoiceModelSession.Get<WorkTourModeTimeModel>().RunNested(personDay, residenceParcel, person.UsualWorkParcel, destinationArrivalTime, destinationDepartureTime, household.VehiclesAvailable); ChoiceProbabilityCalculator.Alternative nestedAlternative = Global.ChoiceModelSession.Get <TourModeTimeModel>().RunNested(personDay, residenceParcel, person.UsualWorkParcel, destinationArrivalTime, destinationDepartureTime, household.VehiclesAvailable, Global.Settings.Purposes.Work); purposeLogsums[Global.Settings.Purposes.Work] = nestedAlternative == null ? 0 : nestedAlternative.ComputeLogsum(); atUsualLogsums[Global.Settings.Purposes.Work] = Global.AggregateLogsums[person.UsualWorkParcel.ZoneId][Global.Settings.Purposes.HomeBasedComposite][carOwnership][votSegment][person.UsualWorkParcel.TransitAccessSegment()]; } if (person.UsualSchoolParcel == null || person.UsualSchoolParcelId == household.ResidenceParcelId) { purposeLogsums[Global.Settings.Purposes.School] = 0; } else { int destinationArrivalTime = ChoiceModelUtility.GetDestinationArrivalTime(Global.Settings.Models.SchoolTourModeModel); int destinationDepartureTime = ChoiceModelUtility.GetDestinationDepartureTime(Global.Settings.Models.SchoolTourModeModel); //JLB 201406 //var nestedAlternative = Global.ChoiceModelSession.Get<SchoolTourModeModel>().RunNested(personDay, residenceParcel, person.UsualSchoolParcel, destinationArrivalTime, destinationDepartureTime, household.VehiclesAvailable); //JLB 201602 //var nestedAlternative = Global.ChoiceModelSession.Get<SchoolTourModeTimeModel>().RunNested(personDay, residenceParcel, person.UsualSchoolParcel, destinationArrivalTime, destinationDepartureTime, household.VehiclesAvailable); ChoiceProbabilityCalculator.Alternative nestedAlternative = Global.ChoiceModelSession.Get <TourModeTimeModel>().RunNested(personDay, residenceParcel, person.UsualSchoolParcel, destinationArrivalTime, destinationDepartureTime, household.VehiclesAvailable, Global.Settings.Purposes.School); purposeLogsums[Global.Settings.Purposes.School] = nestedAlternative == null ? 0 : nestedAlternative.ComputeLogsum(); atUsualLogsums[Global.Settings.Purposes.School] = Global.AggregateLogsums[person.UsualSchoolParcel.ZoneId][Global.Settings.Purposes.HomeBasedComposite][carOwnership][votSegment][person.UsualSchoolParcel.TransitAccessSegment()]; } double compositeLogsum = Global.AggregateLogsums[household.ResidenceZoneId][Global.Settings.Purposes.HomeBasedComposite][carOwnership][votSegment][transitAccess]; purposeLogsums[Global.Settings.Purposes.Escort] = Global.AggregateLogsums[household.ResidenceZoneId][Global.Settings.Purposes.Escort][carOwnership][votSegment][transitAccess]; purposeLogsums[Global.Settings.Purposes.PersonalBusiness] = Global.AggregateLogsums[household.ResidenceZoneId][Global.Settings.Purposes.PersonalBusiness][carOwnership][votSegment][transitAccess]; purposeLogsums[Global.Settings.Purposes.Shopping] = Global.AggregateLogsums[household.ResidenceZoneId][Global.Settings.Purposes.Shopping][carOwnership][votSegment][transitAccess]; purposeLogsums[Global.Settings.Purposes.Social] = Global.AggregateLogsums[household.ResidenceZoneId][Global.Settings.Purposes.Social][carOwnership][votSegment][transitAccess]; for (int xPurpose = Global.Settings.Purposes.Escort; xPurpose <= Global.Settings.Purposes.Social + 10; xPurpose++) { // extra components 1-5 are for 2,3,4,5,6 tour purposes // extra components 6-10 are for 2,3,4,5,6 stop puroposes // recode purpose to match coefficients int purpose = xPurpose <= Global.Settings.Purposes.Social ? xPurpose : xPurpose <= Global.Settings.Purposes.Social + 5 ? Global.Settings.Purposes.Social + 1 : Global.Settings.Purposes.Social + 2; // get correct multiplier on coefficients. double xMultiplier = xPurpose <= Global.Settings.Purposes.Social ? 1.0 : xPurpose <= Global.Settings.Purposes.Social + 5 ? Math.Log(xPurpose - Global.Settings.Purposes.Social + 1) : Math.Log(xPurpose - Global.Settings.Purposes.Social - 5 + 1); choiceProbabilityCalculator.CreateUtilityComponent(xPurpose); ChoiceProbabilityCalculator.Component component = choiceProbabilityCalculator.GetUtilityComponent(xPurpose); component.AddUtilityTerm(100 * purpose + 1, xMultiplier * person.IsFulltimeWorker.ToFlag()); component.AddUtilityTerm(100 * purpose + 2, xMultiplier * person.IsPartTimeWorker.ToFlag()); component.AddUtilityTerm(100 * purpose + 3, xMultiplier * person.IsRetiredAdult.ToFlag()); component.AddUtilityTerm(100 * purpose + 4, xMultiplier * person.IsNonworkingAdult.ToFlag()); component.AddUtilityTerm(100 * purpose + 5, xMultiplier * person.IsUniversityStudent.ToFlag()); component.AddUtilityTerm(100 * purpose + 6, xMultiplier * person.IsDrivingAgeStudent.ToFlag()); component.AddUtilityTerm(100 * purpose + 7, xMultiplier * person.IsChildAge5Through15.ToFlag()); component.AddUtilityTerm(100 * purpose + 8, xMultiplier * person.IsChildUnder5.ToFlag()); component.AddUtilityTerm(100 * purpose + 9, xMultiplier * HHwithLowIncomeFlag); component.AddUtilityTerm(100 * purpose + 10, xMultiplier * HHwithMidleIncomeFlag); component.AddUtilityTerm(100 * purpose + 11, xMultiplier * HHwithHighIncomeFlag); //component.AddUtilityTerm(100 * purpose + 12, xMultiplier * carsPerDriver); component.AddUtilityTerm(100 * purpose + 12, xMultiplier * householdCars); component.AddUtilityTerm(100 * purpose + 13, xMultiplier * person.IsOnlyAdult().ToFlag()); component.AddUtilityTerm(100 * purpose + 14, xMultiplier * person.IsOnlyFullOrPartTimeWorker().ToFlag()); component.AddUtilityTerm(100 * purpose + 15, xMultiplier * 0); component.AddUtilityTerm(100 * purpose + 16, xMultiplier * person.IsFemale.ToFlag() * person.IsAdult.ToFlag() * (!household.HasChildrenUnder16).ToFlag()); component.AddUtilityTerm(100 * purpose + 17, xMultiplier * person.IsFemale.ToFlag() * person.IsAdult.ToFlag() * household.HasChildrenUnder5.ToFlag()); component.AddUtilityTerm(100 * purpose + 18, xMultiplier * person.IsFemale.ToFlag() * person.IsAdult.ToFlag() * household.HasChildrenAge5Through15.ToFlag()); component.AddUtilityTerm(100 * purpose + 19, xMultiplier * person.IsMale.ToFlag() * person.IsAdult.ToFlag() * household.HasChildrenUnder5.ToFlag()); component.AddUtilityTerm(100 * purpose + 20, xMultiplier * person.IsMale.ToFlag() * person.IsAdult.ToFlag() * household.HasChildrenAge5Through15.ToFlag()); //component.AddUtilityTerm(100 * purpose + 21, xMultiplier * primaryFamilyTimeFlag); //GV: wrong sign //component.AddUtilityTerm(100 * purpose + 21, xMultiplier * person.AgeIsBetween18And25.ToFlag()); //component.AddUtilityTerm(100 * purpose + 22, xMultiplier * person.AgeIsBetween26And35.ToFlag()); //component.AddUtilityTerm(100 * purpose + 23, xMultiplier * person.AgeIsBetween51And65.ToFlag()); component.AddUtilityTerm(100 * purpose + 24, xMultiplier * person.WorksAtHome().ToFlag()); component.AddUtilityTerm(100 * purpose + 25, xMultiplier * mixedDensity); component.AddUtilityTerm(100 * purpose + 26, xMultiplier * intersectionDensity); //component.AddUtilityTerm(100 * purpose + 27, xMultiplier * purposeLogsums[purpose]); //GV: 17.08.2013, the logsums are wrong //component.AddUtilityTerm(100 * purpose + 28, xMultiplier * person.TransitPassOwnershipFlag); } // tour utility const int tourComponentIndex = 18; choiceProbabilityCalculator.CreateUtilityComponent(tourComponentIndex); ChoiceProbabilityCalculator.Component tourComponent = choiceProbabilityCalculator.GetUtilityComponent(tourComponentIndex); //tourComponent.AddUtilityTerm(1701, carsPerDriver); tourComponent.AddUtilityTerm(1701, householdCars); tourComponent.AddUtilityTerm(1702, person.WorksAtHome().ToFlag()); tourComponent.AddUtilityTerm(1703, mixedDensity); tourComponent.AddUtilityTerm(1704, mixedDensity * person.IsChildAge5Through15.ToFlag()); tourComponent.AddUtilityTerm(1705, compositeLogsum); //tourComponent.AddUtilityTerm(1706, person.TransitPassOwnershipFlag); tourComponent.AddUtilityTerm(1706, primaryFamilyTimeFlag); // stop utility const int stopComponentIndex = 19; choiceProbabilityCalculator.CreateUtilityComponent(stopComponentIndex); ChoiceProbabilityCalculator.Component stopComponent = choiceProbabilityCalculator.GetUtilityComponent(stopComponentIndex); //stopComponent.AddUtilityTerm(1711, carsPerDriver); stopComponent.AddUtilityTerm(1711, householdCars); stopComponent.AddUtilityTerm(1712, person.WorksAtHome().ToFlag()); stopComponent.AddUtilityTerm(1713, mixedDensity); stopComponent.AddUtilityTerm(1714, mixedDensity * person.IsChildAge5Through15.ToFlag()); stopComponent.AddUtilityTerm(1715, compositeLogsum); //stopComponent.AddUtilityTerm(1716, person.TransitPassOwnershipFlag); //stopComponent.AddUtilityTerm(1716, primaryFamilyTimeFlag); //GV: 17.08.2013, the logsums are wrong for (int alternativeIndex = 0; alternativeIndex < TOTAL_ALTERNATIVES; alternativeIndex++) { DayPattern dayPattern = dayPatterns[alternativeIndex]; bool available = dayPattern.Available; ChoiceProbabilityCalculator.Alternative alternative = choiceProbabilityCalculator.GetAlternative(alternativeIndex, available, choice != null && choice.Equals(dayPattern)); if (!Global.Configuration.IsInEstimationMode && !alternative.Available) { continue; } alternative.Choice = dayPattern; // components for the purposes for (int purpose = Global.Settings.Purposes.Escort; purpose <= Global.Settings.Purposes.Social; purpose++) { if (dayPattern.Tours[purpose] > 0 || dayPattern.Stops[purpose] > 0) { alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(purpose)); if (dayPattern.Tours[purpose] > 0) { alternative.AddUtilityTerm(100 * purpose + 50, 1); // tour purpose ASC //alternative.AddUtilityTerm(100 * purpose + 51, purposeLogsums[purpose]); // tour purpose logsum GV: 17.08.2013, the logsums are wrong } if (dayPattern.Stops[purpose] > 0) { alternative.AddUtilityTerm(100 * purpose + 60, 1); // stop purpose ASC //alternative.AddUtilityTerm(100 * purpose + 61, purposeLogsums[purpose]); // stop purpose logsum GV: 17.08.2013, the logsums are wrong } if (Global.Configuration.IsInEstimationMode) { //GV commented out //alternative.AddUtilityTerm(100 * purpose + 70, 1 - person.PaperDiary); //GV commented out //alternative.AddUtilityTerm(100 * purpose + 71, person.ProxyResponse); } } } // multiple tour purposes component if (dayPattern.TotalTourPurposes > 1) { alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(Global.Settings.Purposes.Social + (dayPattern.TotalTourPurposes - 1))); } // multiple stop purposes component if (dayPattern.TotalStopPurposes > 1) { alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(Global.Settings.Purposes.Social + 5 + (dayPattern.TotalStopPurposes - 1))); } for (int tourPurpose = Global.Settings.Purposes.Work; tourPurpose <= Global.Settings.Purposes.Social; tourPurpose++) { for (int stopPurpose = Global.Settings.Purposes.Work; stopPurpose <= Global.Settings.Purposes.Social - 1; stopPurpose++) { if (tourPurpose > Global.Settings.Purposes.School && stopPurpose <= Global.Settings.Purposes.School) { continue; } if (dayPattern.Tours[tourPurpose] > 0 && dayPattern.Stops[stopPurpose] > 0) { alternative.AddUtilityTerm(1200 + 10 * tourPurpose + stopPurpose, 1); // tour-stop comb. utility } } } for (int tourPurpose = Global.Settings.Purposes.Work; tourPurpose <= Global.Settings.Purposes.School; tourPurpose++) { if (dayPattern.Tours[tourPurpose] == 1 && dayPattern.TotalStopPurposes >= 1) { alternative.AddUtilityTerm(1300 + 10 * tourPurpose, purposeLogsums[tourPurpose]); // usual location logsum x presence of stops in work or school pattern alternative.AddUtilityTerm(1300 + 10 * tourPurpose + 1, compositeLogsum); // home aggregate logsum x presence of stops in work or school pattern //alternative.AddUtilityTerm(1300 + 10 * tourPurpose + 2, atUsualLogsums[tourPurpose]); // at usual location aggregate logsum x presence of stops in work or school pattern GV: commented out as the sign is wrong } } for (int tourPurpose = Global.Settings.Purposes.Work; tourPurpose <= Global.Settings.Purposes.Social - 2; tourPurpose++) { for (int tourPurpose2 = tourPurpose + 1; tourPurpose2 <= Global.Settings.Purposes.Social; tourPurpose2++) { if (dayPattern.Tours[tourPurpose] > 0 && dayPattern.Tours[tourPurpose2] > 0) { alternative.AddUtilityTerm(1400 + 10 * tourPurpose + tourPurpose2, 1); // tour-tour comb. utility } } } for (int tourPurpose = Global.Settings.Purposes.Business; tourPurpose <= Global.Settings.Purposes.Business; tourPurpose++) { for (int tourPurpose2 = Global.Settings.Purposes.Escort; tourPurpose2 <= Global.Settings.Purposes.Social; tourPurpose2++) { if (dayPattern.Tours[tourPurpose] > 0 && dayPattern.Tours[tourPurpose2] > 0) { alternative.AddUtilityTerm(1461, 1); // tour-tour comb. utility for business combos } } } for (int stopPurpose = Global.Settings.Purposes.Work; stopPurpose <= Global.Settings.Purposes.Social - 2; stopPurpose++) { for (int stopPurpose2 = stopPurpose + 1; stopPurpose2 <= Global.Settings.Purposes.Social; stopPurpose2++) { if (dayPattern.Stops[stopPurpose] > 0 && dayPattern.Stops[stopPurpose2] > 0) { alternative.AddUtilityTerm(1500 + 10 * stopPurpose + stopPurpose2, 1); // stop-stop comb. utility } } } if (dayPattern.TotalTourPurposes > 0 && dayPattern.TotalStopPurposes > 0) { int totalStopPurposes = dayPattern.TotalStopPurposes; if (totalStopPurposes > 3) { totalStopPurposes = 3; } alternative.AddUtilityTerm(1600 + 10 * dayPattern.TotalTourPurposes + totalStopPurposes, 1); // nttour-ntstop utility } if (dayPattern.TotalTourPurposes - dayPattern.Tours[Global.Settings.Purposes.Work] - dayPattern.Tours[Global.Settings.Purposes.Business] - dayPattern.Tours[Global.Settings.Purposes.School] > 0) { // tour utility alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(tourComponentIndex)); } if (dayPattern.TotalStopPurposes - dayPattern.Stops[Global.Settings.Purposes.Work] - dayPattern.Stops[Global.Settings.Purposes.Business] - dayPattern.Stops[Global.Settings.Purposes.School] > 0) { // stop utility alternative.AddUtilityComponent(choiceProbabilityCalculator.GetUtilityComponent(stopComponentIndex)); } } }
private void RunModel(ChoiceProbabilityCalculator choiceProbabilityCalculator, HouseholdDayWrapper householdDay, int jHTSimulated, int genChoice, bool[,] jHTAvailable, bool[] pHTAvailable, int[][] altParticipants, int choice = Constants.DEFAULT_VALUE) { IEnumerable <PersonDayWrapper> orderedPersonDays = householdDay.PersonDays.OrderBy(p => p.GetJointHalfTourParticipationPriority()).ToList().Cast <PersonDayWrapper>(); int threadAssignedIndex = ParallelUtility.threadLocalAssignedIndex.Value; int pairedHalfTour = genChoice == 1 ? 1 : 0; int firstHalfTour = genChoice == 2 ? 1 : 0; int secondHalfTour = genChoice == 3 ? 1 : 0; double income = householdDay.Household.Income < 0 ? Global.Configuration.Coefficients_BaseCostCoefficientIncomeLevel : householdDay.Household.Income; // missing converted to 30K double incomeMultiple = Math.Min(Math.Max(income / Global.Configuration.Coefficients_BaseCostCoefficientIncomeLevel, .1), 10); // ranges for extreme values double incomePower = Global.Configuration.Coefficients_CostCoefficientIncomePower_Work; double costCoefficient = Global.Coefficients_BaseCostCoefficientPerMonetaryUnit / Math.Pow(incomeMultiple, incomePower); double votValue = (60.0 * Global.Configuration.Coefficients_MeanTimeCoefficient_Work) / costCoefficient; // in $/hour // set household characteristics here that don't depend on person characteristics int hhsize = householdDay.Household.Size; 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[] 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[] pType7AgeUnder12 = new int[6]; int[] pType7Age12Plus = new int[6]; int[] pAgeUnder12 = new int[6]; int[] pAge5To8 = new int[6]; int[] pAge9To12 = new int[6]; int[] pAge13To15 = new int[6]; int[] pAge = new int[6]; int[] pDrivingAge = 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 && 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; } pPatternType[count] = personDay.PatternType; pConstant[count] = 1; pType8[count] = personDay.Person.IsChildUnder5.ToFlag(); 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(); pAdultFemale[count] = personDay.Person.IsAdultFemale.ToFlag(); pType7AgeUnder12[count] = (personDay.Person.IsChildAge5Through15 && personDay.Person.Age < 12).ToFlag(); pType7Age12Plus[count] = (personDay.Person.IsChildAge5Through15 && personDay.Person.Age >= 12).ToFlag(); pAgeUnder12[count] = (personDay.Person.Age < 12).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(); pAge[count] = personDay.Person.Age; pDrivingAge[count] = personDay.Person.IsDrivingAge.ToFlag(); } } // set household characteristics here that do depend on person characteristics //bool partTimeWorkerIsAvailable = false; //for (int i = 1; i <= 5; i++) { // if (pType2[i] == 1 && pPatternType[i] == Constants.PatternType.MANDATORY && pHTAvailable[i] == true) // partTimeWorkerIsAvailable = true; // //} // set person characteristics here that depend on household characteristics //int[] pFullTimeWorkerButPartTimeWorkerIsAvailable = new int[6]; //for (int i = 1; i <= 5; i++) { // if (pType1[i] == 1 && partTimeWorkerIsAvailable) { // pFullTimeWorkerButPartTimeWorkerIsAvailable[i] = 1; // } //} 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, pType1[p]); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(02, pType2[p]); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(03, pType3[p]); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(04, pType4[p]); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(05, pType5[p]); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(06, pType6[p]); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(07, pType7[p]); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(08, pType8[p]); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(09, pAge5To8[p]); //choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(10, pAge9To12[p]); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(11, pAdultFemale[p]); //choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(12, pType1[p] * firstHalfTour); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(13, pType1[p] * secondHalfTour); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(14, pType2[p] * firstHalfTour); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(15, pType2[p] * secondHalfTour); //choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(16, (1 - pAdult[p]) * firstHalfTour); choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(17, (1 - pAdult[p]) * secondHalfTour); //choiceProbabilityCalculator.GetUtilityComponent(componentPerson[p]).AddUtilityTerm(18, pFullTimeWorkerButPartTimeWorkerIsAvailable[p]); } //create two-way match interaction utility components int[,] componentMatch = new int[6, 6]; int iMatchAgeUnder12 = 0; int iMatchAdult = 0; int iMatchAdultWithChildrenUnder16 = 0; double distanceInMiles = 0; double inverseOfDistanceInMiles = 0; double logAgeDiffAdult = 0; double logAgeDiffChild = 0; for (int t2 = 1; t2 <= 5; t2++) { for (int t1 = 1; t1 < t2; t1++) { //populate match variables iMatchAgeUnder12 = pAgeUnder12[t1] * pAgeUnder12[t2]; iMatchAdult = pAdult[t1] * pAdult[t2]; iMatchAdultWithChildrenUnder16 = pAdultWithChildrenUnder16[t1] * pAdultWithChildrenUnder16[t2]; logAgeDiffChild = Math.Log(1 + Math.Abs(pAge[t1] - pAge[t2])) * (pAge[t1] <= 18).ToFlag() * (pAge[t2] <= 18).ToFlag(); logAgeDiffAdult = Math.Log(1 + Math.Abs(pAge[t1] - pAge[t2])) * (pAge[t1] >= 18).ToFlag() * (pAge[t2] >= 18).ToFlag(); distanceInMiles = 0; inverseOfDistanceInMiles = 0; if (pPatternType[t1] > 0 && pPatternType[t2] > 0) { double zzDist = ImpedanceRoster.GetValue("distance", Global.Settings.Modes.Sov, Global.Settings.PathTypes.FullNetwork, votValue, Global.Settings.Times.EightAM, pUsualLocationZoneId[t1], pUsualLocationZoneId[t2]).Variable; double circuityDistance = (zzDist > Global.Configuration.MaximumBlendingDistance || Global.Configuration.DestinationScale != Global.Settings.DestinationScales.Parcel) ? pUsualLocationParcel[t1].CalculateShortDistance(pUsualLocationParcel[t2], /* doNewCorrections */ false) : Constants.DEFAULT_VALUE; SkimValue skimValue = Global.Configuration.DestinationScale != Global.Settings.DestinationScales.Parcel ? ImpedanceRoster.GetValue("ivtime", Global.Settings.Modes.Sov, Global.Settings.PathTypes.FullNetwork, votValue, Global.Settings.Times.EightAM, pUsualLocationZoneId[t1], pUsualLocationZoneId[t2]) : ImpedanceRoster.GetValue("ivtime", Global.Settings.Modes.Sov, Global.Settings.PathTypes.FullNetwork, votValue, Global.Settings.Times.EightAM, pUsualLocationParcel[t1], pUsualLocationParcel[t2], circuityDistance); distanceInMiles = skimValue.BlendVariable; inverseOfDistanceInMiles = 1 / (Math.Max(0.1, distanceInMiles)); } //create and populate components componentIndex++; componentMatch[t1, t2] = componentIndex; choiceProbabilityCalculator.CreateUtilityComponent(componentMatch[t1, t2]); choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(21, iMatchAdultWithChildrenUnder16); choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(22, inverseOfDistanceInMiles); choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(23, logAgeDiffChild); choiceProbabilityCalculator.GetUtilityComponent(componentMatch[t1, t2]).AddUtilityTerm(24, logAgeDiffAdult); } } //create two-way cross interaction utility components int[,] componentCross = new int[6, 6]; int iCrossAgeUnderTwelveAndAdult = 0; //int iCrossAge13To15AndAdultFemale = 0; //int iCrossAge9To12AndAdultFemale = 0; //int iCrossAge5To8AndAdultFemale = 0; //int iCrossAgeUnder5AndAdultFemale = 0; //int iCrossAgeUnder5AndFTWorker = 0; for (int t2 = 1; t2 <= 5; t2++) { for (int t1 = 1; t1 <= 5; t1++) { if (!(t1 == t2)) { //populate cross variables iCrossAgeUnderTwelveAndAdult = pAgeUnder12[t1] * pAdult[t2]; //iCrossAge13To15AndAdultFemale = pAge13To15[t1] * pAdultFemale[t2]; //iCrossAge9To12AndAdultFemale = pAge9To12[t1] * pAdultFemale[t2]; //iCrossAge5To8AndAdultFemale = pAge5To8[t1] * pAdultFemale[t2]; //iCrossAgeUnder5AndAdultFemale = pType8[t1] * pAdultFemale[t2]; //iCrossAgeUnder5AndFTWorker = pType8[t1] * pType1[t2]; //create and populate cross components componentIndex++; componentCross[t1, t2] = componentIndex; choiceProbabilityCalculator.CreateUtilityComponent(componentCross[t1, t2]); choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(41, iCrossAgeUnderTwelveAndAdult); //choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(42, iCrossAge13To15AndAdultFemale); //choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(43, iCrossAge9To12AndAdultFemale); //choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(44, iCrossAge5To8AndAdultFemale); //choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(45, iCrossAgeUnder5AndAdultFemale); //choiceProbabilityCalculator.GetUtilityComponent(componentCross[t1, t2]).AddUtilityTerm(46, iCrossAgeUnder5AndFTWorker); } } } //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 based on person unavailability for (int i = 1; i <= 5; i++) { if (altParticipants[alt][i] == 1 && (jHTAvailable[genChoice - 1, i] == false || pHTAvailable[i] == false)) { available[alt] = false; } } // restrict availability if nobody is an driving age bool altHasDrivingAge = false; for (int i = 1; i <= 5; i++) { if (altParticipants[alt][i] == 1 && pDrivingAge[i] > 0) { altHasDrivingAge = true; } } if (!altHasDrivingAge) { available[alt] = false; } // restrict availability if anybody has nonMandatory pattern type bool altHasNonMandatoryPatternType = false; for (int i = 1; i <= 5; i++) { if (altParticipants[alt][i] == 1 && !(pPatternType[i] == Global.Settings.PatternTypes.Mandatory)) { altHasNonMandatoryPatternType = true; } } if (altHasNonMandatoryPatternType) { available[alt] = false; } // restrict availability of alts that include less than 2 participants if (altParticipants[alt][7] < 2) { available[alt] = false; } //Generate alt-specific variables int numberOfParticipatingAdults = 0; int numberOfParticipatingChildren = 0; //bool includesAllMandatoryPatternPersons = true; if (available[alt] == true) { for (int i = 1; i <= 5; i++) { if (altParticipants[alt][i] == 1) { // totalParticipants++; if (pAdult[i] == 1) { numberOfParticipatingAdults++; } if (pAdult[i] == 0) { numberOfParticipatingChildren++; } } //else if (pPatternType[i] == Constants.PatternType.MANDATORY && pHTAvailable[i] == true) { includesAllMandatoryPatternPersons = false; } } } // 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(61, (numberOfParticipatingAdults > 1 && numberOfParticipatingChildren > 0) ? 1 : 0); //alternative.AddUtilityTerm(62, includesAllMandatoryPatternPersons.ToFlag()); //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])); } } } } } }