示例#1
0
        public static Func <Operation, bool> NeighbourSelector(IGraphLayer graph, Route route, int rank)
        {
            HashSet <int> current = route.Select(op => op.Id).ToHashSet();

            for (int i = 0; i < rank; i++)
            {
                HashSet <int> next = new HashSet <int>();
                foreach (int i1 in current)
                {
                    foreach (int i2 in  graph.OutgoingArcs(i1).Select(a => a.Head))
                    {
                        next.Add(i2);
                    }

                    foreach (int i2 in graph.IncomingArcs(i1).Select(a => a.Tail))
                    {
                        next.Add(i2);
                    }
                }
                current.UnionWith(next);
            }


            return(op => current.Contains(op.Id));
        }
示例#2
0
        public ISequencingLayer Clone()
        {
            IGraphLayer graphClone = GraphLayer.Clone();

            return(new SequencingLayer(
                       _sequences.Select(p => p.Clone(graphClone)).ToArray(),
                       graphClone));
        }
示例#3
0
 /// <summary>
 /// Creates an empty MachineLayer; No disjunctive arcs shall be present.
 /// </summary>
 public SequencingLayer(IGraphLayer graphLayer)
 {
     GraphLayer = graphLayer;
     _sequences = new IJobSequence[Problem.MachineAndConnectionCount];
     for (int i = 0; i < Problem.MachineAndConnectionCount; i++)
     {
         _sequences[i] = new JobSequence(i, GraphLayer);
     }
 }
示例#4
0
        public static void DoCheck(IGraphLayer graphLayer)
        {
            var costLayer = graphLayer.CostLayer;
            var solution  = costLayer.Solution;

            if (!TimesGraphChecks.On)
            {
                return;
            }

            Assert(TimesGraphChecks, graphLayer.IsAcyclic());

            for (int i = 0; i < graphLayer.Count; i++)
            {
                var actualEntryTime = solution.GetEntryTime(i);

                TimeSpan shouldBe;

                if (solution.GetRoute(i, canBeNull: true) == null ||      // if no route set.
                    solution.GetOperation(i, canBeNull: true) == null)    // if the current route is short.

                {
                    shouldBe = TimeSpan.Zero;
                }

                else
                {
                    shouldBe = graphLayer.IncomingArcs(i)
                               .Select(ia => solution.GetEntryTime(ia.Tail) + ia.Length)
                               .Append(solution.GetOperation(i).EarliestEarliestEntry)
                               .Max();
                }

                var deltaTicks = Math.Abs(shouldBe.Ticks - actualEntryTime.Ticks);

                if (deltaTicks > 0)
                {
                    Assert(TimesGraphChecks, false, CreateDebugMessageOnDetectedTimeInconsistency(graphLayer, i));
                }
            }
        }
示例#5
0
        public static void VisualizeRelevant(
            this IGraphLayer graphLayer)
        {
            Console.WriteLine($"Visualizing graph.");
            var solution = graphLayer.CostLayer.Solution;
            var problem  = solution.Problem;

            TimeSpan[] delayAvoidingEntryTimes = new TimeSpan[graphLayer.Count];

            foreach (int v in graphLayer.TopologicalOrder().Reverse())
            {
                var op = solution.GetOperation(v);

                delayAvoidingEntryTimes[v] = graphLayer
                                             .OutgoingArcs(v)
                                             .Select(a => delayAvoidingEntryTimes[a.Head] - a.Length)
                                             .Prepend(op.DelayWeight > 0? op.LatestEntry : TimeSpan.MaxValue)
                                             .Prepend(TimeSpan.MaxValue)
                                             .Min();
            }

            bool[] select = new bool[graphLayer.Count];
            for (int i = 0; i < graphLayer.Count; i++)
            {
                if (solution.GetOperation(i, canBeNull: true) != null &&
                    solution.GetEntryTime(i) > delayAvoidingEntryTimes[i])
                {
                    select[i] = true;
                }
            }

            Console.WriteLine($"Selecting {select.Count(x => x)} of {graphLayer.Count} nodes.");

            graphLayer.Visualize(
                op => select[op.Id],
                null,
                op => $"avoiding={delayAvoidingEntryTimes[op.Id].Show()}");
        }
