private long ShortcutPath(Path path, long delayDec, out Path xpath) { var segset = new SortedSet <SegLink>(); var seglist = new LinkedList <Pipe>(); long time = 0; for (int i = 0; i < path.Segments.Length; i++) { Pipe seg = path.Segments[i]; time += seg.GetDelay(_a); var pos = seglist.AddLast(seg); segset.Add(new SegLink() { pos = pos, time = time }); } SegLink max = new SegLink() { pos = null, time = time + 1 }; SegLink minJoin = new SegLink() { pos = null, time = delayDec + 1 }; var joinset = segset.GetViewBetween(minJoin, max); Debug.Assert(joinset.Any()); Hop bestSpliceHop = null; Hop bestJoinHop = null; long bestCost = long.MaxValue; long bestJoinTime = -1; foreach (var seglink in joinset) { long joinTime = seglink.time; Pipe seg = seglink.pos.Value; Hop joinHop = seg.GetSink(_a); long joinCost = _a.Preds[joinHop.Node].Count(); if (joinCost < bestCost) { bestCost = joinCost; bestJoinHop = joinHop; bestJoinTime = joinTime; bestSpliceHop = FindSpliceHop(segset, max, joinTime, delayDec); } long segDelay = seg.GetDelay(_a); --joinTime; if (segDelay > 1 && joinTime > delayDec && bestCost > 1) { bestCost = 1; var insHop = new InsertionHop(_a, seg, segDelay - 1, 1); bestJoinHop = insHop; bestJoinTime = joinTime; var left = seglist.AddBefore(seglink.pos, insHop.LeftPipe); var right = seglist.AddAfter(seglink.pos, insHop.RightPipe); seglist.Remove(seglink.pos); segset.Remove(seglink); var leftLink = new SegLink() { pos = left, time = seglink.time - 1 }; segset.Add(leftLink); var rightLink = new SegLink() { pos = right, time = seglink.time }; segset.Add(rightLink); bestSpliceHop = FindSpliceHop(segset, max, joinTime, delayDec); break; } } long bestSpliceTime = bestJoinTime - delayDec - 1; var newSegments = new List <Pipe>(); var wormhole = new InsertionPipe(bestSpliceHop, bestJoinHop, 1); time = 0; var curpos = seglist.First; while (curpos != null) { Pipe seg = curpos.Value; long nextTime = time + seg.GetDelay(_a); if (nextTime <= bestSpliceTime || time >= bestJoinTime) { newSegments.Add(seg); } else if (time == bestSpliceTime) { newSegments.Add(wormhole); } else if (time < bestSpliceTime && nextTime > bestSpliceTime) { var joinHop = (InsertionHop)bestSpliceHop; newSegments.Add(joinHop.LeftPipe); newSegments.Add(wormhole); } time = nextTime; curpos = curpos.Next; } xpath = new Path(_a, newSegments.ToArray()); return(bestCost + 1); }
private bool FindCheapestPathConnection(Path srcPath, Path dstPath, long depTime, long arrTime, out Path xpath, out long cost) { long reqDelay = arrTime - depTime; if (reqDelay < 2) { xpath = null; cost = long.MaxValue; return(false); } long bestCost = long.MaxValue; xpath = null; long srcDelay = srcPath.TotalDelay; for (int i = srcPath.Segments.Length - 1; i >= 0; i--) { Pipe srcSeg = srcPath.Segments[i]; if (reqDelay > srcDelay) { long dstDelay = dstPath.TotalDelay; long pathDelay = srcDelay + dstDelay; for (int j = 0; j < dstPath.Segments.Length; j++) { Pipe dstSeg = dstPath.Segments[j]; if (reqDelay > pathDelay) { var node = dstSeg.GetSource(_a).Node; if (!_a.IsEndpoint[node]) { long joinCost = ComputeJoinCost(_a.Preds[dstSeg.GetSource(_a).Node]); if (joinCost < bestCost) { var link = new InsertionPipe(srcSeg.GetSink(_a), dstSeg.GetSource(_a), reqDelay - pathDelay); xpath = new Path(_a, new Pipe[] { link }); bestCost = joinCost; } } long segDelay = dstSeg.GetDelay(_a); if (segDelay >= 2 && bestCost > GetSplitJoinCost()) { var join = new InsertionHop(_a, dstSeg, 1, segDelay - 1); var link = new InsertionPipe(srcSeg.GetSink(_a), join, reqDelay - pathDelay + 1); xpath = new Path(_a, new Pipe[] { link }); bestCost = GetSplitJoinCost(); } if (bestCost == 0) { break; } } pathDelay -= dstSeg.GetDelay(_a); } if (bestCost == 0) { break; } } srcDelay -= srcSeg.GetDelay(_a); } // To be implemented cost = bestCost + 1; return(bestCost != long.MaxValue); }
private long ExtendPath(Path path, long delayInc, out Path xpath) { Debug.Assert(delayInc >= 1); if (path.TotalDelay <= 1) { Debug.Assert(path.Segments.Length == 1); Tp pipe = path.Segments[0].Inst; Pipe ipipe = new InsertionPipe((RealHop)_a.Source[pipe], (RealHop)_a.Sink[pipe], delayInc); xpath = new Path(_a, new Pipe[] { ipipe }); long fanin = _a.Preds[_a.Sink[pipe]].Count(); return(fanin + 1); } Hop bestSpliceHop = null; Hop bestJoinHop = null; long bestCost = long.MaxValue; int spliceIdx = -1; int joinIdx = -1; var segments = new List <Pipe>(); for (int i = 0; i < path.Segments.Length; i++) { Pipe seg = path.Segments[i]; Tp pipe = seg.Inst; long delay = seg.GetDelay(_a); Debug.Assert(delay > 0); if (bestCost > 1) { if (delay == 1) { long cost = ComputeJoinCost(_a.Preds[_a.Sink[pipe]]); if (cost < bestCost) { bestSpliceHop = (RealHop)_a.Source[pipe]; bestJoinHop = (RealHop)_a.Sink[pipe]; bestCost = cost; spliceIdx = i; joinIdx = i + 1; } segments.Add(seg); } if (bestCost > GetSplitJoinCost()) { bestSpliceHop = (RealHop)_a.Source[pipe]; var ihop = new InsertionHop(_a, seg, 1, delay - 1); bestJoinHop = ihop; bestCost = 1; spliceIdx = i; joinIdx = i + 1; segments.Add(ihop.LeftPipe); segments.Add(ihop.RightPipe); } } else { segments.Add(seg); } } Pipe nose = new InsertionPipe(bestSpliceHop, bestJoinHop, delayInc + 1); var newSegments = new List <Pipe>(); newSegments.AddRange(segments.Take(spliceIdx)); newSegments.Add(nose); newSegments.AddRange(segments.Skip(joinIdx)); xpath = new Path(_a, newSegments.ToArray()); return(bestCost + 1); }