我正在尝试使用多面体来构建图形。当我没有大量顶点但使用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); }
}
代码工作正常,我唯一关心的就是性能。
我试图简化多边形,甚至使用凸包来减少工作量,但在某些情况下,我需要照原样使用多边形。
因此,我们将不胜感激...
答案 0 :(得分:1)
在以if (vertexCount > 2)
开头的代码行中,您测试了文字计数,但是自上次测试if (vertexCount >= 3)
以来,该计数没有改变。删除第二个if
。
然后,使用Polygon gPol = new Polygon();
创建一个新的多边形。之后,此多边形立即由out
中的polygons.TryGetValue(newId, out gPol)
参数替换。
TryGetValue
产生true
,然后gPol
成为在集合中找到的多边形,或者TryGetValue
产生false
而gPol
变成{{1} }。不要分配null
gPol
或使用C#7.0语法
Polygon gPol;
if (polygons.TryGetValue(newId, out gPol)) ...
在if (polygons.TryGetValue(newId, out Polygon gPol)) ...
情况下,您应该创建一个新的多边形(因为else
是gPol
)。但是,您可以简化此代码,因为在两种情况下都添加了边缘:
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
刚刚创建的列表。