public Workflow Reschedule(Workflow workflow, Heur heuristics) { var wf = new Workflow(workflow); while (wf.readyTasks.Count > 0) { var estimatedTasks = new IEnumerable <Task> [wf.readyTasks.Count]; for (int i = 0; i < wf.readyTasks.Count; i++) { estimatedTasks[i] = new List <Task>(); var task = wf.readyTasks[i]; for (int j = 0; j < wf.resources.Length; j++) { var resource = wf.resources[j]; var taskOnResource = new Task(task); taskOnResource.estimatedCompletionTime = Estimate(taskOnResource, resource); taskOnResource.realCompletionTime = -1; taskOnResource.resourceId = j; ((List <Task>)estimatedTasks[i]).Add(taskOnResource); } estimatedTasks[i] = estimatedTasks[i].OrderBy(e => e.estimatedCompletionTime); } var selectedTask = heuristics(estimatedTasks); int selectedResoucreId = selectedTask.resourceId; if (wf.resources[selectedResoucreId].IsAvailable()) { // launch selected task on selected resource selectedTask.realCompletionTime = NextRealTime(selectedTask, wf.resources[selectedResoucreId], wf.systemMean, wf.systemDeviation); wf.resources[selectedResoucreId].estimatedAvailabilityTime += selectedTask.estimatedCompletionTime; wf.resources[selectedResoucreId].realAvailabilityTime += selectedTask.realCompletionTime; wf.resources[selectedResoucreId].currentTaskId = selectedTask.id; wf.readyTasks.RemoveAll(task => task.id == selectedTask.id); wf.launchedTasks.Add(selectedTask); } else { // schedule selected task on selected resource wf.resources[selectedResoucreId].estimatedAvailabilityTime += selectedTask.estimatedCompletionTime; wf.readyTasks.RemoveAll(task => task.id == selectedTask.id); wf.scheduledTasks.Add(selectedTask); } } // возвращаяем все запланированные, но не запущенные задачи обратно в очередь -- а вдруг переназначим на другие ресурсы? Это актуально и потому, что могут придти новые задачи, и потому, что realTime != estimatedTime foreach (var task in wf.scheduledTasks) { wf.resources[task.resourceId].estimatedAvailabilityTime -= task.estimatedCompletionTime; } wf.readyTasks.AddRange(wf.scheduledTasks); wf.scheduledTasks.Clear(); return(wf); }
public Workflow Reschedule(Workflow workflow, Heur heuristics) { var wf = new Workflow(workflow); while (wf.readyTasks.Count > 0) { var estimatedTasks = new IEnumerable<Task>[wf.readyTasks.Count]; for (int i=0; i<wf.readyTasks.Count; i++) { estimatedTasks[i] = new List<Task>(); var task = wf.readyTasks[i]; for (int j=0; j<wf.resources.Length; j++) { var resource = wf.resources[j]; var taskOnResource = new Task(task); taskOnResource.estimatedCompletionTime = Estimate(taskOnResource, resource); taskOnResource.realCompletionTime = -1; taskOnResource.resourceId = j; ((List<Task>) estimatedTasks[i]).Add(taskOnResource); } estimatedTasks[i] = estimatedTasks[i].OrderBy(e => e.estimatedCompletionTime); } var selectedTask = heuristics(estimatedTasks); int selectedResoucreId = selectedTask.resourceId; if (wf.resources[selectedResoucreId].IsAvailable()) { // launch selected task on selected resource selectedTask.realCompletionTime = NextRealTime(selectedTask, wf.resources[selectedResoucreId], wf.systemMean, wf.systemDeviation); wf.resources[selectedResoucreId].estimatedAvailabilityTime += selectedTask.estimatedCompletionTime; wf.resources[selectedResoucreId].realAvailabilityTime += selectedTask.realCompletionTime; wf.resources[selectedResoucreId].currentTaskId = selectedTask.id; wf.readyTasks.RemoveAll(task => task.id == selectedTask.id); wf.launchedTasks.Add(selectedTask); } else { // schedule selected task on selected resource wf.resources[selectedResoucreId].estimatedAvailabilityTime += selectedTask.estimatedCompletionTime; wf.readyTasks.RemoveAll(task => task.id == selectedTask.id); wf.scheduledTasks.Add(selectedTask); } } // возвращаяем все запланированные, но не запущенные задачи обратно в очередь -- а вдруг переназначим на другие ресурсы? Это актуально и потому, что могут придти новые задачи, и потому, что realTime != estimatedTime foreach (var task in wf.scheduledTasks) wf.resources[task.resourceId].estimatedAvailabilityTime -= task.estimatedCompletionTime; wf.readyTasks.AddRange(wf.scheduledTasks); wf.scheduledTasks.Clear(); return wf; }