/// <summary> /// Generates all feasible sets of modes for the trip chain /// </summary> /// <param name="chain">The chain to operate on</param> public static void GenerateModeSets(this ITripChain chain) { //initiates the mode set ModeSet.InitModeSets(chain); ModeData[] data = new ModeData[chain.Trips.Count]; // Generate the random terms var trips = chain.Trips; for (int i = 0; i < data.Length; i++) { data[i] = ModeData.Get(trips[i]); if (data[i] != null) { data[i].GenerateError(); } } ModeSet set = ModeSet.Make(chain); // launch the recursive version to explore all sets GenerateModeSets(chain, data, set); //clear temp var 'mode' that was used in generate mode set algo foreach (var trip in chain.Trips) { trip.Mode = null; } }
/// <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--; } }