public bool TryGetVertexAt( int index, out VertexAdjacency <TEdgeData> vertex) { if (ContainsVertexAt(index)) { vertex = this[index]; return(true); } vertex = default; return(false); }
/// <summary> /// Determines whether the specified vertices are equal. /// The vertices are equal if references are equal or if both vertices have the same number of adjacent edges and the second vertex /// contains all edges of the first one. /// Two edges are equal if destination vertices are equal and execution of <see cref=" IEqualityComparer{T}.Equals(T,T)" /> /// method for edges data of <paramref name="edgeDataComparer" /> returns <c>true</c>. /// </summary> /// <typeparam name="TEdgeData">The type of the edge data.</typeparam> /// <param name="source">The first vertex to compare.</param> /// <param name="other">The second vertex to compare.</param> /// <param name="edgeDataComparer">The edge data comparer.</param> /// <returns><c>true</c> if the specified vertices are equal; otherwise, <c>false</c>.</returns> public static bool IsEquivalent <TEdgeData>(this VertexAdjacency <TEdgeData> source, VertexAdjacency <TEdgeData> other, IEqualityComparer <TEdgeData> edgeDataComparer = null) { if (ReferenceEquals(source, other)) { return(true); } if (source == null || other == null) { return(false); } if (source.EdgesCount != other.EdgesCount) { return(false); } if (source.HasEmptyEdgeData()) { return(source.AdjacentIndexes.All(other.ContainsEdgeToIndex)); } edgeDataComparer ??= EqualityComparer <TEdgeData> .Default; foreach (var edgeTo in source) { if (!other.TryGetEdgeToIndex(edgeTo.Destination, out var edgeData) || !edgeDataComparer.Equals(edgeData, edgeTo.Data)) { return(false); } } return(true); }
/// <summary> /// Enumerates vertices to the last not empty vertex (trims the last empty vertices). /// Replaces all empty (in-between) vertices by the <paramref name="empty" /> instance. /// </summary> /// <typeparam name="T">The type of the vertex.</typeparam> /// <param name="source">The source of an extension of <see cref="IEnumerable{IVertex}" /> interface.</param> /// <param name="empty">The empty vertex.</param> /// <returns> /// Sequence of vertices without last empty ones. /// </returns> public static IEnumerable <VertexAdjacency <T> > TrimEmptyEnd <T>(this IEnumerable <VertexAdjacency <T> > source, VertexAdjacency <T> empty) { var emptyCount = 0; foreach (var item in source) { if (item.Count <= 0) { emptyCount++; } else { for (var idx = 0; idx < emptyCount; idx++) { yield return(empty); } emptyCount = 0; yield return(item); } } }
public GraphConnectivityDefinition <TTargetEdgeData> Create <TSrcEdgeData, TTargetEdgeData>( IReadOnlyList <VertexAdjacency <TSrcEdgeData> > sourceAdjacency, IVertexAdjacencyFactory <TTargetEdgeData> verticesFactory = null, Func <TSrcEdgeData, TTargetEdgeData> targetEdgeDataSelector = null, bool sharedVerticesInstances = false, IEqualityComparer <VertexAdjacency <TSrcEdgeData> > vertexEqualityComparer = null) { if (sourceAdjacency == null || sourceAdjacency.Count <= 0) { return(GetEmpty <TTargetEdgeData>()); } if (verticesFactory == null) { verticesFactory = new VertexAdjacencyFactory <TTargetEdgeData>(); } if (targetEdgeDataSelector == null) { if (EmptyValue.IsEmptyValueType <TTargetEdgeData>()) { targetEdgeDataSelector = _ => (TTargetEdgeData)(object)EmptyValue.Value; } else { if (!typeof(TTargetEdgeData).IsAssignableFrom(typeof(TSrcEdgeData))) { throw new ArgumentNullException(nameof(targetEdgeDataSelector), "Edge data selector can't be evaluated for specified types and must be defined."); } targetEdgeDataSelector = prev => (TTargetEdgeData)(object)prev; } } var oldVertices = sourceAdjacency; var destItemsCount = oldVertices.GetIndexOfLastNotEmptyVertex() + 1; var newVertices = new VertexAdjacency <TTargetEdgeData> [destItemsCount]; var oldToNewVertexInstanceMap = sharedVerticesInstances ? new Dictionary <VertexAdjacency <TSrcEdgeData>, VertexAdjacency <TTargetEdgeData> >( vertexEqualityComparer ?? VertexAdjacencyComparer <TSrcEdgeData> .DefaultWithHighestNumberOfEdgesFirst) : null; for (var idx = 0; idx < destItemsCount; idx++) { var oldVertex = oldVertices[idx]; VertexAdjacency <TTargetEdgeData> newVertex; if (oldToNewVertexInstanceMap != null) { if (!oldToNewVertexInstanceMap.TryGetValue(oldVertex, out newVertex)) { newVertex = verticesFactory.GetInstance( oldVertex.Select(e => AdjacentEdge.Create(e.Destination, targetEdgeDataSelector.Invoke(e.Data))), oldVertex.Count); oldToNewVertexInstanceMap.Add(oldVertex, newVertex); } } else { newVertex = verticesFactory.GetInstance( oldVertex.Select(e => AdjacentEdge.Create(e.Destination, targetEdgeDataSelector.Invoke(e.Data))), oldVertex.Count); } newVertices[idx] = newVertex; } return(CreateEmptyTailWrapperOf(newVertices, oldVertices.Count)); }
/// <summary>Determines whether the source vertex has empty edge data (of <see cref="EmptyValue"/> type).</summary> /// <typeparam name="TEdgeData">The type of the edge data.</typeparam> /// <param name="source">The source.</param> /// <returns><c>true</c> if the edge data is of <see cref="EmptyValue"/>; otherwise, <c>false</c>.</returns> public static bool HasEmptyEdgeData <TEdgeData>(this VertexAdjacency <TEdgeData> _) { return(EmptyValue.IsEmptyValueType <TEdgeData>()); }