Exemplo n.º 1
0
        private static void RemoveRefenceCycles(SolvingNode[] nodes)
        {
            while (true)
            {
                var refList = FindRefNodesGraph(nodes);

                var arrayOfRefList = refList.ToArray();
                var refGraph       = ConvertToRefArrayGraph(arrayOfRefList);
                var refTopology    = GraphTools.SortTopology(refGraph);
                if (!refTopology.HasCycle)
                {
                    return;
                }

                var refCycle = refTopology.NodeNames.Select(n => nodes[n.To]).ToArray();
                SolvingFunctions.MergeGroup(refCycle);
            }
        }
Exemplo n.º 2
0
        public static NodeSortResult Toposort(SolvingNode[] nodes)
        {
            //На данном этапе - в nodes лежат все узлы участвующие в вычислениях
            //нужно убрать все  циклы с ребрами "равно", что-бы можно было спокойно работать далее
            //не опасаясь Stackoverflow
            RemoveRefenceCycles(nodes);
            //Теперь из графа можно исключить все ребра "равно". Для этого нужно перекинуть
            //все взаимодействия (Ancestor и Member) на оригинальные узлы
            //
            //Это нужно для того что бы можно было провести направленный топосорт

            MergeAllReferences(nodes, out var refs, out var concretes);

            var graph  = ConvertToArrayGraph(concretes);
            var sorted = GraphTools.SortTopology(graph);
            var order  = sorted.NodeNames.Select(n => concretes[n.To]).Reverse().ToArray();

            return(new NodeSortResult(order, refs,
                                      sorted.HasCycle
                ? sorted.NodeNames.Any(n => n.Type == EdgeType.Member)
                    ? SortStatus.MemebershipCycle
                    : SortStatus.AncestorCycle
                : SortStatus.Sorted));
        }