/// <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)); }
/// <summary> /// Initializes a new instance of the <see cref="MutableUndirectedSimpleIncidenceGraph"/> class. /// </summary> /// <param name="initialVertexCount">The initial number of vertices.</param> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="initialVertexCount"/> is less than zero. /// </exception> public MutableUndirectedSimpleIncidenceGraph(int initialVertexCount = 0) { if (initialVertexCount < 0) { throw new ArgumentOutOfRangeException(nameof(initialVertexCount)); } _outEdgesByVertex = ArrayPrefixBuilder.EnsureSize(_outEdgesByVertex, initialVertexCount, true); }
/// <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)); }
/// <inheritdoc/> public SimpleIncidenceGraph ToGraph() { int n = _vertexCount; int m = _edges.Count; Endpoints[] array = _edges.Array; Debug.Assert(array != null, nameof(array) + " != null"); if (NeedsReordering) { Array.Sort(array, 0, m, SimpleEdgeComparer.Instance); } Endpoints[] edgesOrderedByTail; if (array.Length == _edges.Count) { edgesOrderedByTail = array; _edges = ArrayPrefix <Endpoints> .Empty; } else { #if NET5 edgesOrderedByTail = GC.AllocateUninitializedArray <Endpoints>(m); #else edgesOrderedByTail = new Endpoints[m]; #endif _edges.CopyTo(edgesOrderedByTail); _edges = ArrayPrefixBuilder.Release(_edges, false); } int[] data = new int[2 + n]; data[0] = n; data[1] = m; Span <int> destUpperBoundByVertex = data.AsSpan(2); foreach (Endpoints edge in edgesOrderedByTail) { int tail = edge.Tail; ++destUpperBoundByVertex[tail]; } for (int vertex = 1; vertex < n; ++vertex) { destUpperBoundByVertex[vertex] += destUpperBoundByVertex[vertex - 1]; } _currentMaxTail = 0; _vertexCount = 0; return(new SimpleIncidenceGraph(data, edgesOrderedByTail)); }
/// <summary> /// Initializes a new instance of the <see cref="Builder"/> class. /// </summary> /// <param name="initialVertexCount">The initial number of vertices.</param> /// <param name="edgeCapacity">The initial capacity of the internal backing storage for the edges.</param> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="initialVertexCount"/> is less than zero, or <paramref name="edgeCapacity"/> is less than zero. /// </exception> public Builder(int initialVertexCount = 0, int edgeCapacity = 0) { if (initialVertexCount < 0) { throw new ArgumentOutOfRangeException(nameof(initialVertexCount)); } if (edgeCapacity < 0) { throw new ArgumentOutOfRangeException(nameof(edgeCapacity)); } _edges = ArrayPrefixBuilder.Create <Endpoints>(edgeCapacity); _vertexCount = initialVertexCount; }
private Endpoints UncheckedAdd(int tail, int head) { _currentMaxTail = tail < _currentMaxTail ? int.MaxValue : tail; int newVertexCountCandidate = Math.Max(tail, head) + 1; if (newVertexCountCandidate > _vertexCount) { _vertexCount = newVertexCountCandidate; } var edge = new Endpoints(tail, head); _edges = ArrayPrefixBuilder.Add(_edges, edge, false); return(edge); }
private int UncheckedAdd(int tail, int head) { int newVertexCountCandidate = Math.Max(tail, head) + 1; if (newVertexCountCandidate > _vertexCount) { _vertexCount = newVertexCountCandidate; } Debug.Assert(_tailByEdge.Count == _headByEdge.Count, "_tailByEdge.Count == _headByEdge.Count"); int edge = _tailByEdge.Count; _tailByEdge = ArrayPrefixBuilder.Add(_tailByEdge, tail, false); _headByEdge = ArrayPrefixBuilder.Add(_headByEdge, head, false); return(edge); }
/// <summary> /// Initializes a new instance of the <see cref="MutableIndexedIncidenceGraph"/> class. /// </summary> /// <param name="initialVertexCount">The initial number of vertices.</param> /// <param name="edgeCapacity">The initial capacity of the internal backing storage for the edges.</param> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="initialVertexCount"/> is less than zero, or <paramref name="edgeCapacity"/> is less than zero. /// </exception> public MutableIndexedIncidenceGraph(int initialVertexCount = 0, int edgeCapacity = 0) { if (initialVertexCount < 0) { throw new ArgumentOutOfRangeException(nameof(initialVertexCount)); } if (edgeCapacity < 0) { throw new ArgumentOutOfRangeException(nameof(edgeCapacity)); } int effectiveEdgeCapacity = Math.Max(edgeCapacity, DefaultInitialOutDegree); _tailByEdge = ArrayPrefixBuilder.Create <int>(effectiveEdgeCapacity); _headByEdge = ArrayPrefixBuilder.Create <int>(effectiveEdgeCapacity); _outEdgesByVertex = ArrayPrefixBuilder.Create <ArrayPrefix <int> >(initialVertexCount); }
private Endpoints UncheckedAdd(int tail, int head) { int newVertexCountCandidate = Math.Max(tail, head) + 1; if (newVertexCountCandidate > _vertexCount) { _vertexCount = newVertexCountCandidate; } var edge = new Endpoints(tail, head); _edges = ArrayPrefixBuilder.Add(_edges, edge, false); ++_edgeCount; if (tail != head) { var invertedEdge = new Endpoints(head, tail); _edges = ArrayPrefixBuilder.Add(_edges, invertedEdge, false); } return(edge); }