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
        }
Beispiel #2
0
        /// <summary>
        ///   Calculates the weight of this path element
        /// </summary>
        /// <param name="vertexCost"> The vertex cost delegate. </param>
        /// <param name="edgeCost"> The edge cost delegate </param>
        public virtual void CalculateWeight(PathDelegates.VertexCost vertexCost, PathDelegates.EdgeCost edgeCost)
        {
            Weight = 0;

            if (vertexCost != null)
            {
                Weight = vertexCost(TargetVertex);
            }

            if (edgeCost != null)
            {
                Weight += edgeCost(Edge);
            }
        }
        /// <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;
        }
Beispiel #6
0
        /// <summary>
        /// Get the valid edges of a vertex
        /// </summary>
        /// <param name="vertex">The vertex.</param>
        /// <param name="direction">The direction.</param>
        /// <param name="edgepropertyFilter">The edge property filter.</param>
        /// <param name="edgeFilter">The edge filter.</param>
        /// <param name="vertexFilter">The target vertex filter.</param>
        /// <returns>Valid edges</returns>
        public static List<Tuple<UInt16, IEnumerable<EdgeModel>>> GetValidEdges(
            VertexModel vertex,
            Direction direction,
            PathDelegates.EdgePropertyFilter edgepropertyFilter,
            PathDelegates.EdgeFilter edgeFilter,
            PathDelegates.VertexFilter vertexFilter)
        {
            var edgeProperties = direction == Direction.IncomingEdge ? vertex.GetIncomingEdges() : vertex.GetOutgoingEdges();
            var result = new List<Tuple<ushort, IEnumerable<EdgeModel>>>();

            if (edgeProperties != null)
            {
                foreach (var edgeContainer in edgeProperties)
                {
                    if (edgepropertyFilter != null && !edgepropertyFilter(edgeContainer.EdgePropertyId, direction))
                    {
                        continue;
                    }

                    if (edgeFilter != null)
                    {
                        var validEdges = new List<EdgeModel>();

                        for (var i = 0; i < edgeContainer.Edges.Count; i++)
                        {
                            var aEdge = edgeContainer.Edges[i];
                            if (edgeFilter(aEdge, direction))
                            {
                                if (vertexFilter != null)
                                {
                                    if (
                                        vertexFilter(direction == Direction.IncomingEdge
                                                         ? aEdge.SourceVertex
                                                         : aEdge.TargetVertex))
                                    {
                                        validEdges.Add(aEdge);
                                    }
                                }
                                else
                                {
                                    validEdges.Add(aEdge);
                                }
                            }
                        }
                        result.Add(new Tuple<ushort, IEnumerable<EdgeModel>>(edgeContainer.EdgePropertyId, validEdges));
                    }
                    else
                    {
                        if (vertexFilter != null)
                        {
                            var validEdges = new List<EdgeModel>();

                            for (var i = 0; i < edgeContainer.Edges.Count; i++)
                            {
                                var aEdge = edgeContainer.Edges[i];
                                if (
                                    vertexFilter(direction == Direction.IncomingEdge
                                                     ? aEdge.SourceVertex
                                                     : aEdge.TargetVertex))
                                {
                                    validEdges.Add(aEdge);
                                }
                            }
                            result.Add(new Tuple<ushort, IEnumerable<EdgeModel>>(edgeContainer.EdgePropertyId, validEdges));
                        }
                        else
                        {
                            result.Add(new Tuple<ushort, IEnumerable<EdgeModel>>(edgeContainer.EdgePropertyId, edgeContainer.Edges));
                        }
                    }
                }
            }

            return result;
        }
Beispiel #7
0
        public bool CalculateShortestPath(
            out List<Path> result,
            string algorithmname,
            Int32 sourceVertexId,
            Int32 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)
        {
            IShortestPathAlgorithm algo;
            if (PluginFactory.TryFindPlugin(out algo, algorithmname))
            {
                algo.Initialize(this, null);

                if (ReadResource())
                {
                    result = algo.Calculate(sourceVertexId, destinationVertexId, maxDepth, maxPathWeight, maxResults,
                                            edgePropertyFilter,
                                            vertexFilter, edgeFilter, edgeCost, vertexCost);

                    FinishReadResource();

                    return result != null && result.Count > 0;
                }

                throw new CollisionException();
            }

            result = null;
            return false;
        }