/// <summary> /// Calculates and stores the best trip chain for /// each type of vehicle (and NPV) /// </summary> /// <param name="chain">The chain to calculate</param> public static void SelectBestPerVehicleType(this ITripChain chain) { ModeSet[] best = chain["BestForVehicle"] as ModeSet[]; var sets = ModeSet.GetModeSets(chain); if (best == null) { best = new ModeSet[TashaRuntime.VehicleTypes.Count + 1]; chain.Attach("BestForVehicle", best); } for (int i = 0; i < best.Length; i++) { best[i] = null; } foreach (var set in sets) { IVehicleType type = null; foreach (var mode in set.ChosenMode) { if (mode.RequiresVehicle != null) { type = mode.RequiresVehicle; break; } } int index = TashaRuntime.VehicleTypes.IndexOf(type); best[index + 1] = (best[index + 1] == null || best[index + 1].U < set.U) ? set : best[index + 1]; } }
/// <summary> /// Finds the best non-personal vehicle mode set for a tour, returns false otherwise /// </summary> /// <param name="tour"></param> /// <param name="bestSet"></param> /// <param name="U"></param> /// <returns></returns> private static bool BestNonVehicleModeSetForTour(List <ITripChain> tour, out IList <ITashaMode> bestSet, out double U) { bestSet = null; U = Double.MinValue; ITripChain firstTripChain = tour[0]; IList <ModeSet> firstModeSet = (IList <ModeSet>)firstTripChain["ModeSets"]; List <List <ModeSet> > ModeSets = new List <List <ModeSet> >(); foreach (var chain in tour) { ModeSets.Add(new List <ModeSet>(ModeSet.GetModeSets(chain))); } Dictionary <ModeSet, double> setAndU = new Dictionary <ModeSet, double>(); foreach (var set in ModeSets[0]) { double curU = set.U; bool existsInAllSets = true; for (int i = 1; i < ModeSets.Count; i++) { bool exists = false; foreach (var nextSet in ModeSets[i]) { if (SameChosenModes(set, nextSet)) { exists = true; curU += nextSet.U; break; } } if (!exists) { existsInAllSets = false; break; } } if (existsInAllSets) { setAndU.Add(set, curU); } } if (setAndU.Count == 0) { return(false); } foreach (var element in setAndU) { IList <ITashaMode> chosen = element.Key.ChosenMode; double u = element.Value; if (u > U) { bestSet = chosen; U = u; } } return(true); }
/// <summary> /// Goes through the data and regenerates the random components for utility /// </summary> /// <param name="household"></param> public static void UpdateUtilities(this ITashaHousehold household) { foreach (var p in household.Persons) { foreach (var chain in p.TripChains) { foreach (var trip in chain.Trips) { ModeData.Get(trip).GenerateError(); } foreach (var modeSet in ModeSet.GetModeSets(chain)) { modeSet.RecalculateU(); } chain.SelectBestPerVehicleType(); } } }
/// <summary> /// Generates all feasible sets of modes for the trip chain /// </summary> /// <param name="chain">The chain to operate on</param> /// <param name="data">The ModeData for each trip</param> /// <param name="set">The mode set we are building</param> private static void GenerateModeSets(ITripChain chain, ModeData[] data, ModeSet set) { var modes = TashaRuntime.AllModes; var numberOfModes = modes.Count - TashaRuntime.SharedModes.Count; var topLevel = data.Length - 1; int level = 0; double utility = 0; int mode = 0; List <ModeSet> possibleTripChains = ModeSet.GetModeSets(chain) as List <ModeSet>; Stack <int> previousMode = new Stack <int>(10); Stack <double> previousU = new Stack <double>(10); var trips = chain.Trips; ITrip currentTrip = trips[0]; while (level != -1) { for ( ; mode < numberOfModes; mode++) { // For each feasible mode var currentData = data[level]; if (currentData.Feasible[mode]) { // find the total utility double newU = utility + currentData.V[mode] + currentData.Error[mode]; // store the mode into our set and chain set.ChosenMode[level] = currentTrip.Mode = modes[mode]; // if we are at the end, store the set if (level >= topLevel) { bool feasible = true; // make sure this chain is allowed for (int j = 0; j < numberOfModes; j++) { // if this doesn't work don't save it if (!modes[j].Feasible(chain)) { feasible = false; break; } } if (feasible) { possibleTripChains?.Add(ModeSet.Make(set, newU)); } } else { // otherwise go to the next trip level++; previousU.Push(utility); utility = newU; currentTrip = trips[level]; previousMode.Push(mode); mode = -1; } } } if (previousMode.Count > 0) { mode = previousMode.Pop() + 1; utility = previousU.Pop(); currentTrip = trips[level - 1]; } level--; } }