Пример #1
0
        /** basic principle:
         *
         * put A on the list -> {A}
         *  put B on the list -> {A,B}
         *  put C on the list -> {A,B,C}
         *  since C is a leaf, print the list (A,B,C)
         *  remove C from the list -> {A,B}
         *  put D on the list -> {A,B,D}
         *  since D is a leaf, print the list (A,B,D)
         */
        public static List <IEdge> CreateGraphFor(INode root, Type type, IDirectedGraph <INode> directedGraph)
        {
            Stack <INode> stack = new Stack <INode>();
            Stack <INode> pathProductionOrders = new Stack <INode>();

            INode        lastProductionOrder = null;
            List <IEdge> edges = new List <IEdge>();

            stack.Push(root);
            while (stack.Any())
            {
                // Do something
                INode popped = stack.Pop();

                if (popped.GetEntity().GetType() == type)
                {
                    pathProductionOrders.Push(popped);
                    if (lastProductionOrder == null)
                    {
                        lastProductionOrder = popped;
                    }
                    else
                    {
                        edges.Add(new Edge(lastProductionOrder, popped));
                        lastProductionOrder = popped;
                    }
                }

                // Push other objects on the stack.
                INodes successorNodes = directedGraph.GetSuccessorNodes(popped);
                if (successorNodes != null)
                {
                    foreach (var successorNode in successorNodes)
                    {
                        stack.Push(successorNode);
                    }
                }
                // popped is a leaf, remove it from path if it was a PrO
                else
                {
                    if (lastProductionOrder != null && lastProductionOrder.Equals(popped))
                    {
                        pathProductionOrders.Pop();
                        if (pathProductionOrders.Any())
                        {
                            lastProductionOrder = pathProductionOrders.Pop();
                            pathProductionOrders.Push(lastProductionOrder);
                        }
                    }
                }
            }

            return(edges);
        }
Пример #2
0
        public void TestGetSuccessorNodes()
        {
            INode[] nodes = EntityFactory.CreateDummyNodes(7);
            IDirectedGraph <INode> directedGraph = CreateBinaryDirectedGraph(nodes);
            INodes leafs = directedGraph.GetLeafNodes();

            foreach (var node in nodes)
            {
                INodes successors = directedGraph.GetSuccessorNodes(node);
                bool   isLeaf     = leafs.Contains(node);
                if (isLeaf)
                {
                    Assert.True(successors == null, "A leaf cannot have successors.");
                }
                else
                {
                    Assert.True(successors != null, "A non-leaf MUST have successors.");
                }
            }
        }
Пример #3
0
        /**
         * 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);
                        }
                    }
                }
            }
        }