示例#6
0
        public static void Check(
            Problem problem,
            ISolution solution,
            IGraphLayer graphLayer,
            ISequencingLayer sequencingLayer)
        {
            if (!Switch.On)
            {
                return;
            }

            Asserts.Assert(Switch, graphLayer.Count == problem.OperationCount);

            IGraph newGraph = new Graph(graphLayer.Count);

            foreach (Route route in problem.Select(j => solution.GetRoute(j, canBeNull: true)).Where(r => r != null))
            {
                foreach (var(op0, op1) in route.Pairwise())
                {
                    newGraph.AddArc(op0.Id, op1.Id, -1, op0.Runtime);
                }
            }

            foreach (IJobSequence permutation in sequencingLayer)
            {
                foreach (var(mOcc0, mOcc1) in permutation.Pairwise())
                {
                    newGraph.AddArc(
                        mOcc0.LastOperation + 1,
                        mOcc1.FirstOperation,
                        mOcc0.MachineId,
                        solution.GetMachineReleaseTime(mOcc0, mOcc1));
                }
            }

            Asserts.Assert(Switch, newGraph.Equals(graphLayer),
                           "1 = graphLayer, 2 = implicit graph\n" + graphLayer.DifferencesToString(newGraph));
        }
示例#7
0
        public static string CreateDebugMessageOnDetectedTimeInconsistency(IGraphLayer graphLayer, int vertex)
        {
            var solution = graphLayer.CostLayer.Solution;

            if (solution.GetRoute(vertex, canBeNull: true) == null)
            {
                return("Inconsistent time at a vertex along a critical path:\n" +
                       "\tIf no route is set, the entry time must be 0, but is " +
                       solution.GetEntryTime(vertex).Show() + "\n");
            }

            StringBuilder report = new StringBuilder()
                                   .AppendLine("Inconsistent time at a vertex along a critical path:")
                                   .Append($"\ttime @ {vertex} = ")
                                   .AppendLine(solution.GetEntryTime(vertex).Show())
                                   .Append($"\tearliest entry time @ {vertex} = ")
                                   .AppendLine(solution.GetOperation(vertex).EarliestEarliestEntry.Show())
                                   .Append($"\t(latest entry @ {vertex} = ")
                                   .Append(solution.GetOperation(vertex).LatestEntry.Show())
                                   .AppendLine(")");

            report.AppendLine(graphLayer.IncomingArcs(vertex).Any()
                ? $"\tthere are the following ({graphLayer.IncomingArcs(vertex).Count()}) incoming arcs: "
                : "\tthere are no incoming arcs.");

            foreach (Arc incomingArc in graphLayer.IncomingArcs(vertex))
            {
                report.Append("\t\t").Append(incomingArc).Append(": ")
                .Append($"length = {incomingArc.Length.Show()}, ")
                .Append($"time@{incomingArc.Tail} = {solution.GetEntryTime(incomingArc.Tail).Show()}")
                .Append(", hence: entryTime >= ")
                .AppendLine((solution.GetEntryTime(incomingArc.Tail) + incomingArc.Length).Show());
            }

            return(report.ToString());
        }
示例#8
0
 private SequencingLayer(IJobSequence[] sequences, IGraphLayer graphLayer)
 {
     GraphLayer = graphLayer;
     _sequences = sequences;
 }
