Exemple #1
0
        /// <inheritdoc/>
        public Dictionary <string, string> GetQueryParameters()
        {
            if (!_selects.Any())
            {
                return(null);
            }

            return(new Dictionary <string, string>
            {
                { "select", _selects.ToString() }
            });
        }
Exemple #2
0
        /// <inheritdoc/>
        public Dictionary <string, string> GetQueryParameters()
        {
            if (!_expands.Any())
            {
                return(null);
            }

            return(new Dictionary <string, string>
            {
                { "include", _expands.ToString() }
            });
        }
        public bool IsPlanar(Graph graphArgument)
        {
            var enableCudafy = Settings.EnableCudafy;

            Settings.EnableCudafy = true;

            if (WorkerLog != null)
            {
                WorkerLog("Начало гамма-алгоритма");
            }
            var graph = new Graph(graphArgument);

            Debug.Assert(
                graph.Children.All(pair => pair.Value
                                   .All(value => graph.Children.ContainsKey(value) &&
                                        graph.Children[value].Contains(pair.Key)))
                );

            if (WorkerBegin != null)
            {
                WorkerBegin();
            }
            // Шаг первый - удаляем все листья и узлы степени 2
            if (WorkerLog != null)
            {
                WorkerLog("Удаляем все листья и узлы степени 2");
            }

            // листья представляют собой дерево и нарисовать его плоскую укладку тривиально.
            graph.RemoveAllTrees();

            // Замечание. Если на ребра планарного графа нанести произвольное число вершин степени 2,
            // то он останется планарным; равным образом, если на ребра непланарного графа
            // нанести вершины степени 2, то он планарным не станет.
            graph.RemoveIntermedians();

            // Шаг второй - граф нужно укладывать отдельно по компонентам связности.
            if (WorkerLog != null)
            {
                WorkerLog("Находим ВСЕ пути в графе длины не более размера графа + 1");
            }
            Dictionary <int, PathDictionary> cachedAllGraphPaths = graph.GetAllGraphPaths();
            var queue = new StackListQueue <Context>
            {
                graph.GetAllSubGraphs().Select(subgraph =>
                                               new Context
                {
                    SubGraphQueue =
                        new StackListQueue <Graph>
                    {
                        subgraph
                    },
                    CachedSubGraphPathsQueue =
                        new StackListQueue <Dictionary <int, PathDictionary> >
                    {
                        Graph.GetSubgraphPaths(subgraph.Vertices, cachedAllGraphPaths)
                    },
                })
            };

            Debug.WriteLine("start ");

            foreach (Context context in queue)
            {
                while (context.SubGraphQueue.Any())
                {
                    Graph subGraph = context.SubGraphQueue.Dequeue();
                    if (WorkerLog != null)
                    {
                        WorkerLog("Проверка связанной компоненты " + subGraph);
                    }
                    Dictionary <int, PathDictionary> cachedSubGraphPaths =
                        context.CachedSubGraphPathsQueue.Dequeue();

                    // На вход подаются графы, обладающие следующими свойствами:
                    // граф связный;
                    // граф имеет хотя бы один цикл;
                    // граф не имеет мостиков, т. е. ребер, после удаления которых
                    // граф распадается на две компонеты связности.

                    if (WorkerLog != null)
                    {
                        WorkerLog(
                            "Находим мосты после удаления которых граф распадается на несколько компонет связности");
                    }

                    var vertices = new StackListQueue <Vertex>(subGraph.Vertices);
                    var bridges  = new StackListQueue <Vertex>();
                    for (int i = 0; i < vertices.Count; i++)
                    {
                        Vertex dequeue = vertices.Dequeue();
                        IEnumerable <Graph> subsubgraphs = subGraph.GetSubgraph(vertices).GetAllSubGraphs();
                        if (subsubgraphs.Count() > 1)
                        {
                            bridges.Add(dequeue);
                        }
                        vertices.Enqueue(dequeue);
                    }

                    Debug.Assert(bridges.Count != vertices.Count);

                    if (bridges.Any())
                    {
                        // Если в графе есть мосты, то их нужно разрезать, провести отдельно плоскую укладку
                        // каждой компоненты связности, а затем соединить их мостами.
                        // Здесь может возникнуть трудность: в процессе укладки концевые вершины моста могут
                        // оказаться внутри плоского графа. Нарисуем одну компоненту связности,
                        // и будем присоединять к ней другие последовательно.
                        // Каждую новую компоненту связности будем рисовать в той грани, в которой лежит
                        // концевая вершина соответствующего моста. Так как граф связности мостами компонент
                        // связности является деревом, мы сумеем получить плоскую укладку.
                        if (WorkerLog != null)
                        {
                            WorkerLog(
                                "В графе есть мосты, их нужно разрезать, провести отдельно плоскую укладку, а затем соединить их мостами.");
                        }
                        if (WorkerLog != null)
                        {
                            WorkerLog("Мосты: " + string.Join(",", bridges));
                        }

                        IEnumerable <Vertex> exceptBridges = vertices.Except(bridges);
                        IEnumerable <Graph>  subsubgraphs  = subGraph.GetSubgraph(exceptBridges).GetAllSubGraphs();
                        Debug.WriteLine("subsubgraphs = " + subsubgraphs.Count());
                        context.SubGraphQueue.Enqueue(
                            subsubgraphs.Select(subgraph => subGraph.GetSubgraph(subgraph.Vertices.Union(bridges))));
                        context.CachedSubGraphPathsQueue.Enqueue(
                            subsubgraphs.Select(
                                subgraph =>
                                Graph.GetSubgraphPaths(subgraph.Vertices.Union(bridges), cachedSubGraphPaths)));

                        continue;
                    }

                    if (WorkerLog != null)
                    {
                        WorkerLog("Находим ЛЮБОЙ МАКСИМАЛЬНОЙ ДЛИНЫ простой цикл в графе");
                    }
                    Circle circle = null;
                    for (int i = cachedSubGraphPaths.Keys.Max(); i > 3; i--)
                    {
                        foreach (var pair in cachedSubGraphPaths.Where(pair => pair.Key == i))
                        {
                            foreach (
                                var key in
                                subGraph.Vertices.Select(vertex => new KeyValuePair <Vertex, Vertex>(vertex, vertex))
                                )
                            {
                                if (pair.Value.ContainsKey(key) && pair.Value[key].Any())
                                {
                                    foreach (Path path in pair.Value[key])
                                    {
                                        circle = new Circle(path.GetRange(0, path.Count - 1));
                                        if (Circle.IsSimple(circle))
                                        {
                                            break;
                                        }
                                        circle = null;
                                    }
                                    if (circle != null)
                                    {
                                        break;
                                    }
                                }
                                if (circle != null)
                                {
                                    break;
                                }
                            }
                            if (circle != null)
                            {
                                break;
                            }
                        }
                        if (circle != null)
                        {
                            break;
                        }
                    }

                    if (circle == null && !context.Edges.Any())
                    {
                        // граф — дерево и нарисовать его плоскую укладку тривиально.
                        // Поскольку мы ещё не начинали рисовать, то значит всё проверено
                        continue;
                    }

                    // Инициализация алгоритма производится так: выбираем любой простой цикл;
                    // и получаем две грани: Γ1 — внешнюю и Γ2 — внутреннюю

                    if (circle != null && !context.Edges.Any())
                    {
                        context.Edges.Add(new Edge(circle));
                    }

                    if (circle != null)
                    {
                        context.Edges.Add(new Edge(circle));
                        context.Builded.Add(context.Edges.Last());
                    }
                    // Если циклов нет, то надо проверить, что данное дерево
                    // можно вписать в уже построенный граф

                    Debug.WriteLine("SubGraph " + subGraph);
                    Debug.WriteLine("builded " + context.Builded);
                    Debug.WriteLine("edges:" +
                                    string.Join(Environment.NewLine, context.Edges.Select(e => e.ToString())));


                    //// Каждый сегмент S относительно уже построенного графа G′ представляет собой одно из двух:
                    //// ребро, оба конца которого принадлежат G′, но само оно не принадлежит G′;
                    //// связную компоненту графа G – G′, дополненную всеми ребрами графа G,
                    //// один из концов которых принадлежит связной компоненте,
                    //// а второй из графа G′.

                    VertexSortedCollection           buildedVertices = context.Builded.Vertices;
                    Dictionary <int, PathDictionary> fromTo          = Graph.GetFromToPaths(buildedVertices,
                                                                                            buildedVertices,
                                                                                            cachedSubGraphPaths);
                    var paths =
                        new PathCollection(fromTo
                                           .SelectMany(pair => pair.Value)
                                           .SelectMany(pair => pair.Value)
                                           .Where(Path.IsNoVertix)
                                           .Where(Path.IsNoCircle)
                                           );
                    Debug.WriteLine("paths " + paths);

                    //var secondGraph = new Graph(subGraph.Except(context.Builded));

                    //if (secondGraph.Any())
                    //{
                    //    IEnumerable<Graph> collection = secondGraph.GetAllSubGraphs();
                    //    context.SubGraphQueue.Enqueue(collection);
                    //    context.CachedSubGraphPathsQueue.Enqueue(
                    //        collection.Select(subgraph => Graph.GetSubgraphPaths(subgraph.Vertices, cachedSubGraphPaths)));
                    //}



                    paths.ReplaceAll(paths.Distinct());
                    Debug.WriteLine("paths " + paths);
                    paths.RemoveAll(context.Builded.Contains);

                    Debug.WriteLine("paths " + paths);
                    Debug.WriteLine("builded " + context.Builded);
                    Debug.WriteLine("edges:" +
                                    string.Join(Environment.NewLine, context.Edges.Select(e => e.ToString())));

                    while (paths.Any())
                    {
                        paths.RemoveAll(context.Builded.Contains);
                        Debug.WriteLine("paths " + paths);
                        if (!paths.Any())
                        {
                            continue;
                        }
                        if (Settings.EnableCudafy)
                        {
                            try
                            {
                                while (paths.Any(Path.IsLong))
                                {
                                    // Находим для всех путей их перечечения с уже построенным графом
                                    // Разбиваем пути в найденных точках пересечения с уже построенным графом
                                    // Если точек пересечения не найдено, то выходим из цикла

                                    int[,] matrix;
                                    int[] indexes;
                                    lock (CudafySequencies.Semaphore)
                                    {
                                        CudafySequencies.SetSequencies(
                                            paths.Select(
                                                path =>
                                                path.GetRange(1, path.Count - 2)
                                                .Select(vertex => vertex.Id)
                                                .ToArray())
                                            .ToArray(),
                                            context.Builded.Vertices.Select(
                                                vertex => new StackListQueue <int>(vertex.Id).ToArray())
                                            .ToArray()
                                            );
                                        CudafySequencies.Execute("CountIntersections");
                                        // подсчитываем число пересечений
                                        matrix = CudafySequencies.GetMatrix();
                                    }
                                    lock (CudafyMatrix.Semaphore)
                                    {
                                        CudafyMatrix.SetMatrix(matrix);
                                        CudafyMatrix.ExecuteRepeatZeroIndexOfNonZero();
                                        // находим индексы ненулевых элементов в строках
                                        indexes = CudafyMatrix.GetIndexes();
                                    }
                                    Dictionary <int, int> dictionary = indexes.Select(
                                        (value, index) => new KeyValuePair <int, int>(index, value))
                                                                       .Where(pair => pair.Value >= 0)
                                                                       .ToDictionary(pair => pair.Key, pair => pair.Value);
                                    if (!dictionary.Any())
                                    {
                                        break;
                                    }
                                    Debug.Assert(dictionary.All(pair => pair.Key >= 0));
                                    Debug.Assert(dictionary.All(pair => pair.Value >= 0));
                                    Debug.Assert(dictionary.All(pair => pair.Key < paths.Count));
                                    Debug.Assert(dictionary.All(pair => pair.Value < context.Builded.Vertices.Count));
                                    var dictionary2 = new StackListQueue <KeyValuePair <Path, Vertex> >(
                                        dictionary.Select(
                                            pair =>
                                            new KeyValuePair <Path, Vertex>(new Path(paths[pair.Key]),
                                                                            new Vertex(context.Builded.Vertices[pair.Value])))
                                        );
                                    var list = new StackListQueue <int>(dictionary.Select(pair => pair.Key).Distinct());
                                    list.Sort();
                                    Debug.Assert(dictionary2.All(pair => pair.Key.Count > 1));
                                    for (int i = list.Count; i-- > 0;)
                                    {
                                        paths.RemoveAt(list[i]);
                                    }
                                    paths.AddRangeExcept(
                                        new PathCollection(
                                            dictionary2.SelectMany(pair => pair.Key.SplitBy(pair.Value)
                                                                   .Where(Path.IsNoVertix)
                                                                   .Where(Path.IsNoCircle))
                                            .Distinct()));
                                    paths.ReplaceAll(paths.Distinct());
                                    paths.RemoveAll(context.Builded.Contains);
                                }
                            }
                            catch (Exception ex)
                            {
                                if (WorkerLog != null)
                                {
                                    WorkerLog(ex.ToString());
                                }
                                paths.ReplaceAll(
                                    paths.SelectMany(context.Builded.Split)
                                    .Where(Path.IsNoVertix)
                                    .Where(Path.IsNoCircle)
                                    );
                                paths.ReplaceAll(paths.Distinct());
                                paths.RemoveAll(context.Builded.Contains);
                            }
                        }
        protected override void ProcessResource( PathCollection aPaths )
        {
            if ( !aPaths.Any() )
            return;

              OnCategoryProcessing( ResourceTypes.Paths );
              Directory.CreateDirectory( Directories.Paths );
              var previous = SetCurrentDirectory( Directories.Paths );

              foreach ( var path in aPaths ) {
            var document =
              new XElement( "Path",
            CreateIndexedResourceNodes( path ),
            new XComment( "Node below refers to: " + FindResourceName( m_gmk.Rooms, path.BackgroundRoom ) ),
            new XElement( "BackgroundRoom", path.BackgroundRoom ),
            new XElement( "ConnectionKind", path.ConnectionKind ),
            new XElement( "Closed", path.Closed ),
            new XElement( "Precision", path.Precision ),
            new XElement( "SnapX", path.SnapX ),
            new XElement( "SnapY", path.SnapY ),
            new XElement( "Points",
              from point in path.Points select
              new XElement( "Point",
                new XElement( "X", point.X ),
                new XElement( "Y", point.Y ),
                new XElement( "Speed", point.Speed )
              )
            )
              );

            SaveDocument( document, SafeResourceFilename( path ) + ".xml" );
            OnResourceProcessed( path.Name );
              }

              OnCategoryProcessed( ResourceTypes.Paths );
              SetCurrentDirectory( previous );
        }