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, ITripWrapper trip, TripTime choice = null) { IPersonWrapper person = trip.Person; IPersonDayWrapper personDay = trip.PersonDay; ITourWrapper tour = trip.Tour; // person inputs int partTimeWorkerFlag = person.IsPartTimeWorker.ToFlag(); int nonworkingAdultFlag = person.IsNonworkingAdult.ToFlag(); int universityStudentFlag = person.IsUniversityStudent.ToFlag(); int retiredAdultFlag = person.IsRetiredAdult.ToFlag(); int drivingAgeStudentFlag = person.IsDrivingAgeStudent.ToFlag(); int childAge5Through15Flag = person.IsChildAge5Through15.ToFlag(); int childUnder5Flag = person.IsChildUnder5.ToFlag(); // set tour inputs int workTourFlag = tour.IsWorkPurpose().ToFlag(); int notWorkTourFlag = (!tour.IsWorkPurpose()).ToFlag(); int notHomeBasedTourFlag = (!tour.IsHomeBasedTour).ToFlag(); // set trip inputs bool originChangeMode = trip.Sequence > 1 && trip.GetPreviousTrip().DestinationPurpose == Global.Settings.Purposes.ChangeMode; int originWorkFlag = trip.IsWorkOriginPurpose().ToFlag(); int originSchoolFlag = trip.IsSchoolOriginPurpose().ToFlag(); int originEscortFlag = trip.IsEscortOriginPurpose().ToFlag(); int originShoppingFlag = trip.IsShoppingOriginPurpose().ToFlag(); int originPersonalBusinessFlag = trip.IsPersonalBusinessOriginPurpose().ToFlag(); int originMealFlag = trip.IsMealOriginPurpose().ToFlag(); int originSocialFlag = trip.IsSocialOriginPurpose().ToFlag(); int sovOrHovTripFlag = trip.UsesSovOrHovModes().ToFlag(); int transitTripFlag = trip.IsTransitMode().ToFlag(); int halfTourFromOriginFlag = trip.IsHalfTourFromOrigin.ToFlag(); int halfTourFromDestinationFlag = (!trip.IsHalfTourFromOrigin).ToFlag(); // set remaining inputs ITimeWindow timeWindow = tour.IsHomeBasedTour ? personDay.TimeWindow : tour.ParentTour.TimeWindow; ITripModeImpedance[] impedances = trip.GetTripModeImpedances(); int remainingToursCount = personDay.HomeBasedTours - personDay.GetTotalSimulatedTours(); int tripRemainingInHalfTour = (trip.DestinationParcel != null && trip.DestinationParcel != tour.OriginParcel).ToFlag(); // we don't know exact # for (int arrivalPeriodIndex = 1; arrivalPeriodIndex < DayPeriod.SmallDayPeriods.Length; arrivalPeriodIndex++) { MinuteSpan arrivalPeriod = DayPeriod.SmallDayPeriods[arrivalPeriodIndex]; int previousArrivalTime = trip.GetPreviousTrip().ArrivalTime; if (previousArrivalTime < arrivalPeriod.Start || previousArrivalTime > arrivalPeriod.End) { continue; } ITripModeImpedance arrivalImpedance = impedances[arrivalPeriod.Index]; // moved to here so not reset for every alternative foreach (TripTime time in TripTime.Times) { MinuteSpan departurePeriod = time.DeparturePeriod; // moved to here so can use travel time ITripModeImpedance departureImpedance = impedances[departurePeriod.Index]; // change availability check to include travel duration int travelDuration = (int)Math.Round(departureImpedance.TravelTime + 0.5); // if not the trip home, on a home-based tour, also include fastest time from the destinatinon to home // if (trip.Tour.IsHomeBasedTour && trip.DestinationPurpose != Global.Settings.Purposes.NoneOrHome) { // var fastestMode = Math.Min(trip.Tour.Mode, Global.Settings.Modes.Hov3); // var pathTypeModel = PathTypeModelFactory.Singleton.Run(trip.DestinationParcel, trip.Household.ResidenceParcel, departurePeriod.Middle, 0, // trip.Tour.DestinationPurpose, trip.Tour.CostCoefficient, trip.Tour.TimeCoefficient, // trip.Person.IsDrivingAge, trip.Household.VehiclesAvailable, trip.Tour.Person.TransitFareDiscountFraction, false, fastestMode).First(); // travelDuration += (int) Math.Round(pathTypeModel.PathTime + 0.5); // } int bestArrivalTime = trip.IsHalfTourFromOrigin ? Math.Max(departurePeriod.End - travelDuration, 1) : Math.Min(departurePeriod.Start + travelDuration, Global.Settings.Times.MinutesInADay); bool available = originChangeMode ? arrivalPeriod.Index == time.DeparturePeriod.Index : (trip.IsHalfTourFromOrigin && // if change mode, must be in same period arrivalPeriod.Index > departurePeriod.Index && timeWindow.EntireSpanIsAvailable(bestArrivalTime, arrivalPeriod.Start - 1)) || (!trip.IsHalfTourFromOrigin && arrivalPeriod.Index < departurePeriod.Index && timeWindow.EntireSpanIsAvailable(arrivalPeriod.End, bestArrivalTime - 1)) || arrivalPeriod.Index == time.DeparturePeriod.Index && timeWindow.TotalAvailableMinutes(arrivalPeriod.Start, arrivalPeriod.End) > travelDuration; double departurePeriodFraction = timeWindow.TotalAvailableMinutes(departurePeriod.Start, departurePeriod.End) / (departurePeriod.End - departurePeriod.Start + 1D); int duration = Math.Abs(departurePeriod.Middle - arrivalPeriod.Middle); available = available && departurePeriodFraction > 0; //ensure transit path type is available in alternative if (trip.Mode == Global.Settings.Modes.Transit && !Global.StopAreaIsEnabled) { double transitPathTypeInVehicleTime = ImpedanceRoster.GetValue("ivtime", trip.Mode, trip.PathType, trip.ValueOfTime, time.DeparturePeriod.Middle, trip.OriginParcel.ZoneId, trip.DestinationParcel.ZoneId).Variable; available = available && (transitPathTypeInVehicleTime > 0); } ChoiceProbabilityCalculator.Alternative alternative = choiceProbabilityCalculator.GetAlternative(time.Index, available, choice != null && choice.Equals(time)); // if (choice.Equals(tripTime) && !available) { // Console.WriteLine(available); // } if (!alternative.Available) { continue; } alternative.Choice = time; double departurePeriodShift = time.DeparturePeriod.Index * (48.0 / DayPeriod.SMALL_DAY_PERIOD_TOTAL_TRIP_TIMES); //adjust shift amount if period lengths change if (trip.IsHalfTourFromOrigin) { // outbound "departure" (arrival) period constants alternative.AddUtilityTerm(11, time.DeparturePeriod.Middle.IsBetween(Global.Settings.Times.ThreeAM, Global.Settings.Times.SixAM).ToFlag()); alternative.AddUtilityTerm(12, time.DeparturePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.SixAM, Global.Settings.Times.SevenAM).ToFlag()); alternative.AddUtilityTerm(13, time.DeparturePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.SevenAM, Global.Settings.Times.EightAM).ToFlag()); alternative.AddUtilityTerm(14, time.DeparturePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.EightAM, Global.Settings.Times.NineAM).ToFlag()); alternative.AddUtilityTerm(15, time.DeparturePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.NineAM, Global.Settings.Times.TenAM).ToFlag()); alternative.AddUtilityTerm(16, time.DeparturePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.TenAM, Global.Settings.Times.OnePM).ToFlag()); alternative.AddUtilityTerm(17, time.DeparturePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.OnePM, Global.Settings.Times.FourPM).ToFlag()); alternative.AddUtilityTerm(18, time.DeparturePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.FourPM, Global.Settings.Times.SevenPM).ToFlag()); alternative.AddUtilityTerm(19, time.DeparturePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.SevenPM, Global.Settings.Times.TenPM).ToFlag()); alternative.AddUtilityTerm(20, time.DeparturePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.TenPM, Global.Settings.Times.MinutesInADay).ToFlag()); } else { // return departure period constants alternative.AddUtilityTerm(21, time.DeparturePeriod.Middle.IsBetween(Global.Settings.Times.ThreeAM, Global.Settings.Times.SevenAM).ToFlag()); alternative.AddUtilityTerm(22, time.DeparturePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.SevenAM, Global.Settings.Times.TenAM).ToFlag()); alternative.AddUtilityTerm(23, time.DeparturePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.TenAM, Global.Settings.Times.OnePM).ToFlag()); alternative.AddUtilityTerm(24, time.DeparturePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.OnePM, Global.Settings.Times.ThreePM).ToFlag()); alternative.AddUtilityTerm(124, time.DeparturePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.ThreePM, Global.Settings.Times.FourPM).ToFlag()); alternative.AddUtilityTerm(25, time.DeparturePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.FourPM, Global.Settings.Times.FivePM).ToFlag()); alternative.AddUtilityTerm(26, time.DeparturePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.FivePM, Global.Settings.Times.SixPM).ToFlag()); alternative.AddUtilityTerm(27, time.DeparturePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.SixPM, Global.Settings.Times.SevenPM).ToFlag()); alternative.AddUtilityTerm(28, time.DeparturePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.SevenPM, Global.Settings.Times.NinePM).ToFlag()); alternative.AddUtilityTerm(29, time.DeparturePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.NinePM, Global.Settings.Times.Midnight).ToFlag()); alternative.AddUtilityTerm(30, time.DeparturePeriod.Middle.IsLeftExclusiveBetween(Global.Settings.Times.Midnight, Global.Settings.Times.MinutesInADay).ToFlag()); } alternative.AddUtilityTerm(31, duration.IsRightExclusiveBetween(Global.Settings.Times.ZeroHours, Global.Settings.Times.OneHour).ToFlag()); // 0 - 1 alternative.AddUtilityTerm(32, duration.IsRightExclusiveBetween(Global.Settings.Times.OneHour, Global.Settings.Times.TwoHours).ToFlag()); // 1 - 2 alternative.AddUtilityTerm(33, duration.IsRightExclusiveBetween(Global.Settings.Times.TwoHours, Global.Settings.Times.ThreeHours).ToFlag()); // 2 - 3 alternative.AddUtilityTerm(34, duration.IsRightExclusiveBetween(Global.Settings.Times.ThreeHours, Global.Settings.Times.FiveHours).ToFlag()); // 3 - 5 alternative.AddUtilityTerm(35, duration.IsRightExclusiveBetween(Global.Settings.Times.FiveHours, Global.Settings.Times.SevenHours).ToFlag()); // 5 - 7 alternative.AddUtilityTerm(36, duration.IsRightExclusiveBetween(Global.Settings.Times.SevenHours, Global.Settings.Times.NineHours).ToFlag()); // 7 - 9 alternative.AddUtilityTerm(37, duration.IsRightExclusiveBetween(Global.Settings.Times.NineHours, Global.Settings.Times.TwelveHours).ToFlag()); // 9 - 12 alternative.AddUtilityTerm(38, duration.IsRightExclusiveBetween(Global.Settings.Times.TwelveHours, Global.Settings.Times.FourteenHours).ToFlag()); // 12 - 14 alternative.AddUtilityTerm(39, duration.IsRightExclusiveBetween(Global.Settings.Times.FourteenHours, Global.Settings.Times.EighteenHours).ToFlag()); // 14 - 18 alternative.AddUtilityTerm(40, (duration >= Global.Settings.Times.EighteenHours).ToFlag()); // 18 - 24 //these were duplicate departure shift variables before, and constrained to 0 in all the coefficient files - replaced by duration shifts alternative.AddUtilityTerm(41, partTimeWorkerFlag * duration); alternative.AddUtilityTerm(43, nonworkingAdultFlag * duration); alternative.AddUtilityTerm(45, universityStudentFlag * duration); alternative.AddUtilityTerm(47, retiredAdultFlag * duration); alternative.AddUtilityTerm(49, drivingAgeStudentFlag * duration); alternative.AddUtilityTerm(51, childAge5Through15Flag * duration); alternative.AddUtilityTerm(53, childUnder5Flag * duration); alternative.AddUtilityTerm(55, halfTourFromOriginFlag * duration); alternative.AddUtilityTerm(131, workTourFlag * halfTourFromOriginFlag * duration); alternative.AddUtilityTerm(133, workTourFlag * halfTourFromDestinationFlag * duration); alternative.AddUtilityTerm(135, notWorkTourFlag * halfTourFromDestinationFlag * duration); alternative.AddUtilityTerm(137, notHomeBasedTourFlag * duration); alternative.AddUtilityTerm(145, originEscortFlag * duration); alternative.AddUtilityTerm(147, originShoppingFlag * duration); alternative.AddUtilityTerm(149, originMealFlag * duration); alternative.AddUtilityTerm(151, originSocialFlag * duration); alternative.AddUtilityTerm(153, originPersonalBusinessFlag * duration); alternative.AddUtilityTerm(155, originSchoolFlag * duration); alternative.AddUtilityTerm(42, partTimeWorkerFlag * departurePeriodShift); alternative.AddUtilityTerm(44, nonworkingAdultFlag * departurePeriodShift); alternative.AddUtilityTerm(46, universityStudentFlag * departurePeriodShift); alternative.AddUtilityTerm(48, retiredAdultFlag * departurePeriodShift); alternative.AddUtilityTerm(50, drivingAgeStudentFlag * departurePeriodShift); alternative.AddUtilityTerm(52, childAge5Through15Flag * departurePeriodShift); alternative.AddUtilityTerm(54, childUnder5Flag * departurePeriodShift); alternative.AddUtilityTerm(56, halfTourFromOriginFlag * departurePeriodShift); alternative.AddUtilityTerm(132, workTourFlag * halfTourFromOriginFlag * departurePeriodShift); alternative.AddUtilityTerm(134, workTourFlag * halfTourFromDestinationFlag * departurePeriodShift); alternative.AddUtilityTerm(136, notWorkTourFlag * halfTourFromDestinationFlag * departurePeriodShift); alternative.AddUtilityTerm(138, notHomeBasedTourFlag * departurePeriodShift); alternative.AddUtilityTerm(146, originEscortFlag * departurePeriodShift); alternative.AddUtilityTerm(148, originShoppingFlag * departurePeriodShift); alternative.AddUtilityTerm(150, originMealFlag * departurePeriodShift); alternative.AddUtilityTerm(152, originSocialFlag * departurePeriodShift); alternative.AddUtilityTerm(154, originPersonalBusinessFlag * departurePeriodShift); alternative.AddUtilityTerm(156, originSchoolFlag * departurePeriodShift); alternative.AddUtilityTerm(86, sovOrHovTripFlag * Math.Max(departureImpedance.GeneralizedTime, 0) * tour.TimeCoefficient); alternative.AddUtilityTerm(88, transitTripFlag * Math.Max(departureImpedance.GeneralizedTime, 0) * tour.TimeCoefficient); alternative.AddUtilityTerm(89, transitTripFlag * (departureImpedance.GeneralizedTime < 0).ToFlag()); alternative.AddUtilityTerm(92, halfTourFromOriginFlag * Math.Log(departurePeriodFraction)); alternative.AddUtilityTerm(92, halfTourFromDestinationFlag * Math.Log(departurePeriodFraction)); alternative.AddUtilityTerm(99, tripRemainingInHalfTour / (1D + halfTourFromOriginFlag * departureImpedance.AdjacentMinutesBefore + halfTourFromDestinationFlag * departureImpedance.AdjacentMinutesAfter)); alternative.AddUtilityTerm(97, remainingToursCount / (1D + halfTourFromOriginFlag * (arrivalImpedance.TotalMinutesAfter + departureImpedance.TotalMinutesBefore) + halfTourFromDestinationFlag * (arrivalImpedance.TotalMinutesBefore + departureImpedance.TotalMinutesAfter))); alternative.AddUtilityTerm(98, remainingToursCount / (1D + halfTourFromOriginFlag * Math.Max(arrivalImpedance.MaxMinutesBefore, departureImpedance.MaxMinutesBefore) + halfTourFromDestinationFlag * Math.Max(arrivalImpedance.MaxMinutesBefore, departureImpedance.MaxMinutesAfter))); } } }
public static void SetImpedanceAndWindow(ITimeWindow timeWindow, ITourWrapper tour, HTourModeTime modeTimes, int constrainedHouseholdCars, double constrainedTransitDiscountFraction, IParcelWrapper alternativeDestination = null) { { var alternativeIndex = modeTimes.Index; var arrivalPeriod = modeTimes.ArrivalPeriod; var departurePeriod = modeTimes.DeparturePeriod; var mode = modeTimes.Mode; var destinationParcel = (alternativeDestination != null) ? alternativeDestination : tour.DestinationParcel; var arrivalPeriodAvailableMinutes = timeWindow.TotalAvailableMinutes(arrivalPeriod.Start, arrivalPeriod.End); var departurePeriodAvailableMinutes = timeWindow.TotalAvailableMinutes(departurePeriod.Start, departurePeriod.End); var householdCars = constrainedHouseholdCars >= 0 ? constrainedHouseholdCars : tour.Household.VehiclesAvailable; var transitDiscountFraction = constrainedTransitDiscountFraction >= 0 ? constrainedTransitDiscountFraction : tour.Person.GetTransitFareDiscountFraction(); // set round trip mode LOS and mode availability if (arrivalPeriodAvailableMinutes <= 0 || departurePeriodAvailableMinutes <= 0 || (mode == Global.Settings.Modes.ParkAndRide && tour.DestinationPurpose != Global.Settings.Purposes.Work) || (mode == Global.Settings.Modes.SchoolBus && tour.DestinationPurpose != Global.Settings.Purposes.School) || (Global.Configuration.IsInEstimationMode && destinationParcel == null)) { modeTimes.ModeAvailableToDestination = false; modeTimes.ModeAvailableFromDestination = false; } //ACTUM must also use round trip path type to preserve the tour-based nonlinear gamma utility functions //else if (mode == Global.Settings.Modes.ParkAndRide) { else if (mode == Global.Settings.Modes.ParkAndRide || Global.Configuration.PathImpedance_UtilityForm_Auto == 1 || Global.Configuration.PathImpedance_UtilityForm_Transit == 1) { // park and ride has to use round-trip path type, approximate each half IEnumerable <dynamic> pathTypeModels = PathTypeModelFactory.Model.Run( tour.Household.RandomUtility, tour.OriginParcel, destinationParcel, arrivalPeriod.Middle, departurePeriod.Middle, tour.DestinationPurpose, tour.CostCoefficient, tour.TimeCoefficient, tour.Person.IsDrivingAge, householdCars, tour.Person.TransitPassOwnership, tour.Household.OwnsAutomatedVehicles > 0, transitDiscountFraction, false, mode); var pathTypeModel = pathTypeModels.First(x => x.Mode == mode); modeTimes.ModeAvailableToDestination = pathTypeModel.Available; modeTimes.ModeAvailableFromDestination = pathTypeModel.Available; if (pathTypeModel.Available) { modeTimes.TravelTimeToDestination = pathTypeModel.PathTime / 2.0; modeTimes.GeneralizedTimeToDestination = pathTypeModel.GeneralizedTimeLogsum / 2.0; modeTimes.TravelTimeFromDestination = pathTypeModel.PathTime / 2.0; modeTimes.GeneralizedTimeFromDestination = pathTypeModel.GeneralizedTimeLogsum / 2.0; modeTimes.ParkAndRideOriginStopAreaKey = pathTypeModel.PathOriginStopAreaKey; modeTimes.ParkAndRideDestinationStopAreaKey = pathTypeModel.PathDestinationStopAreaKey; modeTimes.TransitTime = pathTypeModel.PathTransitTime; modeTimes.TransitDistance = pathTypeModel.PathTransitDistance; modeTimes.TransitCost = pathTypeModel.PathTransitCost; modeTimes.TransitGeneralizedTime = pathTypeModel.PathTransitGeneralizedTime; modeTimes.WalkTime = pathTypeModel.PathWalkTime; modeTimes.WalkDistance = pathTypeModel.PathWalkDistance; modeTimes.BikeTime = pathTypeModel.PathBikeTime; modeTimes.BikeDistance = pathTypeModel.PathBikeDistance; modeTimes.BikeCost = pathTypeModel.PathBikeCost; modeTimes.OriginAccessMode = pathTypeModel.PathOriginAccessMode; modeTimes.OriginAccessTime = pathTypeModel.PathOriginAccessTime; modeTimes.OriginAccessDistance = pathTypeModel.PathOriginAccessDistance; modeTimes.OriginAccessCost = pathTypeModel.PathOriginAccessCost; modeTimes.DestinationAccessMode = pathTypeModel.PathDestinationAccessMode; modeTimes.DestinationAccessTime = pathTypeModel.PathDestinationAccessTime; modeTimes.DestinationAccessDistance = pathTypeModel.PathDestinationAccessDistance; modeTimes.DestinationAccessCost = pathTypeModel.PathDestinationAccessCost; modeTimes.PathDistance = pathTypeModel.PathDistance; modeTimes.PathCost = pathTypeModel.PathCost; } } else { // get times for each half tour separately, using HOV3 for school bus var pathMode = (mode == Global.Settings.Modes.SchoolBus) ? Global.Settings.Modes.Hov3 : mode; //if (tour.Household.Id == 80205 && tour.PersonDay.HouseholdDay.AttemptedSimulations == 9 && (pathMode == 1 || pathMode == 5)) { if (tour.Person.IsDrivingAge == true && tour.Household.VehiclesAvailable > 0 && pathMode == 3) { bool testbreak = true; } IEnumerable <dynamic> pathTypeModels = PathTypeModelFactory.Model.Run( tour.Household.RandomUtility, tour.OriginParcel, destinationParcel, arrivalPeriod.Middle, 0, tour.DestinationPurpose, tour.CostCoefficient, tour.TimeCoefficient, tour.Person.IsDrivingAge, householdCars, tour.Person.TransitPassOwnership, tour.Household.OwnsAutomatedVehicles > 0, transitDiscountFraction, false, pathMode); var pathTypeModel = pathTypeModels.First(x => x.Mode == pathMode); modeTimes.ModeAvailableToDestination = pathTypeModel.Available; if (pathTypeModel.Available) { modeTimes.TravelTimeToDestination = pathTypeModel.PathTime; modeTimes.GeneralizedTimeToDestination = pathTypeModel.GeneralizedTimeLogsum; } pathTypeModels = PathTypeModelFactory.Model.Run( tour.Household.RandomUtility, destinationParcel, tour.OriginParcel, departurePeriod.Middle, 0, tour.DestinationPurpose, tour.CostCoefficient, tour.TimeCoefficient, tour.Person.IsDrivingAge, householdCars, tour.Person.TransitPassOwnership, tour.Household.OwnsAutomatedVehicles > 0, transitDiscountFraction, false, pathMode); pathTypeModel = pathTypeModels.First(x => x.Mode == pathMode); modeTimes.ModeAvailableFromDestination = pathTypeModel.Available; if (pathTypeModel.Available) { modeTimes.TravelTimeFromDestination = pathTypeModel.PathTime; modeTimes.GeneralizedTimeFromDestination = pathTypeModel.GeneralizedTimeLogsum; } } if (tour.Household.Id == 2138 && tour.Person.Sequence == 1 && tour.Sequence == 1) { bool testbreak = true; } if (modeTimes.ModeAvailableToDestination == false) { } if (modeTimes.ModeAvailableFromDestination == false) { } if (modeTimes.ModeAvailableToDestination && modeTimes.ModeAvailableFromDestination) { modeTimes.LongestFeasibleWindow = timeWindow.LongestAvailableFeasibleWindow(arrivalPeriod.End, departurePeriod.Start, modeTimes.TravelTimeToDestination, modeTimes.TravelTimeFromDestination, Global.Settings.Times.MinimumActivityDuration); } } }
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, 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); } } } }