Exemplo n.º 1
0
        public override int Transform([NotNull] GlobalContext globalContext, Ignore Ignore,
                                      [NotNull] TransformOptions transformOptions, [NotNull][ItemNotNull] IEnumerable <Dependency> dependencies,
                                      [NotNull] List <Dependency> transformedDependencies)
        {
            // Only items are changed (Order is added)
            transformedDependencies.AddRange(dependencies);

            // Algorithm:
            // LOOP
            //    Find the item with the least outgoing edges (measured relative to outgoing and ingoing ones)
            //    Put it into result list; and move edges to it from consideration
            // UNTIL list of items is empty

            MatrixDictionary <Item, int> aggregatedCounts =
                MatrixDictionary.CreateCounts(dependencies.Where(d => !Equals(d.UsingItem, d.UsedItem)), transformOptions.OrderBy, globalContext.CurrentGraph);

            for (int i = 0; aggregatedCounts.ColumnKeys.Any(); i++)
            {
                var itemsToSortValues =
                    aggregatedCounts.ColumnKeys.Select(
                        k => new {
                    Item  = k,
                    Value = transformOptions.GetSortValue(aggregatedCounts.GetRowSum(k), aggregatedCounts.GetColumnSum(k))
                });
                decimal minToRatio = itemsToSortValues.Min(ir => ir.Value);
                Item    minItem    = itemsToSortValues.First(ir => ir.Value == minToRatio).Item;

                aggregatedCounts.RemoveColumn(minItem);

                minItem.IncrementMarker(transformOptions.OrderMarkerPrefix + i.ToString("D4"));
            }
            return(Program.OK_RESULT);
        }
Exemplo n.º 2
0
        public override int Transform([NotNull] GlobalContext globalContext, Ignore configureOptions,
                                      [NotNull] TransformOptions transformOptions, [NotNull][ItemNotNull] IEnumerable <Dependency> dependencies,
                                      [NotNull] List <Dependency> transformedDependencies)
        {
            Dependency[] matchingDependencies = dependencies
                                                .Where(d => !transformOptions.Matches.Any() ||
                                                       transformOptions.Matches.Any(m => ItemMatch.IsMatch(m, d.UsingItem)) &&
                                                       transformOptions.Matches.Any(m => ItemMatch.IsMatch(m, d.UsedItem)))
                                                .ToArray();

            MatrixDictionary <Item, int> aggregatedCounts = MatrixDictionary.CreateCounts(matchingDependencies, d => d.Ct,
                                                                                          globalContext.CurrentGraph);

            // Force each item to exist on both matrix axes
            foreach (var from in aggregatedCounts.RowKeys)
            {
                aggregatedCounts.GetColumnSum(from);
            }
            foreach (var to in aggregatedCounts.ColumnKeys)
            {
                aggregatedCounts.GetRowSum(to);
            }

            // aggregatedCounts is used destructively in both following Mark runs; this is no problem,
            // because no sink can also be a source in NDepCheck: Nodes without any edges do not
            // appear; and nodes with only self cycles are either not a source and sink (if ignoreSelfCycles=false),
            // or they are both a source and a sink and hence are found in the first Mark run.

            if (transformOptions.MarkSinks)
            {
                Mark(aggregatedCounts, ac => ac.RowKeys, i => aggregatedCounts.GetRowSum(i),
                     !transformOptions.ConsiderSelfCyclesInSourcesAndSinks, transformOptions.Recursive, transformOptions.MarkerToAdd);
            }
            if (transformOptions.MarkSources)
            {
                Mark(aggregatedCounts, ac => ac.ColumnKeys, i => aggregatedCounts.GetColumnSum(i),
                     !transformOptions.ConsiderSelfCyclesInSourcesAndSinks, transformOptions.Recursive, transformOptions.MarkerToAdd);
            }

            var remainingNodes = new HashSet <Item>(aggregatedCounts.RowKeys);

            remainingNodes.UnionWith(aggregatedCounts.ColumnKeys);

            if (transformOptions.MarkSingleCycleNodes)
            {
                foreach (var d in matchingDependencies)
                {
                    if (Equals(d.UsingItem, d.UsedItem))
                    {
                        d.UsingItem.IncrementMarker(transformOptions.MarkerToAdd);
                    }
                }
            }

            transformedDependencies.AddRange(dependencies);

            return(Program.OK_RESULT);
        }
