/// <inheritdoc/> public UndirectedIndexedIncidenceGraph ToGraph() { int n = _vertexCount; int m = _tailByEdge.Count; Debug.Assert(_tailByEdge.Count == _headByEdge.Count, "_tailByEdge.Count == _headByEdge.Count"); int dataLength = 2 + n + m + m + m + m; #if NET5 int[] data = GC.AllocateUninitializedArray <int>(dataLength); #else int[] data = new int[dataLength]; #endif data[0] = n; data[1] = m; Span <int> destEdgesOrderedByTail = data.AsSpan(2 + n, m + m); int invertedEdgeCount = 0; for (int edge = 0; edge < m; ++edge) { destEdgesOrderedByTail[edge] = edge; int head = _headByEdge[edge]; int tail = _tailByEdge[edge]; if (head != tail) { destEdgesOrderedByTail[m + invertedEdgeCount++] = ~edge; } } int directedEdgeCount = m + invertedEdgeCount; Array.Sort(data, 2 + n, directedEdgeCount, new UndirectedIndexedEdgeComparer(_tailByEdge.Array, _headByEdge.Array)); Span <int> destUpperBoundByVertex = data.AsSpan(2, n); destUpperBoundByVertex.Clear(); for (int i = 0; i < directedEdgeCount; ++i) { int edge = destEdgesOrderedByTail[i]; int tail = edge < 0 ? _headByEdge[~edge] : _tailByEdge[edge]; ++destUpperBoundByVertex[tail]; } for (int vertex = 1; vertex < n; ++vertex) { destUpperBoundByVertex[vertex] += destUpperBoundByVertex[vertex - 1]; } Span <int> destHeadByEdge = data.AsSpan(2 + n + m + m, m); _headByEdge.AsSpan().CopyTo(destHeadByEdge); Span <int> destTailByEdge = data.AsSpan(2 + n + m + m + m, m); _tailByEdge.AsSpan().CopyTo(destTailByEdge); _headByEdge = ArrayPrefixBuilder.Release(_headByEdge, false); _tailByEdge = ArrayPrefixBuilder.Release(_tailByEdge, false); _vertexCount = 0; return(new UndirectedIndexedIncidenceGraph(data)); }
/// <inheritdoc/> public IndexedIncidenceGraph ToGraph() { int n = _vertexCount; int m = _tailByEdge.Count; Debug.Assert(_tailByEdge.Count == _headByEdge.Count, "_tailByEdge.Count == _headByEdge.Count"); int dataLength = 2 + n + m + m + m; #if NET5 int[] data = GC.AllocateUninitializedArray <int>(dataLength); #else int[] data = new int[dataLength]; #endif data[0] = n; data[1] = m; Span <int> destReorderedEdges = data.AsSpan(2 + n, m); for (int edge = 0; edge < m; ++edge) { destReorderedEdges[edge] = edge; } if (NeedsReordering) { Array.Sort(data, 2 + n, m, new IndexedEdgeComparer(_tailByEdge.Array)); } Span <int> destUpperBoundByVertex = data.AsSpan(2, n); destUpperBoundByVertex.Clear(); for (int edge = 0; edge < m; ++edge) { int tail = _tailByEdge[edge]; ++destUpperBoundByVertex[tail]; } for (int vertex = 1; vertex < n; ++vertex) { destUpperBoundByVertex[vertex] += destUpperBoundByVertex[vertex - 1]; } Span <int> destHeadByEdge = data.AsSpan(2 + n + m, m); _headByEdge.AsSpan().CopyTo(destHeadByEdge); Span <int> destTailByEdge = data.AsSpan(2 + n + m + m, m); _tailByEdge.AsSpan().CopyTo(destTailByEdge); _currentMaxTail = 0; _headByEdge = ArrayPrefixBuilder.Release(_headByEdge, false); _tailByEdge = ArrayPrefixBuilder.Release(_tailByEdge, false); _vertexCount = 0; return(new IndexedIncidenceGraph(data)); }