Exemplo n.º 1
0
        private void VisitNodesBack(IChainNode <TN> leaf, Action <IChainNode <TN> > processNode)
        {
            short infinityLoopDetector = short.MinValue;
            var   checkNodes           = new[] { leaf.Id };

            while (checkNodes.Length != 0)
            {
                if (++infinityLoopDetector == short.MaxValue - 1)
                {
                    throw new InfinityLoopException();
                }

                var newChildIds = new List <string>();
                foreach (var node in checkNodes)
                {
                    var linkedTo = Edges.Where(x => x.ToId == node && Nodes.Single(s => s.Id == x.ToId).IsLoop == false)
                                   .Select(x => x.FromId).ToList();
                    linkedTo = linkedTo.Select(x => Nodes.Single(n => n.Id == x))
                               .Select(x => x.Id).ToList();
                    newChildIds.AddRange(linkedTo);
                    foreach (var id in linkedTo)
                    {
                        processNode(this[id]);
                    }
                }

                checkNodes = newChildIds.Distinct().ToArray();
            }
        }
 public void ConnectNodes(IChainNode node, List <IChainNode> nextNodes)
 {
     foreach (var chainNode in nextNodes)
     {
         if (node is ISingleNextNode single)
         {
             single.SetSingleNextNode(chainNode);
         }
         else if (node is IMultiNextNode multi)
         {
             multi.AddNextNodes(chainNode);
         }
     }
 }
        public void AddNextNodes(IChainNode node)
        {
            if (_listOfNextNode.ContainsKey(node.Destination))
            {
                return;
            }
            _listOfNextNode.Add(node.Destination, node);
            _transporterQueues.Add(node.Destination, new Queue <IBaggage>());

            Task.Run(() =>
            {
                DistributeBaggage(node.Destination);
            });
        }
Exemplo n.º 4
0
        public void AddDetails(IChainNode node)
        {
            switch (node.Type)
            {
            case ChainType.Conflict when node is Conflict conflict:
                Details.AddRange(conflict.Details);
                break;

            case ChainType.Detail when node is LaboriousDetail detail:
                Details.Add(detail.Number, detail);
                break;

            default: throw new InvalidOperationException();
            }
        }
Exemplo n.º 5
0
        public IList <IChainNode <TN> > SearchHeads(IChainNode <TN> leaf)
        {
            var result   = new List <IChainNode <TN> >();
            var allHeads = GetHeads();

            VisitNodesBack(leaf, node =>
            {
                //add only final nodes
                if (allHeads.Any(x => x.Id == node.Id))
                {
                    result.Add(node);
                }
            });
            return(result);
        }
Exemplo n.º 6
0
        public IList <IChainNode <TN> > SearchLeafs(IChainNode <TN> head)
        {
            var result   = new List <IChainNode <TN> >();
            var allLeafs = GetLeafs();

            VisitNodes(head, node =>
            {
                //add only final nodes
                if (allLeafs.Any(x => x.Id == node.Id))
                {
                    result.Add(node);
                }
            });
            return(result);
        }
Exemplo n.º 7
0
        public void AddNode(IChainNode <TN> node)
        {
            if (CheckArguments)
            {
                if (node == null)
                {
                    throw new ArgumentNullException(nameof(node));
                }

                if (Nodes.Any(x => x.Id == node.Id))
                {
                    throw new DuplicateNodeException(node.Id);
                }
            }

            Nodes.Add(node);
        }
Exemplo n.º 8
0
        public IChainRepository <T> Finish(IChainNode <T> chainNode)
        {
            this._lastnode = chainNode;

            return(this);
        }
Exemplo n.º 9
0
        public IChainRepository <T> Next(IChainNode <T> chainNode)
        {
            this._internQueue.Enqueue(chainNode);

            return(this);
        }
