예제 #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);
        }
예제 #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);
        }