public static IEnumerable <Interval> FindIntervals(IntervalNode[] blocks, IntervalNode header) { var heads = new HashSet <IntervalNode>(); var intervalVisited = new HashSet <IntervalNode>(); heads.Add(header); while (true) { var n = heads.Except(intervalVisited).FirstOrDefault(); if (n == null) { break; } intervalVisited.Add(n); var iofn = new HashSet <IntervalNode>(); iofn.Add(n); while (true) { var candidate = iofn.SelectMany(i => i.Successors.Intersect(blocks)).Distinct() .Except(iofn).FirstOrDefault(p => iofn.IsSupersetOf(p.Predecessors.Intersect(blocks))); if (candidate == null) { break; } iofn.Add(candidate); } heads.UnionWith(blocks.Where(m => !heads.Contains(m) && !iofn.Contains(m) && m.Predecessors.Intersect(blocks).Any(p => iofn.Contains(p)))); yield return(new Interval(n, iofn.ToArray())); } }
public static IntervalNode[][] GetIntervalSequence(IntervalNode[] blocks, IntervalNode root) { var i1 = FindIntervals(blocks, root).ToArray(); var intervalNodes = i1.Select(interval => new IntervalNode(interval)).ToArray(); foreach (var intervalNode in intervalNodes) { intervalNode.Predecessors.AddRange(intervalNode.Interval.Blocks .SelectMany(b => b.Predecessors) .Except(intervalNode.Interval.Blocks) .Select(b => intervalNodes.First(i => i.Interval.Blocks.Contains(b))) .Distinct()); intervalNode.Successors.AddRange(intervalNode.Interval.Blocks .SelectMany(b => b.Successors) .Except(intervalNode.Interval.Blocks) .Select(b => intervalNodes.First(i => i.Interval.Blocks.Contains(b))) .Distinct()); } if (intervalNodes.Length != 1) { return(GetIntervalSequence(intervalNodes, intervalNodes[0]).Prepend(intervalNodes).ToArray()); } return(new[] { intervalNodes }); }
public Interval(IntervalNode header, IntervalNode[] blocks) { Header = header; Blocks = blocks; }