Exemplo n.º 10
0
        public void AddDirectedEdge(IChainNode <TN> from, IChainNode <TN> to, TE data)
        {
            if (CheckArguments)
            {
                if (from == null)
                {
                    throw new ArgumentNullException(nameof(from));
                }

                if (to == null)
                {
                    throw new ArgumentNullException(nameof(to));
                }

                if (Nodes.All(x => x.Id != from.Id))
                {
                    throw new UnknownNodeException(from.Id);
                }

                if (Nodes.All(x => x.Id != to.Id))
                {
                    throw new UnknownNodeException(to.Id);
                }
            }

            if (from.Id == to.Id)
            {
                //skip infinity loop
                return;
            }

            var forwardNodeIds  = new List <string>();
            var backwardNodeIds = new List <string>();
            var isLoop          = false;

            forwardNodeIds.Add(to.Id);
            VisitNodes(to, node =>
            {
                forwardNodeIds.Add(node.Id);
                if (node.Id == from.Id)
                {
                    isLoop = true;
                }
            });

            if (isLoop)
            {
                //search for nodes in loop
                backwardNodeIds.Add(from.Id);
                VisitNodesBack(from, node => { backwardNodeIds.Add(node.Id); });

                var loopIds = forwardNodeIds.Union(backwardNodeIds)
                              .Where(x => forwardNodeIds.Contains(x) && backwardNodeIds.Contains(x))
                              .Distinct().ToList();


                //try to find entry - it should be node nearest to head

                var heads      = GetHeads();
                var deep       = new Dictionary <string, int>();
                var multiInIds = new List <string>();

                foreach (var head in heads)
                {
                    var lvl = 0;
                    VisitNodes(head, node =>
                    {
                        lvl++;
                        if (loopIds.Contains(node.Id))
                        {
                            if (deep.ContainsKey(node.Id))
                            {
                                deep[node.Id] = Math.Min(deep[node.Id], lvl);
                                multiInIds.Add(node.Id);
                            }
                            else
                            {
                                deep.Add(node.Id, lvl);
                            }
                        }
                    });
                }

                if (multiInIds.Count == 1 && multiInIds[0] == from.Id)
                {
                    multiInIds.Add(to.Id);
                    if (deep.ContainsKey(to.Id))
                    {
                        deep[to.Id] = -1;
                    }
                    else
                    {
                        deep.Add(to.Id, -1);
                    }
                }

                if (!multiInIds.Any())
                {
                    multiInIds.Add(to.Id);
                    if (deep.ContainsKey(to.Id))
                    {
                        deep[to.Id] = -1;
                    }
                    else
                    {
                        deep.Add(to.Id, -1);
                    }
                }

                var minLvl    = deep.Where(x => multiInIds.Contains(x.Key)).Select(x => x.Value).Min();
                var loopEntry = this[deep.Where(x => multiInIds.Contains(x.Key)).First(x => x.Value == minLvl).Key];

                var nodeToEntry = Edges.Any(x => loopIds.Contains(x.FromId) && x.ToId == loopEntry.Id)
                    ? Edges.Single(x => loopIds.Contains(x.FromId) && x.ToId == loopEntry.Id).FromId
                    : from.Id;

                this[nodeToEntry].IsLoop = true;
            }

            if (CheckArguments)
            {
                if (Edges.Any(x => x.FromId == from.Id && x.ToId == to.Id))
                {
                    throw new DuplicateEdgeException(from.Id, to.Id);
                }
            }
            else
            {
                //check and skip
                if (Edges.Any(x => x.FromId == from.Id && x.ToId == to.Id))
                {
                    return;
                }
            }
            Edges.Add(new EdgeType <TE>(from.Id, to.Id, data));
        }
Exemplo n.º 11
0
 public Node(IChainNode <T> node)
 {
     _node = node;
 }
Exemplo n.º 12
0
 public void SetSingleNextNode(IChainNode node)
 {
     NextNode = node;
 }
Exemplo n.º 13
0
 public IChainNode SetNext(IChainNode nextNode)
 {
     this.m_NextNode = nextNode;
     return(this);
 }
Exemplo n.º 14
0
 public void AddNextNodes(IChainNode node)
 {
     nextNodes.Add(node);
 }