public INodes GetLeafNodes() { INodes leafs = new Nodes(); foreach (var node in _nodes) { INodes successors = GetSuccessorNodes(node.GetNode()); if (successors == null || successors.Any() == false) { leafs.Add(node.GetNode()); } } if (leafs.Any() == false) { return(null); } return(leafs); }
/** * Top-down */ public void ScheduleBackward() { // S = {0} (alle einplanbaren Operations/Demands/Providers) if (_clearOldTimes) { // d_0 = 0 foreach (var uniqueNode in _orderOperationGraph.GetAllUniqueNodes()) { IScheduleNode uniqueScheduleNode = uniqueNode.GetEntity(); if (uniqueScheduleNode.IsReadOnly() == false && uniqueScheduleNode.GetType() != typeof(CustomerOrderPart)) { uniqueScheduleNode.ClearStartTimeBackward(); uniqueScheduleNode.ClearEndTimeBackward(); } } } // while S nor empty do while (_S.Any()) { INode i = _S.Pop(); IScheduleNode iAsScheduleNode = i.GetEntity(); INodes successorNodes = _orderOperationGraph.GetSuccessorNodes(i); if (successorNodes != null && successorNodes.Any()) { foreach (var successor in successorNodes) { _S.Push(successor); IScheduleNode successorScheduleNode = successor.GetEntity(); if (successorScheduleNode.IsReadOnly()) { continue; } // Konservativ vorwärtsterminieren ist korrekt, // aber rückwärts muss wenn immer möglich terminiert werden // (prüfe parents und ermittle minStart und setze das) INodes predecessorNodes = _orderOperationGraph.GetPredecessorNodes(successor); DueTime minStartTime = iAsScheduleNode.GetStartTimeBackward(); if (minStartTime == null) { throw new MrpRunException( "How can the StartTime of an already scheduled node be null ?"); } foreach (var predecessorNode in predecessorNodes) { DueTime predecessorsStartTime = predecessorNode.GetEntity().GetStartTimeBackward(); if (predecessorsStartTime != null && predecessorsStartTime.IsSmallerThan(minStartTime)) { minStartTime = predecessorsStartTime; } } if (successorScheduleNode.GetType() == typeof(CustomerOrderPart)) { throw new MrpRunException( "Only a root node can be a CustomerOrderPart."); } if (successorScheduleNode.IsReadOnly() == false) { successorScheduleNode.SetEndTimeBackward(minStartTime); } } } } }
public void ScheduleForward() { Stack <INode> S = new Stack <INode>(); // d_0 = 0 foreach (var node in _orderOperationGraph.GetLeafNodes()) { IScheduleNode scheduleNode = node.GetEntity(); if (scheduleNode.IsReadOnly() == false && scheduleNode.GetStartTimeBackward().IsSmallerThan(_simulationInterval.GetStart())) { // implicitly the due/endTime will also be set accordingly scheduleNode.SetStartTimeBackward(_simulationInterval.GetStart()); S.Push(node); } else // no forward scheduling is needed { } } // while S nor empty do while (S.Any()) { INode i = S.Pop(); IScheduleNode iAsScheduleNode = (IScheduleNode)i.GetEntity(); INodes predecessors = _orderOperationGraph.GetPredecessorNodes(i); if (predecessors != null && predecessors.Any()) { foreach (var predecessor in predecessors) { IScheduleNode predecessorScheduleNode = predecessor.GetEntity(); // if predecessor starts before endTime of current d/p --> change that if (predecessorScheduleNode.IsReadOnly() == false && predecessorScheduleNode .GetStartTimeBackward().IsSmallerThan(iAsScheduleNode.GetEndTimeBackward())) { // COPs are not allowed to change if (predecessorScheduleNode.GetType() != typeof(CustomerOrderPart)) { // don't take getDueTime() since in case of a demand, // this will be the startTime, which is to early // This must be the maximum endTime of all childs !!! DueTime maxEndTime = iAsScheduleNode.GetEndTimeBackward(); foreach (var successor in _orderOperationGraph.GetSuccessorNodes( predecessor)) { DueTime successorsEndTime = successor.GetEntity().GetEndTimeBackward(); if (successorsEndTime.IsGreaterThan(maxEndTime)) { maxEndTime = successorsEndTime; } } predecessorScheduleNode.SetStartTimeBackward(maxEndTime); } } S.Push(predecessor); } } } }