/// <summary> /// Generate schedules by adding a new event to the end of existing ones /// Create a new system schedule list by adding each of the new Task commands for the Assets onto each of the old schedules /// </summary> /// <param name="system"></param> /// <param name="tasks"></param> /// <param name="initialStateList"></param> /// <returns></returns> public virtual List <SystemSchedule> GenerateSchedules(SystemClass system, Stack <Task> tasks, SystemState initialStateList) { log.Info("SIMULATING... "); // Create empty systemSchedule with initial state set SystemSchedule emptySchedule = new SystemSchedule(initialStateList); List <SystemSchedule> systemSchedules = new List <SystemSchedule>(); systemSchedules.Add(emptySchedule); // if all asset position types are not dynamic types, can pregenerate accesses for the simulation bool canPregenAccess = true; foreach (var asset in system.Assets) { if (asset.AssetDynamicState != null) { canPregenAccess &= asset.AssetDynamicState.Type != HSFUniverse.DynamicStateType.DYNAMIC_ECI && asset.AssetDynamicState.Type != HSFUniverse.DynamicStateType.DYNAMIC_LLA; } else { canPregenAccess = false; } } // if accesses can be pregenerated, do it now Stack <Access> preGeneratedAccesses = new Stack <Access>(); Stack <Stack <Access> > scheduleCombos = new Stack <Stack <Access> >(); if (canPregenAccess) { log.Info("Pregenerating Accesses..."); //DWORD startPregenTickCount = GetTickCount(); preGeneratedAccesses = Access.pregenerateAccessesByAsset(system, tasks, _startTime, _endTime, _stepLength); //DWORD endPregenTickCount = GetTickCount(); //pregenTimeMs = endPregenTickCount - startPregenTickCount; //writeAccessReport(access_pregen, tasks); - TODO: Finish this code - EAM log.Info("Done pregenerating accesses"); } // otherwise generate an exhaustive list of possibilities for assetTaskList else { log.Info("Generating Exhaustive Task Combinations... "); Stack <Stack <Access> > exhaustive = new Stack <Stack <Access> >(); Stack <Access> allAccesses = new Stack <Access>(tasks.Count); foreach (var asset in system.Assets) { foreach (var task in tasks) { allAccesses.Push(new Access(asset, task)); } allAccesses.Push(new Access(asset, null)); exhaustive.Push(allAccesses); allAccesses.Clear(); } scheduleCombos = (Stack <Stack <Access> >)exhaustive.CartesianProduct(); log.Info("Done generating exhaustive task combinations"); } /// TODO: Delete (or never create in the first place) schedules with inconsistent asset tasks (because of asset dependencies) // Find the next timestep for the simulation //DWORD startSchedTickCount = GetTickCount(); int i = 1; List <SystemSchedule> potentialSystemSchedules = new List <SystemSchedule>(); List <SystemSchedule> systemCanPerformList = new List <SystemSchedule>(); for (double currentTime = _startTime; currentTime < _endTime; currentTime += _stepLength) { log.Info("Simulation Time " + currentTime); // if accesses are pregenerated, look up the access information and update assetTaskList if (canPregenAccess) { scheduleCombos = GenerateExhaustiveSystemSchedules(preGeneratedAccesses, system, currentTime); } // Check if it's necessary to crop the systemSchedule list to a more managable number if (systemSchedules.Count > _maxNumSchedules) { log.Info("Cropping " + systemSchedules.Count + " Schedules."); CropSchedules(systemSchedules, ScheduleEvaluator, emptySchedule); systemSchedules.Add(emptySchedule); } // Generate an exhaustive list of new tasks possible from the combinations of Assets and Tasks //TODO: Parallelize this. int k = 0; foreach (var oldSystemSchedule in systemSchedules) { potentialSystemSchedules.Add(new SystemSchedule(new StateHistory(oldSystemSchedule.AllStates))); foreach (var newAccessStack in scheduleCombos) { k++; if (oldSystemSchedule.CanAddTasks(newAccessStack, currentTime)) { var CopySchedule = new StateHistory(oldSystemSchedule.AllStates); potentialSystemSchedules.Add(new SystemSchedule(CopySchedule, newAccessStack, currentTime)); // oldSched = new SystemSchedule(CopySchedule); } } } int numSched = 0; foreach (var potentialSchedule in potentialSystemSchedules) { if (Checker.CheckSchedule(system, potentialSchedule)) { systemCanPerformList.Add(potentialSchedule); } numSched++; } foreach (SystemSchedule systemSchedule in systemCanPerformList) { systemSchedule.ScheduleValue = ScheduleEvaluator.Evaluate(systemSchedule); } systemCanPerformList.Sort((x, y) => x.ScheduleValue.CompareTo(y.ScheduleValue)); systemCanPerformList.Reverse(); // Merge old and new systemSchedules var oldSystemCanPerfrom = new List <SystemSchedule>(systemCanPerformList); systemSchedules.InsertRange(0, oldSystemCanPerfrom);//<--This was potentialSystemSchedules potentialSystemSchedules.Clear(); systemCanPerformList.Clear(); // Print completion percentage in command window Console.WriteLine("Scheduler Status: {0}% done; {1} schedules generated.", 100 * currentTime / _endTime, systemSchedules.Count); } return(systemSchedules); }
public virtual List <SystemSchedule> GenerateSchedules(SystemClass system, Stack <MissionElements.Task> tasks, SystemState initialStateList, Evaluator scheduleEvaluator) { //system.setThreadNum(1); //DWORD startTickCount = GetTickCount(); //accumSchedTimeMs = 0; // get the global dependencies object //Dependencies dependencies = new Dependencies().Instance(); Console.WriteLine("SIMULATING... "); // Create empty systemSchedule with initial state set SystemSchedule emptySchedule = new SystemSchedule(initialStateList); List <SystemSchedule> systemSchedules = new List <SystemSchedule>(); systemSchedules.Add(emptySchedule); // if all asset position types are not dynamic types, can pregenerate accesses for the simulation bool canPregenAccess = true; foreach (var asset in system.Assets) { if (asset.AssetDynamicState != null) { canPregenAccess &= asset.AssetDynamicState.Type != HSFUniverse.DynamicStateType.DYNAMIC_ECI && asset.AssetDynamicState.Type != HSFUniverse.DynamicStateType.DYNAMIC_LLA; } else { canPregenAccess = false; } } // if accesses can be pregenerated, do it now Stack <Access> preGeneratedAccesses = new Stack <Access>(); Stack <Stack <Access> > scheduleCombos = new Stack <Stack <Access> >(); if (canPregenAccess) { Console.Write("Pregenerating Accesses..."); //DWORD startPregenTickCount = GetTickCount(); preGeneratedAccesses = Access.pregenerateAccessesByAsset(system, tasks, _startTime, _endTime, _stepLength); //DWORD endPregenTickCount = GetTickCount(); //pregenTimeMs = endPregenTickCount - startPregenTickCount; //writeAccessReport(access_pregen, tasks); - TODO: Finish this code - EAM Console.WriteLine(" DONE!"); } // otherwise generate an exhaustive list of possibilities for assetTaskList else { Console.Write("Generating Exhaustive Task Combinations... "); Stack <Stack <Access> > exhaustive = new Stack <Stack <Access> >(); Stack <Access> allAccesses = new Stack <Access>(tasks.Count); foreach (var asset in system.Assets) { foreach (var task in tasks) { allAccesses.Push(new Access(asset, task)); } exhaustive.Push(allAccesses); allAccesses.Clear(); } scheduleCombos = (Stack <Stack <Access> >)exhaustive.CartesianProduct(); Console.WriteLine(" DONE!"); } /// \todo TODO: Delete (or never create in the first place) schedules with inconsistent asset tasks (because of asset dependencies) // Find the next timestep for the simulation //DWORD startSchedTickCount = GetTickCount(); for (double currentTime = _startTime; currentTime < _endTime; currentTime += _stepLength) { Console.WriteLine(currentTime); // if accesses are pregenerated, look up the access information and update assetTaskList if (canPregenAccess) { scheduleCombos = GenerateExhaustiveSystemSchedules(preGeneratedAccesses, system, currentTime); } // Check if it's necessary to crop the systemSchedule list to a more managable number if (systemSchedules.Count > _maxNumSchedules) { CropSchedules(systemSchedules, scheduleEvaluator, emptySchedule); } // Create a new system schedule list by adding each of the new Task commands for the Assets onto each of the old schedules // Start timing // Generate an exhaustive list of new tasks possible from the combinations of Assets and Tasks //TODO: Parallelize this. List <SystemSchedule> potentialSystemSchedules = new List <SystemSchedule>(); foreach (var oldSystemSchedule in systemSchedules) { foreach (var newAccessStack in scheduleCombos) { if (oldSystemSchedule.CanAddTasks(newAccessStack, currentTime)) { SystemSchedule newSched = new SystemSchedule(oldSystemSchedule, newAccessStack, currentTime); potentialSystemSchedules.Add(newSched); } } potentialSystemSchedules.Add(new SystemSchedule(oldSystemSchedule)); //deep copy } // TODO EAM: Remove this and only add new SystemScedule if canAddTasks and CanPerform are both true. That way we don't need to delete SystemSchedules after the fact below. List <SystemSchedule> systemCanPerformList = new List <SystemSchedule>(); //for (list<systemSchedule*>::iterator newSchedIt = newSysScheds.begin(); newSchedIt != newSysScheds.end(); newSchedIt++) // The parallel version // Should we use a Partitioner? // Need to test this... /* * Stopwatch stopWatch = new Stopwatch(); * stopWatch.Start(); * // The Scheduler has to call the CanPerform for a SystemClass, SystemSchedule combo. The SystemClass * Parallel.ForEach(potentialSystemSchedules, (currentSchedule) => * { * // dependencies.updateStates(newSchedule.getEndStates()); * if (Checker.CheckSchedule(system, currentSchedule)) * systemCanPerformList.Add(currentSchedule); * Console.WriteLine("Processing {0} on thread {1}", currentSchedule.ToString(), Thread.CurrentThread.ManagedThreadId); * }); * stopWatch.Stop(); * * TimeSpan ts = stopWatch.Elapsed; * // Format and display the TimeSpan value. * string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", * ts.Hours, ts.Minutes, ts.Seconds, * ts.Milliseconds / 10); * Console.WriteLine("Parallel Scheduler RunTime: " + elapsedTime); */ foreach (var potentialSchedule in potentialSystemSchedules) { if (Checker.CheckSchedule(system, potentialSchedule)) { systemCanPerformList.Add(potentialSchedule); } //dependencies.updateStates(newSchedule.getEndStates()); //systemCanPerformList.Push(system.canPerform(potentialSchedule)); } // End timing /* * // delete systemSchedules (and corresponding lower level classes) that are not possible * list<systemSchedule*>::iterator eraseIt = newSysScheds.begin(); * for (vector<bool>::iterator successIt = systemCanPerformList.begin(); successIt != systemCanPerformList.end(); successIt++) * { * if (*successIt) { eraseIt++; } * else { * delete* eraseIt; * eraseIt = newSysScheds.erase(eraseIt); * } * } */ // Merge old and new systemSchedules systemSchedules.InsertRange(0, systemCanPerformList);//<--This was potentialSystemSchedules potentialSystemSchedules.Clear(); // Print completion percentage in command window Console.Write("Scheduler Status: {0} done; {1} schedules generated.", 100 * currentTime / _endTime, systemSchedules.Count); } if (systemSchedules.Count > _maxNumSchedules) { CropSchedules(systemSchedules, scheduleEvaluator, emptySchedule); } // THIS GOES AWAY IF CAN EXTEND HAPPENS IN THE SUBSYSTEM - EAM // extend all schedules to the end of the simulation /* * foreach (var schedule in systemSchedules) * { * bool canExtendUntilEnd = true; * // Iterate through Subsystem Nodes and set that they havent run * foreach (var subsystem in system.Subsystems) * subsystem.IsEvaluated = false; * * int subAssetNum; * foreach (var subsystem in system.Subsystems) * canExtendUntilEnd &= subsystem.canPerform(schedule.getSubsystemNewState(subsystem.Asset), schedule.getSubsytemNewTask(subsystem.Asset), system.Environment, _endTime, true); * * // Iterate through constraints * foreach (var constraint in system.Constraints) * { * canExtendUntilEnd &= constraint.Accepts(schedule); * } * // for (vector <const Constraint*>::const_iterator constraintIt = system.getConstraints().begin(); constraintIt != system.getConstraints().end(); constraintIt++) * // canExtendUntilEnd &= (*constraintIt)->accepts(*schedIt); * if (!canExtendUntilEnd) { * //delete *schedIt; * Console.WriteLine("Schedule may not be valid"); * } * } */ //DWORD endSchedTickCount = GetTickCount(); //schedTimeMs = endSchedTickCount - startSchedTickCount; //DWORD endTickCount = GetTickCount(); //totalTimeMs = endTickCount - startTickCount; return(systemSchedules); }