private double[][][][] ComputeZone(IRandomUtility randomUtility, int id) { var purposes = new double[Global.Settings.Purposes.TotalPurposes][][][]; for (var purpose = Global.Settings.Purposes.HomeBasedComposite; purpose <= Global.Settings.Purposes.Social; purpose++) { var carOwnerships = new double[Global.Settings.CarOwnerships.TotalCarOwnerships][][]; purposes[purpose] = carOwnerships; for (var carOwnership = Global.Settings.CarOwnerships.Child; carOwnership < Global.Settings.CarOwnerships.TotalCarOwnerships; carOwnership++) { var votALSegments = new double[Global.Settings.VotALSegments.TotalVotALSegments][]; carOwnerships[carOwnership] = votALSegments; for (var votALSegment = Global.Settings.VotALSegments.Low; votALSegment < Global.Settings.VotALSegments.TotalVotALSegments; votALSegment++) { var transitAccesses = new double[Global.Settings.TransitAccesses.TotalTransitAccesses]; votALSegments[votALSegment] = transitAccesses; for (var transitAccess = Global.Settings.TransitAccesses.Gt0AndLteQtrMi; transitAccess < Global.Settings.TransitAccesses.TotalTransitAccesses; transitAccess++) { transitAccesses[transitAccess] = Constants.EPSILON; } } } } IZone origin; if (!_eligibleZones.TryGetValue(id, out origin)) { return(purposes); } foreach (var destination in _eligibleZones.Values) { var setImpedance = true; var subzones = _zoneSubzones[destination.Id]; //const double parkingCost = 0; // mode impedance var sovInVehicleTimeFromOrigin = ImpedanceRoster.GetValue("ivtime", Global.Settings.Modes.Sov, Global.Settings.PathTypes.FullNetwork, Global.Settings.ValueOfTimes.DefaultVot, _middayStartMinute, id, destination.Id).Variable; var scaledSovDistanceFromOrigin = 0D; var transitGenTime = 0D; var walkGenTime = 0D; var sovGenTime = 0D; var hov2GenTime = 0D; for (var purpose = Global.Settings.Purposes.HomeBasedComposite; purpose <= Global.Settings.Purposes.Social; purpose++) { var carOwnerships = purposes[purpose]; var distanceParameters = _distanceParameters[purpose]; // set purpose inputs var escortFlag = (purpose == Global.Settings.Purposes.Escort).ToFlag(); var personalBusinessFlag = (purpose == Global.Settings.Purposes.PersonalBusiness).ToFlag(); var shoppingFlag = (purpose == Global.Settings.Purposes.Shopping).ToFlag(); var mealFlag = (purpose == Global.Settings.Purposes.Meal).ToFlag(); var socialFlag = (purpose == Global.Settings.Purposes.Social).ToFlag(); var p01 = _p01[purpose]; var p02 = _p02[purpose]; var p03 = _p03[purpose]; var p11 = _p11[purpose]; var p14 = _p14[purpose]; var p21 = _p21[purpose]; var p22 = _p22[purpose]; var p23 = _p23[purpose]; var p24 = _p24[purpose]; var p31 = _p31[purpose]; var p32 = _p32[purpose]; var p33 = _p33[purpose]; var p34 = _p34[purpose]; var p37 = _p37[purpose]; for (var carOwnership = Global.Settings.CarOwnerships.Child; carOwnership < Global.Settings.CarOwnerships.TotalCarOwnerships; carOwnership++) { var votALSegments = carOwnerships[carOwnership]; // set car ownership inputs var childFlag = FlagUtility.GetChildFlag(carOwnership); var noCarsFlag = FlagUtility.GetNoCarsFlag(carOwnership); var carCompetitionFlag = FlagUtility.GetCarCompetitionFlag(carOwnership); var noCarCompetitionFlag = FlagUtility.GetNoCarCompetitionFlag(carOwnership); var carDeficitFlag = FlagUtility.GetCarDeficitFlag(carOwnership); var distanceParameter = distanceParameters[carOwnership][1] / 100D; // converts hundreths of minutes to minutes for (var votALSegment = Global.Settings.VotALSegments.Low; votALSegment < Global.Settings.VotALSegments.TotalVotALSegments; votALSegment++) { var transitAccesses = votALSegments[votALSegment]; // set vot specific variables double timeCoefficient = Global.Settings.VotALSegments.TimeCoefficient; var costCoefficient = (votALSegment == Global.Settings.VotALSegments.Low) ? Global.Settings.VotALSegments.CostCoefficientLow : (votALSegment == Global.Settings.VotALSegments.Medium) ? Global.Settings.VotALSegments.CostCoefficientMedium : Global.Settings.VotALSegments.CostCoefficientHigh; for (var transitAccess = Global.Settings.TransitAccesses.Gt0AndLteQtrMi; transitAccess < Global.Settings.TransitAccesses.TotalTransitAccesses; transitAccess++) { var purposeUtility = 0D; // set transit access flags var hasNearTransitAccessFlag = (transitAccess == Global.Settings.TransitAccesses.Gt0AndLteQtrMi).ToFlag(); var hasNoTransitAccessFlag = (transitAccess == Global.Settings.TransitAccesses.None).ToFlag(); foreach (var subzone in subzones) { var size = subzone.GetSize(purpose); if (size <= -50 || sovInVehicleTimeFromOrigin <= 0 || (2 * sovInVehicleTimeFromOrigin) > distanceParameter) { continue; } // set subzone flags var hasNoTransitEgressFlag = 1 - (subzone.Sequence == 0 ? 1 : 0); if (setImpedance) { setImpedance = false; // intermediate variable of type IEnumerable<IPathTypeModel> is needed to acquire First() method as extension IEnumerable <IPathTypeModel> pathTypeModels; pathTypeModels = PathTypeModelFactory.Singleton.Run(randomUtility, id, destination.Id, _middayStartMinute, _middayStartMinute, Global.Settings.Purposes.PersonalBusiness, costCoefficient, timeCoefficient, true, 1, false, 0.0, false, Global.Settings.Modes.Walk); var walkPath = pathTypeModels.First(); walkGenTime = walkPath.GeneralizedTimeLogsum; pathTypeModels = PathTypeModelFactory.Singleton.Run(randomUtility, id, destination.Id, _middayStartMinute, _middayStartMinute, Global.Settings.Purposes.PersonalBusiness, costCoefficient, timeCoefficient, true, 1, false, 0.0, false, Global.Settings.Modes.Sov); var sovPath = pathTypeModels.First(); var sovDistanceFromOrigin = (sovPath.PathDistance / Global.Settings.DistanceUnitsPerMile) / 2D; scaledSovDistanceFromOrigin = sovDistanceFromOrigin / 10D; sovGenTime = sovPath.GeneralizedTimeLogsum; pathTypeModels = PathTypeModelFactory.Singleton.Run(randomUtility, id, destination.Id, _middayStartMinute, _middayStartMinute, Global.Settings.Purposes.PersonalBusiness, costCoefficient, timeCoefficient, true, 1, false, 0.0, false, Global.Settings.Modes.Hov2); var hov2Path = pathTypeModels.First(); hov2GenTime = hov2Path.GeneralizedTimeLogsum; //if using stop areas, use stop area nearest to the zone centroid var transitOid = (!Global.StopAreaIsEnabled) ? id : (origin.NearestStopAreaId > 0) ? Global.TransitStopAreaMapping[origin.NearestStopAreaId] : id; var transitDid = (!Global.StopAreaIsEnabled) ? destination.Id : (destination.NearestStopAreaId > 0) ? Global.TransitStopAreaMapping[destination.NearestStopAreaId] : id; pathTypeModels = PathTypeModelFactory.Singleton.Run(randomUtility, transitOid, transitDid, _middayStartMinute, _middayStartMinute, Global.Settings.Purposes.PersonalBusiness, costCoefficient, timeCoefficient, true, 1, false, Global.Configuration.Policy_UniversalTransitFareDiscountFraction, false, Global.Settings.Modes.Transit); var transitPath = pathTypeModels.First(); transitGenTime = transitPath.GeneralizedTimeLogsum; } var modeUtilitySum = 0D; // SOV if (childFlag == 0 && noCarsFlag == 0 && sovGenTime != Global.Settings.GeneralizedTimeUnavailable) { modeUtilitySum += ComputeUtility( //p01 * (OPERATING_COST_PER_MILE * sovDistance + sovToll) + //p01 * parkingCost + //p02 * sovInVehicleTime + timeCoefficient * sovGenTime + p11 + p14 * carCompetitionFlag); } // HOV if (hov2GenTime != Global.Settings.GeneralizedTimeUnavailable) { modeUtilitySum += ComputeUtility( //p01 * ((OPERATING_COST_PER_MILE * hov2Distance + hov2Toll) / CP_FACTOR) + //p01 * parkingCost / CP_FACTOR + //p02 * hov2InVehicleTime + timeCoefficient * hov2GenTime + p21 + p22 * childFlag + p23 * noCarsFlag + p24 * carCompetitionFlag); } // TRANSIT if (transitGenTime != Global.Settings.GeneralizedTimeUnavailable && hasNoTransitAccessFlag == 0 && hasNoTransitEgressFlag == 0) { modeUtilitySum += ComputeUtility( //p01 * transitFare + //p02 * transitInVehicleTime + //p03 * transitInitialWaitTime + //p03 * transitNumberOfBoards + timeCoefficient * transitGenTime + p31 + p32 * childFlag + p33 * noCarsFlag + p34 * carCompetitionFlag + p37 * hasNoTransitAccessFlag); } // WALK if (walkGenTime != Global.Settings.GeneralizedTimeUnavailable) { modeUtilitySum += ComputeUtility( //p03 * walkDistance * 20); timeCoefficient * walkGenTime); } var modeLogsum = modeUtilitySum > Constants.EPSILON ? Math.Log(modeUtilitySum) : -30D; switch (purpose) { case 1: // HOME_BASED_COMPOSITE purposeUtility += ComputeUtility( size + HBB002 * modeLogsum + HBB003 * modeLogsum * noCarsFlag + HBB007 * modeLogsum * (noCarsFlag + carCompetitionFlag) * hasNoTransitAccessFlag + HBB008 * modeLogsum * noCarCompetitionFlag * hasNoTransitAccessFlag + HBB012 * subzone.MixedUseMeasure * carCompetitionFlag + HBB013 * subzone.MixedUseMeasure * noCarCompetitionFlag + HBB014 * subzone.MixedUseMeasure * childFlag + HBB016 * scaledSovDistanceFromOrigin * noCarsFlag + HBB018 * scaledSovDistanceFromOrigin * childFlag); break; case 2: // WORK_BASED purposeUtility += ComputeUtility( size + WBB002 * modeLogsum + WBB011 * modeLogsum * noCarCompetitionFlag * hasNearTransitAccessFlag + WBB012 * subzone.MixedUseMeasure * carCompetitionFlag + WBB013 * subzone.MixedUseMeasure * noCarCompetitionFlag + WBB015 * scaledSovDistanceFromOrigin); break; default: // ESCORT, PERSONAL_BUSINESS, SHOPPING, MEAL, SOCIAL or RECREATION purposeUtility += ComputeUtility( size + PSB006 * escortFlag * modeLogsum + PSB007 * noCarsFlag * modeLogsum + PSB008 * escortFlag * carDeficitFlag * modeLogsum + PSB009 * escortFlag * childFlag * modeLogsum + PSB011 * escortFlag * carDeficitFlag * hasNoTransitAccessFlag * modeLogsum + PSB012 * escortFlag * noCarCompetitionFlag * hasNoTransitAccessFlag * modeLogsum + PSB014 * carDeficitFlag * hasNearTransitAccessFlag * modeLogsum + PSB016 * escortFlag * scaledSovDistanceFromOrigin + PSB017 * noCarsFlag * scaledSovDistanceFromOrigin + PSB018 * escortFlag * carDeficitFlag * scaledSovDistanceFromOrigin + PSB020 * escortFlag * carCompetitionFlag * subzone.MixedUseMeasure + PSB021 * escortFlag * noCarCompetitionFlag * subzone.MixedUseMeasure + PSB022 * escortFlag * childFlag * subzone.MixedUseMeasure + PSB023 * personalBusinessFlag * modeLogsum + PSB024 * personalBusinessFlag * carDeficitFlag * modeLogsum + PSB025 * personalBusinessFlag * childFlag * modeLogsum + PSB027 * personalBusinessFlag * noCarCompetitionFlag * hasNoTransitAccessFlag * modeLogsum + PSB029 * personalBusinessFlag * carDeficitFlag * scaledSovDistanceFromOrigin + PSB030 * personalBusinessFlag * childFlag * scaledSovDistanceFromOrigin + PSB031 * personalBusinessFlag * carCompetitionFlag * subzone.MixedUseMeasure + PSB032 * personalBusinessFlag * noCarCompetitionFlag * subzone.MixedUseMeasure + PSB033 * personalBusinessFlag * childFlag * subzone.MixedUseMeasure + PSB034 * shoppingFlag * modeLogsum + PSB035 * shoppingFlag * carDeficitFlag * modeLogsum + PSB036 * shoppingFlag * childFlag * modeLogsum + PSB037 * shoppingFlag * carDeficitFlag * hasNoTransitAccessFlag * modeLogsum + PSB038 * shoppingFlag * noCarCompetitionFlag * hasNoTransitAccessFlag * modeLogsum + PSB045 * mealFlag * modeLogsum + PSB047 * mealFlag * childFlag * modeLogsum + PSB049 * mealFlag * noCarCompetitionFlag * hasNoTransitAccessFlag * modeLogsum + PSB053 * mealFlag * carCompetitionFlag * subzone.MixedUseMeasure + PSB054 * mealFlag * noCarCompetitionFlag * subzone.MixedUseMeasure + PSB055 * mealFlag * childFlag * subzone.MixedUseMeasure + PSB056 * socialFlag * modeLogsum + PSB057 * socialFlag * carDeficitFlag * modeLogsum + PSB059 * socialFlag * carDeficitFlag * hasNoTransitAccessFlag * modeLogsum + PSB060 * socialFlag * noCarCompetitionFlag * hasNoTransitAccessFlag * modeLogsum + PSB063 * socialFlag * childFlag * scaledSovDistanceFromOrigin + PSB064 * socialFlag * carCompetitionFlag * subzone.MixedUseMeasure + PSB065 * socialFlag * noCarCompetitionFlag * subzone.MixedUseMeasure + PSB066 * socialFlag * childFlag * subzone.MixedUseMeasure); break; } } transitAccesses[transitAccess] += purposeUtility; } } } } } return(purposes); }