Exemplo n.º 3
0
        private static void Mark(MatrixDictionary <Item, int> aggregatedCounts,
                                 Func <MatrixDictionary <Item, int>, IEnumerable <Item> > getKeys,
                                 Func <Item, int> sum, bool ignoreSelfCyclesInSourcesAndSinks, bool recursive, string markerToAdd)
        {
            bool itemRemoved;

            do
            {
                itemRemoved = false;
                foreach (var i in getKeys(aggregatedCounts).ToArray())
                {
                    if (sum(i) == (ignoreSelfCyclesInSourcesAndSinks ? aggregatedCounts.Get(i, i) : 0))
                    {
                        aggregatedCounts.RemoveRow(i);
                        aggregatedCounts.RemoveColumn(i);
                        i.IncrementMarker(markerToAdd);
                        itemRemoved = true;
                    }
                }
            } while (recursive && itemRemoved);
        }
Exemplo n.º 4
0
        public void TestOneTopologicalSortStep()
        {
            var          gc    = new GlobalContext();
            WorkingGraph graph = gc.CurrentGraph;

            Item a            = graph.CreateItem(ItemType.SIMPLE, "a");
            Item b            = graph.CreateItem(ItemType.SIMPLE, "b");
            Item c            = graph.CreateItem(ItemType.SIMPLE, "c");
            var  dependencies = new[] {
                graph.CreateDependency(a, b, source: null, markers: "", ct: 1),
                graph.CreateDependency(c, a, source: null, markers: "", ct: 100),
                graph.CreateDependency(c, b, source: null, markers: "", ct: 100)
            };

            var aggregated = new Dictionary <FromTo, Dependency>();

            foreach (var d in dependencies.Where(d => !Equals(d.UsingItem, d.UsedItem)))
            {
                new FromTo(d.UsingItem, d.UsedItem).AggregateDependency(graph, d, aggregated);
            }

            var aggregatedCounts = new MatrixDictionary <Item, int>((s, i) => s + i, (s, i) => s - i);

            foreach (var kvp in aggregated)
            {
                aggregatedCounts.Add(kvp.Key.From, kvp.Key.To, kvp.Value.Ct);
            }

            var itemsToRatios =
                aggregatedCounts.ColumnKeys.Select(
                    k => new {
                Item  = k,
                Ratio = aggregatedCounts.GetRowSum(k) / (aggregatedCounts.GetColumnSum(k) + aggregatedCounts.GetRowSum(k) + 0.001m)
            });
            decimal minToRatio = itemsToRatios.Min(ir => ir.Ratio);
            Item    minItem    = itemsToRatios.First(ir => ir.Ratio == minToRatio).Item;

            Assert.AreEqual(b, minItem);
        }
Exemplo n.º 5
0
        public void TestSmallMatrixDictionary()
        {
            var d = new MatrixDictionary <string, int>((s, i) => s + i, (s, i) => s - i);

            //    |  A  B  #
            // ------------#----
            //  A |  1  2  # 3
            //  B |  4  8  # 12
            //  ========================
            //    |  5 10  #
            d.Add("A", "A", 1);
            d.Add("A", "B", 2);
            d.Add("B", "A", 4);
            d.Add("B", "B", 8);

            Assert.AreEqual(3, d.GetRowSum("A"));
            Assert.AreEqual(12, d.GetRowSum("B"));
            Assert.AreEqual(5, d.GetColumnSum("A"));
            Assert.AreEqual(10, d.GetColumnSum("B"));

            //    |  A  B  #
            // ------------#----
            //  A |  1  2  # 3
            //  B |  -  -  # 0
            //  ========================
            //    |  1  2  #

            for (int i = 0; i < 3; i++)
            {
                d.RemoveRow("B");

                Assert.AreEqual(3, d.GetRowSum("A"));
                Assert.AreEqual(0, d.GetRowSum("B"));
                Assert.AreEqual(1, d.GetColumnSum("A"));
                Assert.AreEqual(2, d.GetColumnSum("B"));
            }
        }
