/// <summary> /// Returns the next machine to schedule. /// </summary> /// <param name="next">Next</param> /// <param name="choices">Choices</param> /// <param name="current">Curent</param> /// <returns>Boolean</returns> public virtual bool TryGetNext(out MachineInfo next, IList<MachineInfo> choices, MachineInfo current) { var machines = choices.OrderBy(mi => mi.Machine.Id.Value).ToList(); var currentMachineIdx = machines.IndexOf(current); var orderedMachines = machines.GetRange(currentMachineIdx, machines.Count - currentMachineIdx); if (currentMachineIdx != 0) { orderedMachines.AddRange(machines.GetRange(0, currentMachineIdx)); } var availableMachines = orderedMachines.Where( mi => mi.IsEnabled && !mi.IsBlocked && !mi.IsWaiting).ToList(); if (availableMachines.Count == 0) { next = null; return false; } int idx = 0; while (this.RemainingDelays.Count > 0 && this.ExploredSteps == this.RemainingDelays[0]) { idx = (idx + 1) % availableMachines.Count; this.RemainingDelays.RemoveAt(0); IO.PrintLine("<DelayLog> Inserted delay, '{0}' remaining.", this.RemainingDelays.Count); } next = availableMachines[idx]; this.ExploredSteps++; return true; }
/// <summary> /// Returns the next machine to schedule. /// </summary> /// <param name="next">Next</param> /// <param name="choices">Choices</param> /// <param name="current">Curent</param> /// <returns>Boolean</returns> public bool TryGetNext(out MachineInfo next, IList<MachineInfo> choices, MachineInfo current) { if (this.BoundedDFS.HasReachedDepthBound()) { return this.Random.TryGetNext(out next, choices, current); } { return this.BoundedDFS.TryGetNext(out next, choices, current); } }
/// <summary> /// Returns the next machine to schedule. /// </summary> /// <param name="next">Next</param> /// <param name="choices">Choices</param> /// <param name="current">Curent</param> /// <returns>Boolean</returns> public bool TryGetNext(out MachineInfo next, IList<MachineInfo> choices, MachineInfo current) { var availableMachines = choices.Where( m => m.IsEnabled && !m.IsBlocked && !m.IsWaiting).ToList(); if (availableMachines.Count == 0) { next = null; return false; } int idx = this.Random.Next(availableMachines.Count); next = availableMachines[idx]; this.ExploredSteps++; return true; }
/// <summary> /// Returns the next machine to schedule. /// </summary> /// <param name="next">Next</param> /// <param name="choices">Choices</param> /// <param name="current">Curent</param> /// <returns>Boolean</returns> public bool TryGetNext(out MachineInfo next, IList<MachineInfo> choices, MachineInfo current) { var availableMachines = choices.Where( m => m.IsEnabled && !m.IsBlocked && !m.IsWaiting).ToList(); if (availableMachines.Count == 0) { next = null; return false; } SChoice nextChoice = null; List<SChoice> scs = null; if (this.SchIndex < this.ScheduleStack.Count) { scs = this.ScheduleStack[this.SchIndex]; } else { scs = new List<SChoice>(); foreach (var task in availableMachines) { scs.Add(new SChoice(task.Machine.Id.Value)); } this.ScheduleStack.Add(scs); } nextChoice = scs.FirstOrDefault(val => !val.IsDone); if (nextChoice == null) { next = null; return false; } if (this.SchIndex > 0) { var previousChoice = this.ScheduleStack[this.SchIndex - 1].Last(val => val.IsDone); previousChoice.IsDone = false; } next = availableMachines.Find(task => task.Machine.Id.Value == nextChoice.Id); nextChoice.IsDone = true; this.SchIndex++; if (next == null) { return false; } this.ExploredSteps++; return true; }
/// <summary> /// Notify that a new task has been created for the given machine. /// </summary> /// <param name="id">TaskId</param> /// <param name="machine">Machine</param> internal virtual void NotifyNewTaskCreated(int id, AbstractMachine machine) { var machineInfo = new MachineInfo(id, machine); IO.Debug("<ScheduleDebug> Created task {0} for machine {1}({2}).", machineInfo.Id, machineInfo.Machine.GetType(), machineInfo.Machine.Id.MVal); if (this.MachineInfos.Count == 0) { machineInfo.IsActive = true; } this.MachineInfos.Add(machineInfo); this.TaskMap.Add(id, machineInfo); }
/// <summary> /// Returns the next machine to schedule. /// </summary> /// <param name="next">Next</param> /// <param name="choices">Choices</param> /// <param name="current">Curent</param> /// <returns>Boolean</returns> public bool TryGetNext(out MachineInfo next, IList<MachineInfo> choices, MachineInfo current) { next = null; List<MachineInfo> availableMachines; if (this.Configuration.BoundOperations) { availableMachines = this.GetPrioritizedMachines(choices.ToList(), current); } else { choices = choices.OrderBy(machine => machine.Machine.Id.Value).ToList(); availableMachines = choices.Where( m => m.IsEnabled && !m.IsBlocked && !m.IsWaiting).ToList(); } if (availableMachines.Count == 0) { IO.PrintLine(">> No available machines to schedule ..."); return false; } this.ExploredSteps++; var parsed = false; while (!parsed) { if (this.InputCache.Count >= this.ExploredSteps) { var step = this.InputCache[this.ExploredSteps - 1]; int idx = 0; if (step.Length > 0) { idx = Convert.ToInt32(step); } else { this.InputCache[this.ExploredSteps - 1] = "0"; } next = availableMachines[idx]; parsed = true; break; } IO.PrintLine(">> Available machines to schedule ..."); for (int idx = 0; idx < availableMachines.Count; idx++) { var m = availableMachines[idx]; if (this.Configuration.BoundOperations) { IO.PrintLine(">> [{0}] '{1}({2})' with operation id '{3}'", idx, m.Machine, m.Machine.Id.MVal, m.Machine.OperationId); } else { IO.PrintLine(">> [{0}] '{1}({2})'", idx, m.Machine, m.Machine.Id.MVal); } } IO.PrintLine(">> Choose machine to schedule [step '{0}']", this.ExploredSteps); var input = IO.GetLine(); if (input.Equals("replay")) { if (!this.Replay()) { continue; } this.Configuration.SchedulingIterations++; this.ConfigureNextIteration(); return false; } else if (input.Equals("jump")) { this.Jump(); continue; } else if (input.Equals("reset")) { this.Configuration.SchedulingIterations++; this.Reset(); return false; } else if (input.Length > 0) { try { var idx = Convert.ToInt32(input); if (idx < 0) { IO.PrintLine(">> Expected positive integer, please retry ..."); continue; } next = availableMachines[idx]; if (next == null) { IO.PrintLine(">> Unexpected id, please retry ..."); continue; } if (this.Configuration.BoundOperations) { this.PrioritizedOperationId = next.Machine.OperationId; } } catch (FormatException) { IO.PrintLine(">> Wrong format, please retry ..."); continue; } } else { next = availableMachines[0]; } this.InputCache.Add(input); parsed = true; } return true; }
/// <summary> /// Returns the prioritized machines. /// </summary> /// <param name="choices">Choices</param> /// <param name="current">Curent</param> /// <returns>Boolean</returns> private List<MachineInfo> GetPrioritizedMachines(List<MachineInfo> choices, MachineInfo current) { choices = choices.OrderBy(mi => mi.Machine.Id.Value).ToList(); choices = choices.OrderBy(mi => mi.Machine.OperationId).ToList(); MachineInfo priorityMachine = current; var prioritizedMachines = new List<MachineInfo>(); if (current.Machine.OperationId == this.PrioritizedOperationId) { var currentMachineIdx = choices.IndexOf(current); prioritizedMachines = choices.GetRange(currentMachineIdx, choices.Count - currentMachineIdx); if (currentMachineIdx != 0) { prioritizedMachines.AddRange(choices.GetRange(0, currentMachineIdx)); } } else { priorityMachine = choices.First(mi => mi.Machine.OperationId == this.PrioritizedOperationId); var priorityMachineIdx = choices.IndexOf(priorityMachine); prioritizedMachines = choices.GetRange(priorityMachineIdx, choices.Count - priorityMachineIdx); if (priorityMachineIdx != 0) { prioritizedMachines.AddRange(choices.GetRange(0, priorityMachineIdx)); } } prioritizedMachines = prioritizedMachines.Where(mi => mi.IsEnabled && !mi.IsBlocked && !mi.IsWaiting).ToList(); if (prioritizedMachines.Count == 0) { return prioritizedMachines; } return prioritizedMachines; }
/// <summary> /// Notify that a new task has been created for the given machine. /// </summary> /// <param name="id">TaskId</param> /// <param name="machine">Machine</param> internal override void NotifyNewTaskCreated(int id, AbstractMachine machine) { var machineInfo = new MachineInfo(id, machine); IO.Debug("<ScheduleDebug> Created task {0} for machine {1}({2}).", machineInfo.Id, machineInfo.Machine.GetType(), machineInfo.Machine.Id.MVal); if (base.MachineInfos.Count == 0) { machineInfo.IsActive = true; } base.MachineInfos.Add(machineInfo); base.TaskMap.Add(id, machineInfo); if (machine is TaskMachine) { this.WrappedTaskMap.Add((machine as TaskMachine).WrappedTask.Id, machineInfo); } }
/// <summary> /// Returns true if the current operation has completed. /// </summary> /// <param name="opid">OperationId</param> /// <returns>Boolean</returns> private bool HasCurrentOperationCompleted(IEnumerable<MachineInfo> choices, MachineInfo current) { foreach (var choice in choices.Where(mi => !mi.IsCompleted)) { if (choice.Machine.OperationId == current.Machine.OperationId || choice.Machine.IsOperationPending(current.Machine.OperationId)) { return false; } } return true; }
/// <summary> /// Returns the next machine to schedule. /// </summary> /// <param name="next">Next</param> /// <param name="choices">Choices</param> /// <param name="current">Curent</param> /// <returns>Boolean</returns> public bool TryGetNext(out MachineInfo next, IList<MachineInfo> choices, MachineInfo current) { if (this.HasCurrentOperationCompleted(choices, current)) { this.Operations.Remove(current.Machine.OperationId); IO.Debug("<OperationDebug> Removes operation '{0}'.", current.Machine.OperationId); } var availableMachines = choices.Where( mi => mi.IsEnabled && !mi.IsBlocked && !mi.IsWaiting).ToList(); if (availableMachines.Count == 0) { next = null; return false; } this.TryRegisterNewOperations(availableMachines, current); var nextOperation = this.GetNextOperation(availableMachines, current); IO.Debug("<OperationDebug> Chosen operation '{0}'.", nextOperation); if (IO.Debugging) { IO.Print("<OperationDebug> Operation list: "); for (int opIdx = 0; opIdx < this.Operations.Count; opIdx++) { if (opIdx < this.Operations.Count - 1) { IO.Print("'{0}', ", this.Operations[opIdx]); } else { IO.Print("'{0}'.\n", this.Operations[opIdx]); } } } if (this.Configuration.DynamicEventQueuePrioritization) { var machineChoices = availableMachines.Where(mi => mi.Machine is Machine). Select(m => m.Machine as Machine); foreach (var choice in machineChoices) { choice.SetQueueOperationPriority(nextOperation); } } next = this.GetNextMachineWithOperation(availableMachines, nextOperation); this.ExploredSteps++; return true; }
/// <summary> /// Tries to register any new operations. /// </summary> /// <param name="choices">Choices</param> /// <param name="current">Curent</param> private void TryRegisterNewOperations(IEnumerable<MachineInfo> choices, MachineInfo current) { if (this.Operations.Count == 0) { this.Operations.Add(current.Machine.OperationId); } var operationIds = choices.Select(mi => mi.Machine.OperationId).Distinct(); foreach (var id in operationIds.Where(id => !this.Operations.Contains(id))) { var opIndex = this.Random.Next(this.Operations.Count) + 1; this.Operations.Insert(opIndex, id); IO.Debug("<OperationDebug> Detected new operation '{0}' at index '{1}'.", id, opIndex); } }
/// <summary> /// Returns the next operation to schedule. /// </summary> /// <param name="choices">Choices</param> /// <param name="current">Curent</param> /// <returns>OperationId</returns> protected abstract int GetNextOperation(List<MachineInfo> choices, MachineInfo current);
/// <summary> /// Returns the prioritized machine. /// </summary> /// <param name="choices">Choices</param> /// <param name="current">Curent</param> /// <returns>MachineInfo</returns> private MachineInfo GetPrioritizedMachine(List<MachineInfo> choices, MachineInfo current) { if (this.PrioritizedMachines.Count == 0) { this.PrioritizedMachines.Add(current.Machine.Id); } foreach (var mi in choices.Where(mi => !this.PrioritizedMachines.Contains(mi.Machine.Id))) { var mIndex = this.Random.Next(this.PrioritizedMachines.Count) + 1; this.PrioritizedMachines.Insert(mIndex, mi.Machine.Id); IO.Debug("<PCTDebug> Detected new machine '{0}({1})' at index '{2}'.", mi.Machine, mi.Machine.Id.MVal, mIndex); } if (this.PriorityChangePoints.Contains(this.ExploredSteps)) { if (choices.Count == 1) { this.MovePriorityChangePointForward(); } else { var priority = this.GetHighestPriorityEnabledMachine(choices); this.PrioritizedMachines.Remove(priority); this.PrioritizedMachines.Add(priority); IO.PrintLine("<PCTLog> Machine '{0}({1})' changes to lowest priority.", priority.Type, priority.MVal); } } var prioritizedMachine = this.GetHighestPriorityEnabledMachine(choices); IO.Debug("<PCTDebug> Prioritized machine '{0}({1})'.", prioritizedMachine.Type, prioritizedMachine.MVal); if (IO.Debugging) { IO.Print("<PCTDebug> Priority list: "); for (int idx = 0; idx < this.PrioritizedMachines.Count; idx++) { if (idx < this.PrioritizedMachines.Count - 1) { IO.Print("'{0}({1})', ", this.PrioritizedMachines[idx].Type, this.PrioritizedMachines[idx].MVal); } else { IO.Print("'{0}({1})'.\n", this.PrioritizedMachines[idx].Type, this.PrioritizedMachines[idx].MVal); } } } var prioritizedMachineInfo = choices.First(mi => mi.Machine.Id.Equals(prioritizedMachine)); return prioritizedMachineInfo; }
/// <summary> /// Returns the next machine to schedule. /// </summary> /// <param name="next">Next</param> /// <param name="choices">Choices</param> /// <param name="current">Curent</param> /// <returns>Boolean</returns> public bool TryGetNext(out MachineInfo next, IList<MachineInfo> choices, MachineInfo current) { var availableMachines = choices.Where( mi => mi.IsEnabled && !mi.IsBlocked && !mi.IsWaiting).ToList(); if (availableMachines.Count == 0) { next = null; return false; } next = this.GetPrioritizedMachine(availableMachines, current); this.ExploredSteps++; return true; }
/// <summary> /// Returns the next operation to schedule. /// </summary> /// <param name="choices">Choices</param> /// <param name="current">Curent</param> /// <returns>OperationId</returns> protected override int GetNextOperation(List<MachineInfo> choices, MachineInfo current) { int idx = this.Random.Next(choices.Count); var machineWithNextOperation = choices[idx]; return machineWithNextOperation.Machine.OperationId; //var enabledOperations = base.Operations.Where(val => choices.Any( // m => m.Machine.OperationId == val)).ToList(); //int opIdx = base.Random.Next(enabledOperations.Count); //return enabledOperations[opIdx]; }