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); }); }
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(); } }
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); }
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); }
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); }
public IChainRepository <T> Finish(IChainNode <T> chainNode) { this._lastnode = chainNode; return(this); }
public IChainRepository <T> Next(IChainNode <T> chainNode) { this._internQueue.Enqueue(chainNode); return(this); }
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)); }
public Node(IChainNode <T> node) { _node = node; }
public void SetSingleNextNode(IChainNode node) { NextNode = node; }
public IChainNode SetNext(IChainNode nextNode) { this.m_NextNode = nextNode; return(this); }
public void AddNextNodes(IChainNode node) { nextNodes.Add(node); }