コード例 #1
0
        /// <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);
        }
コード例 #2
0
        /// <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);
        }
コード例 #3
0
        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
        }
コード例 #4
0
        /// <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;
        }
コード例 #5
0
        /// <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;
        }
コード例 #6
0
        /// <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;
        }
コード例 #7
0
        public void BigBitArrayConstructorUnitTest()
        {
            Assert.Inconclusive("TODO");

            var target = new BigBitArray();
        }