示例#9
0
        public static void Visualize(
            this IGraphLayer graphLayer,
            Func <Operation, bool> opSelector          = null,
            Func <Arc, bool> arcSelector               = null,
            Func <Operation, string> additionalOpLabel = null)
        {
            GraphvizWrapper.Graph g = new GraphvizWrapper.Graph();

            opSelector        = opSelector ?? (x => true);
            arcSelector       = arcSelector ?? (x => true);
            additionalOpLabel = additionalOpLabel ?? (x => "");

            HashSet <Arc> allCriticalArcs;

            if (graphLayer.TimesAreUpToDate())
            {
                allCriticalArcs = graphLayer.GetCriticalArcs(onlyDisjunctive: false).ToHashSet();
            }
            else
            {
                allCriticalArcs = new HashSet <Arc>();
            }

            Func <Operation, bool> opAndCriticalSelector =
                x => opSelector(x) || allCriticalArcs.Any(a => a.Head == x.Id || a.Tail == x.Id);

            Dictionary <Operation, Node> nodes = new Dictionary <Operation, Node>();

            var solution = graphLayer.CostLayer.Solution;
            var problem  = solution.Problem;

            var colors = ColorScale.ShuffledPalette(problem.JobCount);

            var connectedComponents = graphLayer.GetNonTrivialScc().SelectMany(x => x).ToHashSet();

            foreach (var job in problem.Jobs)
            {
                Route route = solution.GetRoute(job);

                foreach (var op in route.Operations.Where(opAndCriticalSelector))
                {
                    StringBuilder label = new StringBuilder();

                    label.AppendLine($"id={op.Id}")
                    .AppendLine($"time={solution.GetEntryTime(op.Id).Show()}")
                    .AppendLine($"earliest={solution.GetOperation(op.Id).EarliestEarliestEntry.Show()}")
                    .AppendLine($"latest={solution.GetOperation(op.Id).LatestEntry.Show()}");

                    if (op.DelayWeight > 0)
                    {
                        label.AppendLine($"weight={op.DelayWeight}");
                        if (graphLayer.CostLayer.GetCostAtOperation(op.Id) > 0)
                        {
                            label.AppendLine($"cost={Math.Round(graphLayer.CostLayer.GetCostAtOperation(op.Id))}");
                        }
                    }

                    var additional = additionalOpLabel(op);

                    if (!string.IsNullOrWhiteSpace(additional))
                    {
                        label.AppendLine(additional);
                    }


                    if (graphLayer.OutgoingArcs(op.Id).Where(arcSelector).Any() ||
                        graphLayer.IncomingArcs(op.Id).Where(arcSelector).Any())
                    {
                        var n = new Node()
                        {
                            Label     = label.ToString(),
                            Shape     = NodeShape.Box,
                            FillColor = colors[job.Id],
                            Style     = NodeStyle.Filled,
                            FontColor = connectedComponents.Contains(op.Id)? Color.Red : Color.Black
                        };
                        nodes.Add(op, n);
                    }
                }
            }

            g.AddNodes(nodes.Values);
            Console.WriteLine($"Nodes added.");

            foreach (var arc in Enumerable.Range(0, graphLayer.Count)
                     .SelectMany(graphLayer.OutgoingArcs)
                     .Where(arcSelector))
            {
                if (nodes.TryGetValue(solution.GetOperation(arc.Tail), out var n0) &&
                    nodes.TryGetValue(solution.GetOperation(arc.Head), out var n1))
                {
                    var label = (arc.MachineId != -1 ? $"M={arc.MachineId} " : "") + $"t={arc.Length.Show()}";

                    var edge = new Edge(n0, n1)
                    {
                        Label = label,
                        Style = arc.MachineId == -1 ? EdgeStyle.Solid : EdgeStyle.Dashed,
                        Color = allCriticalArcs.Contains(arc) ? Color.Red : Color.Black,
                    };

                    if (solution.GetEntryTime(arc.Tail) + arc.Length == solution.GetEntryTime(arc.Head))
                    {
                        edge.Style = EdgeStyle.Bold;
                    }

                    g.AddEdges(edge);
                }
            }
            Console.WriteLine($"Edges added.");

            g.Display();
            Console.WriteLine("Done.");
        }