Exemplo n.º 6
0
        public void TestMatrixDictionary()
        {
            var d = new MatrixDictionary <string, int>((s, i) => s + i, (s, i) => s - i);

            //    |   A   B   C   D #
            // ---------------------#----
            //  A |  15 100   0   . # 115
            //  B |   3  20 101   . # 124
            //  C |   7   5  30   . #  42
            //  D |   .   2 300   . # 302
            //  =========================
            //    |  25 127 431   0 #

            d.Add("A", "A", 15);
            d.Add("A", "B", 100);
            d.Add("A", "C", 0);
            d.Add("B", "A", 3);
            d.Add("B", "B", 20);
            d.Add("B", "C", 101);
            d.Add("C", "A", 7);
            d.Add("C", "B", 5);
            d.Add("C", "C", 30);
            d.Add("D", "B", 2);
            d.Add("D", "C", 300);

            Assert.AreEqual(115, d.GetRowSum("A"));
            Assert.AreEqual(124, d.GetRowSum("B"));
            Assert.AreEqual(42, d.GetRowSum("C"));
            Assert.AreEqual(302, d.GetRowSum("D"));

            Assert.AreEqual(25, d.GetColumnSum("A"));
            Assert.AreEqual(127, d.GetColumnSum("B"));
            Assert.AreEqual(431, d.GetColumnSum("C"));
            Assert.AreEqual(0, d.GetColumnSum("D"));

            CollectionAssert.IsSubsetOf(new[] { "A", "B", "C", "D" }, d.RowKeys.ToList());
            CollectionAssert.IsSubsetOf(new[] { "A", "B", "C" }, d.ColumnKeys.ToList());

            for (int i = 0; i < 2; i++)
            {
                Assert.IsTrue(d.RemoveRow("B"));

                //    |   A   B   C   D #
                // ---------------------#----
                //  A |  15 100   0   . # 115
                //  B |   -   -   -   . #   -
                //  C |   7   5  30   . #  42
                //  D |   .   2 300   . # 302
                //  =========================
                //    |  22 107 330   0 #

                Assert.AreEqual(115, d.GetRowSum("A"));
                Assert.AreEqual(0, d.GetRowSum("B"));
                Assert.AreEqual(42, d.GetRowSum("C"));
                Assert.AreEqual(302, d.GetRowSum("D"));

                Assert.AreEqual(22, d.GetColumnSum("A"));
                Assert.AreEqual(107, d.GetColumnSum("B"));
                Assert.AreEqual(330, d.GetColumnSum("C"));
                Assert.AreEqual(0, d.GetColumnSum("D"));

                CollectionAssert.IsSubsetOf(new[] { "A", "C", "D" }, d.RowKeys.ToList());
                CollectionAssert.IsSubsetOf(new[] { "A", "B", "C" }, d.ColumnKeys.ToList());
            }
            Assert.IsTrue(d.RemoveRow("B"));
            Assert.IsFalse(d.RemoveRow("B"));

            for (int i = 0; i < 2; i++)
            {
                Assert.IsTrue(d.RemoveColumn("A"));

                //    |   A   B   C   D #
                // ---------------------#----
                //  A |   = 100   0   . # 100
                //  B |   -   -   -   . #   -
                //  C |   =   5  30   . #  35
                //  D |   .   2 300   . # 302
                //  =========================
                //    |   0 107 330   0 #

                Assert.AreEqual(100, d.GetRowSum("A"));
                Assert.AreEqual(0, d.GetRowSum("B"));
                Assert.AreEqual(35, d.GetRowSum("C"));
                Assert.AreEqual(302, d.GetRowSum("D"));

                Assert.AreEqual(0, d.GetColumnSum("A"));
                Assert.AreEqual(107, d.GetColumnSum("B"));
                Assert.AreEqual(330, d.GetColumnSum("C"));
                Assert.AreEqual(0, d.GetColumnSum("D"));

                CollectionAssert.IsSubsetOf(new[] { "A", "C", "D" }, d.RowKeys.ToList());
                CollectionAssert.IsSubsetOf(new[] { "B", "C" }, d.ColumnKeys.ToList());
            }
            Assert.IsTrue(d.RemoveColumn("A"));
            Assert.IsFalse(d.RemoveColumn("A"));
        }