示例#1
0
 /// <summary>
 /// Creates the vertices in the level graph and fills the level matrix and connected
 /// subgraph dictionary with them.
 /// </summary>
 private void CreateVertices()
 {
     for (int row = 0; row < _rows; row++)
     {
         for (int column = 0; column < _columns; column++)
         {
             var vertex = new Vertex(row, column);
             _levelMatrix[row, column] = vertex;
             _connectedSubgraphs[vertex] = new ConnectedSubgraph(vertex);
             _availableVertices.Add(vertex);
         }
     }
 }
示例#2
0
        /// <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;
        }
示例#3
0
        /// <summary>
        /// Adjusts the connected subgraph assignment for a specific vertex.
        /// </summary>
        /// <param name="vertex">The vertex whose connected subgraph should be adjusted.
        /// </param>
        /// <param name="recalculateCurrent">Specifies whether the vertex's currently assigned
        /// connected subgraph should be recalculated before adjusting the assignment.</param>
        private void AdjustConnectedSubgraphs(Vertex vertex, bool recalculateCurrent)
        {
            ConnectedSubgraph currentGraph = _connectedSubgraphs[vertex];

            // Recalculate the currently assigned connected subgraph if needed
            if (recalculateCurrent)
                currentGraph.RecalculateConnectedVertices();

            // If the specified vertex does not belong to its currently assigned connected
            // subgraph, create a new connected subgraph object using the specified vertex as a
            // main vertex for it and then assign it to all vertices that belong to it
            if (!currentGraph.ContainsVertex(vertex))
            {
                var newGraph = new ConnectedSubgraph(vertex);
                foreach (Vertex connectedVertex in newGraph.ConnectedVertices)
                {
                    _connectedSubgraphs[connectedVertex] = newGraph;
                }
            }
        }
示例#4
0
        /// <summary>
        /// Attempts to remove an edge entering a specific vertex in a specific connected subgraph
        /// and replace it with another edge towards a different connected subgraph, thus merging
        /// the two connected subgraphs.
        /// </summary>
        /// <param name="connectedSubgraph">The connected subgraph which should be merged with
        /// another one.</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 AddExternalEdgeEnteringVertex(
            ConnectedSubgraph connectedSubgraph,
            Vertex vertex)
        {
            // Attempt to find another vertex from a different connected subgraph 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 (!connectedSubgraph.ContainsVertex(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;
        }