public CriticalPath GetMaxProjectBuffer(List <List <ActivityWithDirection> > criticalPaths) { if (!criticalPaths.Any()) { return(null); } var criticalPath = new CriticalPath(); var maxProjBuf = 0.0; criticalPaths.ForEach(cp => { var projBuf = Math.Sqrt(cp.Where(a => a.LinkDistance == null) .Sum(a => Math.Pow(a.Activity.Duration - a.Activity.AggressiveDuration, 2))); if (projBuf > maxProjBuf) { maxProjBuf = projBuf; criticalPath = new CriticalPath { ActivityDirections = cp.CloneLists() }; } }); var maxDuration = criticalPaths.First().Where(a => a.LinkDistance == null).Max(a => a.Activity.ToDuration); var maxUnit = criticalPaths.First().Where(a => a.LinkDistance == null && a.Activity.ToDuration == maxDuration).First().Activity.ToUnit; criticalPath.ProjectBuffer = new ProjectBuffer { StartingDuration = maxDuration, StartingUnit = maxUnit, Buffer = maxProjBuf }; return(criticalPath); }
public override string ToString() { int?[,] matrix = ConvertToAdjMatrix(); int Count = AllNodes.Count(); StringBuilder builder = new StringBuilder(); builder.AppendFormat("CP: [{0}]", string.Join(", ", CriticalPath.ToArray())); builder.AppendLine(); builder.Append(' ', 8); for (int i = 0; i < Count; i++) { builder.AppendFormat("{0}", i); builder.Append(' ', (i >= 10) ? 1 : 2); } builder.AppendLine(); for (int i = 0; i < Count; i++) { builder.AppendFormat("{0}", i); builder.Append(' ', (i >= 10) ? 1 : 2); builder.Append("| [ "); for (int j = 0; j < Count; j++) { if (i == j) { builder.Append(" &,"); } else if (matrix[i, j] == null) { builder.Append(" .,"); } else { builder.AppendFormat(" {0},", matrix[i, j]); } } builder.Append(" ]\r\n"); } builder.Append("\r\n"); // Adjacency list representation List <List <int> > list = ConvertToAdjList(false); for (int i = 0; i < Count; i++) { builder.AppendFormat("[{0}]: ", i); for (int j = 0; j < list[i].Count; j++) { builder.AppendFormat("{0}{1}", list[i][j], j == (list[i].Count - 1) ? "" : " "); } builder.AppendLine(); } return(builder.ToString()); }
/// <summary> /// Checks if a Critical Path is established and if all nodes are connected /// </summary> private bool ValidateNodeConnected() { Debug.WriteLine("[id] => cameFrom"); CriticalPath.ForEach(node => Debug.WriteLine($"[{CriticalPath.IndexOf(node)}] => {node}")); bool isConnected = true; foreach (Node node in AllNodes) { if (node.Edges.Count == 0) { isConnected = false; break; } } return(CriticalPath.Count > 0 && isConnected); }
public void Base() { var sut = new CriticalPath(); var vertex1 = new WeightedGraphVertex { Edges = new System.Collections.Generic.List <WeightedGraphNodeEdge> { new WeightedGraphNodeEdge { To = 1, Weight = 5 }, new WeightedGraphNodeEdge { To = 3, Weight = 9 }, new WeightedGraphNodeEdge { To = 4, Weight = 14 } } }; var vertex2 = new WeightedGraphVertex { Edges = new System.Collections.Generic.List <WeightedGraphNodeEdge> { new WeightedGraphNodeEdge { To = 2, Weight = 7 } } }; var vertex3 = new WeightedGraphVertex { Edges = new System.Collections.Generic.List <WeightedGraphNodeEdge> { new WeightedGraphNodeEdge { To = 4, Weight = 4 } } }; var vertex4 = new WeightedGraphVertex { Edges = new System.Collections.Generic.List <WeightedGraphNodeEdge> { new WeightedGraphNodeEdge { To = 4, Weight = 11 } } }; var vertex5 = new WeightedGraphVertex { Edges = new System.Collections.Generic.List <WeightedGraphNodeEdge>() }; var graph = new [] { vertex1, vertex2, vertex3, vertex4, vertex5 }; Assert.Equal(20, sut.GetCriticalPath(graph)); }
public void BiggerGraph() { var sut = new CriticalPath(); var vertex1 = new WeightedGraphVertex { Edges = new System.Collections.Generic.List <WeightedGraphNodeEdge> { new WeightedGraphNodeEdge { To = 1, Weight = 17 } } }; var vertex2 = new WeightedGraphVertex { Edges = new System.Collections.Generic.List <WeightedGraphNodeEdge> { new WeightedGraphNodeEdge { To = 2, Weight = 13 } } }; var vertex3 = new WeightedGraphVertex { Edges = new System.Collections.Generic.List <WeightedGraphNodeEdge> { new WeightedGraphNodeEdge { To = 3, Weight = 9 } } }; var vertex4 = new WeightedGraphVertex { Edges = new System.Collections.Generic.List <WeightedGraphNodeEdge> { new WeightedGraphNodeEdge { To = 4, Weight = 11 }, new WeightedGraphNodeEdge { To = 8, Weight = 10 } } }; var vertex5 = new WeightedGraphVertex { Edges = new System.Collections.Generic.List <WeightedGraphNodeEdge> { } }; var vertex6 = new WeightedGraphVertex { Edges = new System.Collections.Generic.List <WeightedGraphNodeEdge> { new WeightedGraphNodeEdge { To = 6, Weight = 11 }, new WeightedGraphNodeEdge { To = 9, Weight = 15 } } }; var vertex7 = new WeightedGraphVertex { Edges = new System.Collections.Generic.List <WeightedGraphNodeEdge> { new WeightedGraphNodeEdge { To = 7, Weight = 18 } } }; var vertex8 = new WeightedGraphVertex { Edges = new System.Collections.Generic.List <WeightedGraphNodeEdge> { new WeightedGraphNodeEdge { To = 3, Weight = 16 }, new WeightedGraphNodeEdge { To = 8, Weight = 13 }, new WeightedGraphNodeEdge { To = 11, Weight = 19 } } }; var vertex9 = new WeightedGraphVertex { Edges = new System.Collections.Generic.List <WeightedGraphNodeEdge> { } }; var vertex10 = new WeightedGraphVertex { Edges = new System.Collections.Generic.List <WeightedGraphNodeEdge> { new WeightedGraphNodeEdge { To = 10, Weight = 14 }, } }; var vertex11 = new WeightedGraphVertex { Edges = new System.Collections.Generic.List <WeightedGraphNodeEdge> { new WeightedGraphNodeEdge { To = 11, Weight = 17 }, } }; var vertex12 = new WeightedGraphVertex { Edges = new System.Collections.Generic.List <WeightedGraphNodeEdge> { } }; var graph = new [] { vertex1, vertex2, vertex3, vertex4, vertex5, vertex6, vertex7, vertex8, vertex9, vertex10, vertex11, vertex12 }; Assert.Equal(56, sut.GetCriticalPath(graph)); }
private List <FeedingBuffer> CalculateFeedingBuffers(IEnumerable <Activity> activities, CriticalPath maxCriticalPath, Activity startingActivity, Activity endingActivity) { var feedingBuffers = new List <FeedingBuffer>(); if (maxCriticalPath == null) { return(feedingBuffers); } var processFeedingBuffer = new List <KeyValuePair <int, float> >(); var orderedProcesses = new List <OrderedProcess>(); var orderedIndex = 0; var startDurProcWithStartAct = activities.Where(a => a.ProcessId == startingActivity.ProcessId).Select(x => x.FromDuration).Min(); var startDurProcWithEndAct = activities.Where(a => a.ProcessId == endingActivity.ProcessId).Select(x => x.FromDuration).Min(); activities.GroupBy(a => a.ProcessId) .Where(g => g.Select(x => x.FromDuration).Min() >= startDurProcWithStartAct && g.Select(x => x.FromDuration).Min() <= startDurProcWithEndAct) .OrderBy(g => g.Min(a => a.FromDuration)).ToList() .ForEach(g => orderedProcesses.Add(new OrderedProcess { order = orderedIndex++, elements = g })); foreach (var proc in orderedProcesses) { float sumPreviousFbs = 0; var criticalActivitiesInProc = proc.elements.Intersect(maxCriticalPath.ActivityDirections.Select(ad => ad.Activity)); var nonCriticalActivities = criticalActivitiesInProc.Any() ? proc.elements .Where(act => act.FromDuration < criticalActivitiesInProc.Select(c => c.FromDuration).Min()) : proc.elements; if (!criticalActivitiesInProc.Any()) { continue; } var feedingBuffer = (float)Math.Sqrt(nonCriticalActivities .Sum(a => Math.Pow(a.Duration - a.AggressiveDuration, 2))); processFeedingBuffer.Add(new KeyValuePair <int, float>(proc.order, feedingBuffer)); if (processFeedingBuffer.Any(pfb => pfb.Key == proc.order - 1)) { sumPreviousFbs = processFeedingBuffer.Where(pfb => pfb.Key < proc.order).Sum(r => r.Value); SetPreviousFeedingBufferShiftingToElements(proc.elements.ToList(), sumPreviousFbs); SetPreviousFeedingBufferShiftingToElements(maxCriticalPath.ActivityDirections.Select(ad => ad.Activity) .Intersect(proc.elements).ToList(), sumPreviousFbs); } var link = GetLinkInCriticalPathForCurrentProcess(maxCriticalPath, proc); if (link != null) { link.FeedingBuffer = new FeedingBuffer { StartingDuration = link.LinkDistance.StartingDuration, PreviousFeedingBuffers = sumPreviousFbs, Buffer = feedingBuffer, StartingUnit = criticalActivitiesInProc.Max(a => link.Direction == ActivityDirection.Normal ? a.StartingUnit + a.Units : a.StartingUnit) }; link.LinkDistance.PreviousFeedingBuffers = sumPreviousFbs; link.LinkDistance.FeedingBuffer = feedingBuffer; } var maxDuration = proc.elements.Max(a => a.ToDuration); var lastProc = proc.elements.First(a => a.ToDuration == maxDuration); feedingBuffers.Add(new FeedingBuffer { StartingDuration = lastProc.ToDuration, PreviousFeedingBuffers = sumPreviousFbs, Buffer = feedingBuffer, StartingUnit = lastProc.ToUnit }); } maxCriticalPath.ProjectBuffer = new ProjectBuffer { StartingDuration = maxCriticalPath.ProjectBuffer.StartingDuration + processFeedingBuffer.Sum(r => r.Value), StartingUnit = maxCriticalPath.ProjectBuffer.StartingUnit, Buffer = maxCriticalPath.ProjectBuffer.Buffer }; return(feedingBuffers); }
private static ActivityWithDirection GetLinkInCriticalPathForCurrentProcess(CriticalPath maxCriticalPath, OrderedProcess proc) { return(maxCriticalPath.ActivityDirections.Where(ad => ad.LinkDistance != null).Skip(proc.order) .FirstOrDefault()); }