从多边形创建图形需要花费大量的顶点时间

时间:2018-07-28 15:00:08

标签: c# performance asp.net-core graph

我正在尝试使用多面体来构建图形。当我没有大量顶点但使用1M时,代码工作正常。有任何性能改进建议吗?

public Graph(List<Polygon> PolygonsSet)
    {
        edges = new List<Edge>();
        graphID = Guid.NewGuid();
        //Setting up Graph instance by adding vertices, edges and polygons
        foreach (Polygon Polygon in PolygonsSet)
        {
            List<Vertex> vertices = Polygon.vertices;

            // Clear pre-existing edges in the case this is an updating process.
            Polygon.edges.Clear();

            //If there is only one polygon, treat it as boundary
            if (PolygonsSet.Count() == 1)
            {
                Polygon.isBoundary = true;
            }

            //If first and last point of vertices list are the same, remove last.
            if (vertices.First().Equals(vertices.Last()) && vertices.Count() > 1)
            {
                vertices = vertices.Take(vertices.Count() - 1).ToList();
            }


            //For each point, creates vertex and associated edge and adds them
            //to the polygons Dictionary
            int vertexCount = vertices.Count();

            // If valid polygon
            if (vertexCount >= 3)
            {
                int newId = GetNextId();
                for (var j = 0; j < vertexCount; j++)
                {
                    int next_index = (j + 1) % vertexCount;
                    Vertex vertex = vertices[j];
                    Vertex next_vertex = vertices[next_index];
                    Edge edge = new Edge(vertex, next_vertex);

                    //If is a valid polygon, add id to vertex and
                    //edge to vertices dictionary
                    if (vertexCount > 2)
                    {
                        vertex.polygonId = newId;
                        next_vertex.polygonId = newId;
                        Polygon gPol = new Polygon();
                        if (polygons.TryGetValue(newId, out gPol))
                        {
                            gPol.edges.Add(edge);
                        }
                        else
                        {
                            Polygon.edges.Add(edge);
                            Polygon.id = newId;
                            polygons.Add(newId, Polygon);
                        }
                    }
                    AddEdge(edge);
                }
            }

        }
    }

和AddEdge方法是;

public void AddEdge(Edge edge)
    {
        List<Edge> startEdgesList = new List<Edge>();
        List<Edge> endEdgesList = new List<Edge>();
        if (graph.TryGetValue(edge.StartVertex, out startEdgesList))
        {
            if (!startEdgesList.Contains(edge)) { startEdgesList.Add(edge); }
        }
        else
        {
            graph.Add(edge.StartVertex, new List<Edge>() { edge });
        }

        if (graph.TryGetValue(edge.EndVertex, out endEdgesList))
        {
            if (!endEdgesList.Contains(edge)) { endEdgesList.Add(edge); }
        }
        else
        {
            graph.Add(edge.EndVertex, new List<Edge>() { edge });
        }

        if (!edges.Contains(edge)) { edges.Add(edge); }
    }

代码工作正常,我唯一关心的就是性能。

我试图简化多边形,甚至使用凸包来减少工作量,但在某些情况下,我需要照原样使用多边形。

因此,我们将不胜感激...

1 个答案:

答案 0 :(得分:1)

在以if (vertexCount > 2)开头的代码行中,您测试了文字计数,但是自上次测试if (vertexCount >= 3)以来,该计数没有改变。删除第二个if。 然后,使用Polygon gPol = new Polygon();创建一个新的多边形。之后,此多边形立即由out中的polygons.TryGetValue(newId, out gPol)参数替换。 TryGetValue产生true,然后gPol成为在集合中找到的多边形,或者TryGetValue产生falsegPol变成{{1} }。不要分配null

gPol

或使用C#7.0语法

Polygon gPol;
if (polygons.TryGetValue(newId, out gPol)) ...

if (polygons.TryGetValue(newId, out Polygon gPol)) ... 情况下,您应该创建一个新的多边形(因为elsegPol)。但是,您可以简化此代码,因为在两种情况下都添加了边缘:

null

您似乎也将if (!polygons.TryGetValue(newId, out Polygon gPol)) { gPol = new Polygon { id = newId }; polygons.Add(newId, gPol); } gPol.edges.Add(edge); Polygon混淆了。


由于gPol是在for循环之前创建的,因此您可以将查找或创建Polyon的代码移出循环

newId

int vertexCount = vertices.Count(); if (vertexCount >= 3) { int newId = GetNextId(); if (!polygons.TryGetValue(newId, out Polygon gPol)) { gPol = new Polygon { id = newId }; polygons.Add(newId, gPol); } for (var j = 0; j < vertexCount; j++) { int next_index = (j + 1) % vertexCount; Vertex vertex = vertices[j]; Vertex next_vertex = vertices[next_index]; Edge edge = new Edge(vertex, next_vertex); vertex.polygonId = newId; next_vertex.polygonId = newId; gPol.edges.Add(edge); AddEdge(edge); } } 中,您重复同样的错误,即覆盖了AddEdge刚刚创建的列表。