/// <summary> /// Gets the global frontier corresponding to a certain level /// </summary> /// <param name="startingVertices">The starting vertices behind the frontier</param> /// <param name="visitedVertices">The visited vertices corresponding to the frontier</param> /// <param name="edgepropertyFilter">The edge property filter</param> /// <param name="edgeFilter">The edge filter</param> /// <param name="vertexFilter">The vertex filter</param> /// <returns>The frontier vertices and their predecessors</returns> private static Dictionary <VertexModel, VertexPredecessor> GetGlobalFrontier(IEnumerable <VertexModel> startingVertices, BigBitArray visitedVertices, PathDelegates.EdgePropertyFilter edgepropertyFilter, PathDelegates.EdgeFilter edgeFilter, PathDelegates.VertexFilter vertexFilter) { var frontier = new Dictionary <VertexModel, VertexPredecessor>(); foreach (var aKv in startingVertices) { foreach (var aFrontierElement in GetLocalFrontier(aKv, visitedVertices, edgepropertyFilter, edgeFilter, vertexFilter)) { VertexPredecessor pred; if (frontier.TryGetValue(aFrontierElement.FrontierVertex, out pred)) { switch (aFrontierElement.EdgeDirection) { case Direction.IncomingEdge: pred.Incoming.Add(aFrontierElement.EdgeLocation); break; case Direction.OutgoingEdge: pred.Outgoing.Add(aFrontierElement.EdgeLocation); break; default: throw new ArgumentOutOfRangeException(); } } else { pred = new VertexPredecessor(); switch (aFrontierElement.EdgeDirection) { case Direction.IncomingEdge: pred.Incoming.Add(aFrontierElement.EdgeLocation); break; case Direction.OutgoingEdge: pred.Outgoing.Add(aFrontierElement.EdgeLocation); break; default: throw new ArgumentOutOfRangeException(); } frontier.Add(aFrontierElement.FrontierVertex, pred); } } } return(frontier); }
/// <summary> /// Gets the frontier elements on an incoming edge /// </summary> /// <param name="vertex">The vertex behind the frontier</param> /// <param name="edgepropertyFilter">The edge property filter</param> /// <param name="edgeFilter">The edge filter</param> /// <param name="vertexFilter">The vertex filter</param> /// <param name="alreadyVisited">The vertices that have been visited already</param> /// <returns>A number of frontier elements</returns> private static IEnumerable <FrontierElement> GetValidIncomingEdges( VertexModel vertex, PathDelegates.EdgePropertyFilter edgepropertyFilter, PathDelegates.EdgeFilter edgeFilter, PathDelegates.VertexFilter vertexFilter, BigBitArray alreadyVisited) { var edgeProperties = vertex.GetIncomingEdges(); var result = new List <FrontierElement>(); if (edgeProperties != null) { foreach (var edgeContainer in edgeProperties) { if (edgepropertyFilter != null && !edgepropertyFilter(edgeContainer.EdgePropertyId, Direction.IncomingEdge)) { continue; } if (edgeFilter != null) { for (var i = 0; i < edgeContainer.Edges.Count; i++) { var aEdge = edgeContainer.Edges[i]; if (edgeFilter(aEdge, Direction.IncomingEdge)) { if (alreadyVisited.SetValue(aEdge.SourceVertex.Id, true)) { if (vertexFilter != null) { if (vertexFilter(aEdge.SourceVertex)) { result.Add(new FrontierElement { EdgeDirection = Direction.IncomingEdge, EdgeLocation = new EdgeLocation { Edge = aEdge, EdgePropertyId = edgeContainer.EdgePropertyId }, FrontierVertex = aEdge.SourceVertex }); } } else { result.Add(new FrontierElement { EdgeDirection = Direction.IncomingEdge, EdgeLocation = new EdgeLocation { Edge = aEdge, EdgePropertyId = edgeContainer.EdgePropertyId }, FrontierVertex = aEdge.SourceVertex }); } } } } } else { if (vertexFilter != null) { for (var i = 0; i < edgeContainer.Edges.Count; i++) { var aEdge = edgeContainer.Edges[i]; if (alreadyVisited.SetValue(aEdge.SourceVertex.Id, true)) { if (vertexFilter(aEdge.SourceVertex)) { result.Add(new FrontierElement { EdgeDirection = Direction.IncomingEdge, EdgeLocation = new EdgeLocation { Edge = aEdge, EdgePropertyId = edgeContainer.EdgePropertyId }, FrontierVertex = aEdge.SourceVertex }); } } } } else { for (var i = 0; i < edgeContainer.Edges.Count; i++) { var aEdge = edgeContainer.Edges[i]; if (alreadyVisited.SetValue(aEdge.SourceVertex.Id, true)) { result.Add(new FrontierElement { EdgeDirection = Direction.IncomingEdge, EdgeLocation = new EdgeLocation { Edge = aEdge, EdgePropertyId = edgeContainer.EdgePropertyId }, FrontierVertex = aEdge.SourceVertex }); } } } } } } return(result); }
public List<Path> Calculate( int sourceVertexId, int destinationVertexId, Int32 maxDepth = 1, Double maxPathWeight = Double.MaxValue, Int32 maxResults = 1, PathDelegates.EdgePropertyFilter edgePropertyFilter = null, PathDelegates.VertexFilter vertexFilter = null, PathDelegates.EdgeFilter edgeFilter = null, PathDelegates.EdgeCost edgeCost = null, PathDelegates.VertexCost vertexCost = null) { #region initial checks VertexModel sourceVertex; VertexModel targetVertex; if (!(_fallen8.TryGetVertex(out sourceVertex, sourceVertexId) && _fallen8.TryGetVertex(out targetVertex, destinationVertexId))) { return null; } if (maxDepth == 0 || maxResults == 0 || maxResults <= 0) { return null; } if (ReferenceEquals(sourceVertex, targetVertex)) { return null; } #endregion #region data var sourceVisitedVertices = new BigBitArray(); sourceVisitedVertices.SetValue(sourceVertex.Id, true); var targetVisitedVertices = new BigBitArray(); targetVisitedVertices.SetValue(targetVertex.Id, true); #endregion #region maxdepth = 1 if (maxDepth == 1) { var depthOneFrontier = GetGlobalFrontier(new List<VertexModel> { sourceVertex }, sourceVisitedVertices, edgePropertyFilter, edgeFilter, vertexFilter); } #endregion #region maxdepth > 1 //find the middle element s-->m-->t Int32 sourceLevel = 0; Int32 targetLevel = 0; var sourceFrontiers = new List<Dictionary<VertexModel, VertexPredecessor>>(); var targetFrontiers = new List<Dictionary<VertexModel, VertexPredecessor>>(); Dictionary<VertexModel, VertexPredecessor> currentSourceFrontier = null; Dictionary<VertexModel, VertexPredecessor> currentTargetFrontier = null; IEnumerable<VertexModel> currentSourceVertices = new List<VertexModel> { sourceVertex }; IEnumerable<VertexModel> currentTargetVertices = new List<VertexModel> { targetVertex }; List<VertexModel> middleVertices = null; do { #region calculate frontier #region source --> target currentSourceFrontier = GetGlobalFrontier(currentSourceVertices, sourceVisitedVertices, edgePropertyFilter, edgeFilter, vertexFilter); sourceFrontiers.Add(currentSourceFrontier); currentSourceVertices = sourceFrontiers[sourceLevel].Keys; sourceLevel++; if (currentSourceFrontier.ContainsKey(targetVertex)) { if (middleVertices == null) { middleVertices = new List<VertexModel>{targetVertex}; } else { middleVertices.Add(targetVertex); } break; } if (FindMiddleVertices(out middleVertices, currentSourceFrontier, currentTargetFrontier)) break; if ((sourceLevel + targetLevel) == maxDepth) break; #endregion #region target --> source currentTargetFrontier = GetGlobalFrontier(currentTargetVertices, targetVisitedVertices, edgePropertyFilter, edgeFilter, vertexFilter); targetFrontiers.Add(currentTargetFrontier); currentTargetVertices = targetFrontiers[targetLevel].Keys; targetLevel++; if (currentTargetFrontier.ContainsKey(sourceVertex)) { if (middleVertices == null) { middleVertices = new List<VertexModel> { sourceVertex }; } else { middleVertices.Add(sourceVertex); } break; } if (FindMiddleVertices(out middleVertices, currentSourceFrontier, currentTargetFrontier)) break; if ((sourceLevel + targetLevel) == maxDepth) break; #endregion #endregion } while (true); return middleVertices != null ? CreatePaths(middleVertices, sourceFrontiers, targetFrontiers, maxResults, sourceLevel, targetLevel) : null; #endregion }
/// <summary> /// Gets the frontier elements on an outgoing edge /// </summary> /// <param name="vertex">The vertex behind the frontier</param> /// <param name="edgepropertyFilter">The edge property filter</param> /// <param name="edgeFilter">The edge filter</param> /// <param name="vertexFilter">The vertex filter</param> /// <param name="alreadyVisited">The vertices that have been visited already</param> /// <returns>A number of frontier elements</returns> private static IEnumerable<FrontierElement> GetValidOutgoingEdges( VertexModel vertex, PathDelegates.EdgePropertyFilter edgepropertyFilter, PathDelegates.EdgeFilter edgeFilter, PathDelegates.VertexFilter vertexFilter, BigBitArray alreadyVisited) { var edgeProperties = vertex.GetOutgoingEdges(); var result = new List<FrontierElement>(); if (edgeProperties != null) { foreach (var edgeContainer in edgeProperties) { if (edgepropertyFilter != null && !edgepropertyFilter(edgeContainer.EdgePropertyId, Direction.OutgoingEdge)) { continue; } if (edgeFilter != null) { for (var i = 0; i < edgeContainer.Edges.Count; i++) { var aEdge = edgeContainer.Edges[i]; if (edgeFilter(aEdge, Direction.OutgoingEdge)) { if (alreadyVisited.SetValue(aEdge.TargetVertex.Id, true)) { if (vertexFilter != null) { if (vertexFilter(aEdge.TargetVertex)) { result.Add(new FrontierElement { EdgeDirection = Direction.OutgoingEdge, EdgeLocation = new EdgeLocation { Edge = aEdge, EdgePropertyId = edgeContainer.EdgePropertyId }, FrontierVertex = aEdge.TargetVertex }); } } else { result.Add(new FrontierElement { EdgeDirection = Direction.OutgoingEdge, EdgeLocation = new EdgeLocation { Edge = aEdge, EdgePropertyId = edgeContainer.EdgePropertyId }, FrontierVertex = aEdge.TargetVertex }); } } } } } else { if (vertexFilter != null) { for (var i = 0; i < edgeContainer.Edges.Count; i++) { var aEdge = edgeContainer.Edges[i]; if (alreadyVisited.SetValue(aEdge.TargetVertex.Id, true)) { if (vertexFilter(aEdge.TargetVertex)) { result.Add(new FrontierElement { EdgeDirection = Direction.OutgoingEdge, EdgeLocation = new EdgeLocation { Edge = aEdge, EdgePropertyId = edgeContainer.EdgePropertyId }, FrontierVertex = aEdge.TargetVertex }); } } } } else { for (var i = 0; i < edgeContainer.Edges.Count; i++) { var aEdge = edgeContainer.Edges[i]; if (alreadyVisited.SetValue(aEdge.TargetVertex.Id, true)) { result.Add(new FrontierElement { EdgeDirection = Direction.OutgoingEdge, EdgeLocation = new EdgeLocation { Edge = aEdge, EdgePropertyId = edgeContainer.EdgePropertyId }, FrontierVertex = aEdge.TargetVertex }); } } } } } } return result; }
/// <summary> /// Gets the local frontier corresponding to a vertex /// </summary> /// <param name="vertex">The vertex behind the local frontier</param> /// <param name="alreadyVisitedVertices">The vertices that have been visited already</param> /// <param name="edgepropertyFilter">The edge property filter</param> /// <param name="edgeFilter">The edge filter</param> /// <param name="vertexFilter">The vertex filter</param> /// <returns>The local frontier</returns> private static IEnumerable<FrontierElement> GetLocalFrontier(VertexModel vertex, BigBitArray alreadyVisitedVertices, PathDelegates.EdgePropertyFilter edgepropertyFilter, PathDelegates.EdgeFilter edgeFilter, PathDelegates.VertexFilter vertexFilter) { var result = new List<FrontierElement>(); result.AddRange(GetValidIncomingEdges(vertex, edgepropertyFilter, edgeFilter, vertexFilter, alreadyVisitedVertices)); result.AddRange(GetValidOutgoingEdges(vertex, edgepropertyFilter, edgeFilter, vertexFilter, alreadyVisitedVertices)); return result; }
/// <summary> /// Gets the global frontier corresponding to a certain level /// </summary> /// <param name="startingVertices">The starting vertices behind the frontier</param> /// <param name="visitedVertices">The visited vertices corresponding to the frontier</param> /// <param name="edgepropertyFilter">The edge property filter</param> /// <param name="edgeFilter">The edge filter</param> /// <param name="vertexFilter">The vertex filter</param> /// <returns>The frontier vertices and their predecessors</returns> private static Dictionary<VertexModel, VertexPredecessor> GetGlobalFrontier(IEnumerable<VertexModel> startingVertices, BigBitArray visitedVertices, PathDelegates.EdgePropertyFilter edgepropertyFilter, PathDelegates.EdgeFilter edgeFilter, PathDelegates.VertexFilter vertexFilter) { var frontier = new Dictionary<VertexModel, VertexPredecessor>(); foreach (var aKv in startingVertices) { foreach (var aFrontierElement in GetLocalFrontier(aKv, visitedVertices, edgepropertyFilter, edgeFilter, vertexFilter)) { VertexPredecessor pred; if (frontier.TryGetValue(aFrontierElement.FrontierVertex, out pred)) { switch (aFrontierElement.EdgeDirection) { case Direction.IncomingEdge: pred.Incoming.Add(aFrontierElement.EdgeLocation); break; case Direction.OutgoingEdge: pred.Outgoing.Add(aFrontierElement.EdgeLocation); break; default: throw new ArgumentOutOfRangeException(); } } else { pred = new VertexPredecessor(); switch (aFrontierElement.EdgeDirection) { case Direction.IncomingEdge: pred.Incoming.Add(aFrontierElement.EdgeLocation); break; case Direction.OutgoingEdge: pred.Outgoing.Add(aFrontierElement.EdgeLocation); break; default: throw new ArgumentOutOfRangeException(); } frontier.Add(aFrontierElement.FrontierVertex, pred); } } } return frontier; }
public void BigBitArrayConstructorUnitTest() { Assert.Inconclusive("TODO"); var target = new BigBitArray(); }