public override SchedulareState Execute(Schedulare schedulare, ShiftsContainer shiftsContainer) { InitParams(schedulare, shiftsContainer); var schedulareState = GetSchedulareState(schedulare.DeepClone(), shiftsContainer, TreeRoot); UpdateCurrentBestSolution(schedulareState); OpenSet.Add(schedulareState); ExecuteStopwatch.Start(); var shiftsList = GetShiftList(schedulareState.Node.Value); while (!IsGoal()) { var randShift = GetRandomShift(shiftsList); // DEBUG PrintDebugData(shiftsContainer, CurrentBestSolution); ExplorationStopwatch.Reset(); ExplorationStopwatch.Start(); #region Exploration loop while (ExplorationStopwatch.Elapsed.TotalSeconds < EXPLORATION_TIME_SECONDS) { // IsGoal // OR break id exploration ended with no result if (IsGoal() || OpenSet.Count.Equals(0)) { break; } var currState = OpenSet.FindMin(); UpdateCurrentBestSolution(currState); OpenSet.DeleteMin(); CloseSet.Add(currState.Node.Value); for (int workerIndex = 0; workerIndex < randShift.Shift.Workers.Count; workerIndex++) { var currStateInOrderToReplaceEmp = currState.DeepClone(); var currStateNodeInOrderToReplaceEmp = currStateInOrderToReplaceEmp.Node; RemoveEmpFromCurrShift(randShift, workerIndex, currStateInOrderToReplaceEmp); // DEBUG PrintDebugData(shiftsContainer, currStateInOrderToReplaceEmp); #region build new nodes foreach (var emp in shiftsContainer.EmployeeConstraints.Select(x => x.Name)) { var newNodeSchedulare = currStateNodeInOrderToReplaceEmp.Value.DeepClone(); var currShiftToAssin = GetIncompleteShift(newNodeSchedulare, shiftsContainer); // modify schdulare currShiftToAssin.Workers.Remove(currShiftToAssin.Workers.FirstOrDefault(x => x.Name.IsNullOrEmpty())); currShiftToAssin.Workers.Add(new Worker() { Name = emp }); // validate if the new state in tabu list - is yes ignore it if (CloseSet.Contains(newNodeSchedulare)) { if (!DEBUG) { continue; } Console.WriteLine($"####### Tabu list filterd #######"); continue; } // add new node to the tree - currNode var childNode = currStateNodeInOrderToReplaceEmp.AddChild(newNodeSchedulare); // get new state var newNodeState = GetSchedulareState(newNodeSchedulare, shiftsContainer, childNode); // add new state to openSet OpenSet.Add(newNodeState); // DEBUG PrintDebugData(shiftsContainer, newNodeState); } #endregion } } ExplorationStopwatch.Stop(); #endregion if (IsGoal()) { break; } } var ret = CurrentBestSolution; CurrentBestSolution = null; IsFinished = false; ExecuteStopwatch.Reset(); return(ret); }
public override SchedulareState Execute(Schedulare schedulare, ShiftsContainer shiftsContainer) { InitParams(schedulare, shiftsContainer); var schedulareState = GetSchedulareState(schedulare.DeepClone(), shiftsContainer, TreeRoot); OpenSet.Add(schedulareState); ExecuteStopwatch.Start(); while (!OpenSet.IsEmpty) { var currState = OpenSet.FindMin(); OpenSet.DeleteMin(); CloseSet.Add(currState); var currNode = currState.Node; UpdateCurrentBestSolution(currState); if (IsGoal() && IsSchedulareFull(currNode.Value, shiftsContainer)) { UpdateCurrentBestSolution(currState); break; } // DEBUG PrintDebugData(shiftsContainer, currState); // if the current node is full schedulare but it is not goal yet // remove the node from open list and look for another solutions if (IsSchedulareFull(currNode.Value, shiftsContainer)) { OpenSet.DeleteMin(); CloseSet.Add(currState); continue; } // create and add child nodes #region build new nodes foreach (var emp in shiftsContainer.EmployeeConstraints.Select(x => x.Name)) { var newNodeSchedulare = currNode.Value.DeepClone(); var currShiftToAssin = GetIncompleteShift(newNodeSchedulare, shiftsContainer); // modify schdulare currShiftToAssin.Workers.Add(new Worker() { Name = emp }); // add new node to the tree - currNode var childNode = currNode.AddChild(newNodeSchedulare); // get new state var newNodeState = GetSchedulareState(newNodeSchedulare, shiftsContainer, childNode); // add new state to openSet OpenSet.Add(newNodeState); } #endregion } // DEBUG PrintDebugData(shiftsContainer, CurrentBestSolution); var ret = CurrentBestSolution; CurrentBestSolution = null; IsFinished = false; ExecuteStopwatch.Reset(); return(ret); }