/// <summary> /// Attempts to remove an edge entering a specific vertex from the strongly connected /// portion of a specific connected subgraph and replace it with another edge towards an /// edge from a weakly connected portion of the connected subgraph, thus expanding the /// strongly connected portion. /// </summary> /// <param name="connectedSubgraph">The connected subgraph which contains a weakly /// connected portion.</param> /// <param name="vertex">The vertex from the strongly connected portion of the connected /// subgraph.</param> /// <returns><see langword="true"/> if the edge was successfully added.</returns> private bool AddStronglyConnectingEdgeEnteringVertex( ConnectedSubgraph connectedSubgraph, Vertex vertex) { Vertex otherVertex = null; List<Vertex> adjacentVertices = GetAdjacentVertices(vertex); while (adjacentVertices.Count > 0) { int vertexIndex = _random.Next(adjacentVertices.Count); Vertex adjacentVertex = adjacentVertices[vertexIndex]; if (!vertex.IsConnectedToVertex(adjacentVertex) && connectedSubgraph.ContainsVertex(adjacentVertex) && !connectedSubgraph.IsVertexStronglyConnected(adjacentVertex)) { if (connectedSubgraph.CheckWillConnectStrongly(vertex, adjacentVertex)) { if (!CheckCanConnectVertices(vertex, adjacentVertex)) { // If the two vertices cannot be connected without causing an // intersection, remove the other edge Vertex crossVertex1 = _levelMatrix[vertex.Row, adjacentVertex.Column]; Vertex crossVertex2 = _levelMatrix[adjacentVertex.Row, vertex.Column]; RemoveEdgeBetweenVertices(crossVertex1, crossVertex2); } // Check if the other vertex has the maximum number of edges entering it // and if so, remove a random edge entering it if (adjacentVertex.ConnectedVertexCount == _maxEdges) RemoveEdgeEnteringVertex(adjacentVertex); otherVertex = adjacentVertex; break; } } adjacentVertices.RemoveAt(vertexIndex); } // If no suitable other vertex was found, give up if (otherVertex == null) return false; // Check if the specified vertex has the maximum number of edges entering it and if so, // remove a random edge entering it if (vertex.ConnectedVertexCount == _maxEdges) RemoveEdgeEnteringVertex(vertex); // Add the edge to the level graph AddEdgeBetweenVertices(vertex, otherVertex); return true; }
/// <summary> /// Checks if an edge can be added between two adjacent vertices without resulting in an /// intersection. /// </summary> /// <param name="vertex1">The first vertex.</param> /// <param name="vertex2">The second vertex.</param> /// <returns><see langword="true"/> if the vertices are not directly connected and an edge /// can be added between them without resulting in an intersection.</returns> private bool CheckCanConnectVertices(Vertex vertex1, Vertex vertex2) { // If the two vertices are already connected, they should not be connected again if (vertex1.IsConnectedToVertex(vertex2)) return false; // If the two vertices are diagonally adjacent in the level matrix, check if there is // an edge between their opposite vertices that will result in an intersection if (vertex1.Row != vertex2.Row && vertex1.Column != vertex2.Column) { Vertex crossVertex1 = _levelMatrix[vertex1.Row, vertex2.Column]; Vertex crossVertex2 = _levelMatrix[vertex2.Row, vertex1.Column]; if (crossVertex1.IsConnectedToVertex(crossVertex2)) return false; } return true; }
/// <summary> /// Attempts to add an edge entering an isolated vertex in order to meet the minimum /// requirement of two edges entering it. /// </summary> /// <param name="vertex">The isolated vertex which needs another edge entering it.</param> /// <returns><see langword="true"/> if the edge was successfully added.</returns> private bool AddSecondaryEdgeEnteringVertex(Vertex vertex) { // Attempt to find an adjacent vertex that can be connected to the specified vertex; if // an edge prevents the two vertices from being connected, remove it Vertex otherVertex = null; List<Vertex> adjacentVertices = GetAdjacentVertices(vertex); while (adjacentVertices.Count > 0) { int vertexIndex = _random.Next(adjacentVertices.Count); Vertex adjacentVertex = adjacentVertices[vertexIndex]; if (!vertex.IsConnectedToVertex(adjacentVertex)) { if (!CheckCanConnectVertices(vertex, adjacentVertex)) { // If the two vertices cannot be connected without causing an intersection, // remove the other edge Vertex crossVertex1 = _levelMatrix[vertex.Row, adjacentVertex.Column]; Vertex crossVertex2 = _levelMatrix[adjacentVertex.Row, vertex.Column]; RemoveEdgeBetweenVertices(crossVertex1, crossVertex2); } // Check if the other vertex has the maximum number of edges entering it and if // so, remove a random edge entering it if (adjacentVertex.ConnectedVertexCount == _maxEdges) RemoveEdgeEnteringVertex(adjacentVertex); otherVertex = adjacentVertex; break; } adjacentVertices.RemoveAt(vertexIndex); } // If no suitable other vertex was found, give up if (otherVertex == null) return false; // Add the edge to the level graph AddEdgeBetweenVertices(vertex, otherVertex); return true; }