Esempio n. 1
0
 /// <summary>
 ///     Connects vertices in graph
 /// </summary>
 /// <param name="vertex1"></param>
 /// <param name="vertex2"></param>
 public void Connect(IVertex <T> vertex1, IVertex <T> vertex2)
 {
     if (vertex2.Equals(vertex1))
     {
         throw new ArgumentException("Cant connect vertice to itself");
     }
     if (this._vertices.Contains(vertex1) && this._vertices.Contains(vertex2))
     {
         if (vertex1.Contains(vertex2))
         {
             throw new ArgumentException("Vertices are already connected");
         }
         vertex1.Connect(vertex2);
         EdgesCount++;
     }
     else
     {
         throw new ArgumentException("Vertices must be in graph");
     }
 }
Esempio n. 2
0
        public static List <IVertex> Successors(this IVertex vertex)
        {
            List <IVertex> result = new List <IVertex>();

            foreach (IEdge edge in vertex.Links)
            {
                var linkedObjects = edge.GetLinkedObjects();
                if (linkedObjects.Count != 2)
                {
                    throw new ArgumentException("Edge relationship (parameter 2) is not binary.");
                }
                IVertex v1 = linkedObjects[0] as IVertex;
                IVertex v2 = linkedObjects[1] as IVertex;
                if (v1.Equals(vertex))
                {
                    result.Add(v2);
                }
            }

            return(result);
        }
        public List <Path> Dfs(IVertex src, IVertex dst)
        {
            if (src.Equals(dst))
            {
                return(new List <Path> {
                    new Path(this, new List <IEdge> {
                        new Edge(-1, src, src, 0)
                    })
                });
            }
            var lst   = new List <Path>();
            var queue = new Queue <QueueItem>();

            queue.Enqueue(new QueueItem(src, new List <IEdge>()));
            while (queue.Count > 0)
            {
                var currentItem = queue.Dequeue();
                foreach (var edge in currentItem.Node.Connectors)
                {
                    if (!currentItem.Visited.Contains(edge))
                    {
                        var visited = new List <IEdge>(currentItem.Visited)
                        {
                            edge
                        };
                        if (edge.V2 == dst)
                        {
                            lst.Add(new Path(this, visited));
                        }
                        else
                        {
                            queue.Enqueue(new QueueItem(edge.V2, visited));
                        }
                    }
                }
            }

            return(lst);
        }
        /// <summary>
        /// Return the predecessor vertices of a vertex following a given oriented binary relationship.
        /// </summary>
        /// <param name="vertex"></param>
        /// <param name="edgeType"></param>
        /// <returns></returns>
        public static List <IVertex> Predecessors(this IVertex vertex, OrientedBinaryEdgeTypeInfo edgeType)
        {
            List <IVertex> result = new List <IVertex>();

            foreach (IEdge edge in vertex.Links)
            {
                if (edge.TypeIdentity.Equals(edgeType))
                {
                    var linkedObjects = edge.GetLinkedObjects();
                    if (linkedObjects.Count != 2)
                    {
                        throw new ArgumentException("Edge relationship (parameter 2) is not binary.");
                    }
                    IVertex v1 = linkedObjects[0] as IVertex;
                    IVertex v2 = linkedObjects[1] as IVertex;
                    if (v2.Equals(vertex))
                    {
                        result.Add(v1);
                    }
                }
            }

            return(result);
        }
Esempio n. 5
0
        protected static void MergeVertexTo(INewGraph graph, IVertex from, IVertex to)
        {
            LogTool.AssertIsFalse(from.Equals(to));
            var fromNeighbors = graph.GetNeighborVertices(from as Common.IVertex).ToList();

            foreach (var n in fromNeighbors)
            {
                var e = graph.GetEdge(from as Common.IVertex, n);
                LogTool.AssertNotNull(e);
                graph.Remove(e);

                if (n.Equals(to))
                {
                    continue;
                }
                graph.AddEdge(n, to as Common.IVertex);
            }
            graph.Remove(from as Common.IVertex);

            foreach (var n in fromNeighbors)
            {
                UpdateEdgeCost(graph, n as IVertex);
            }
        }
Esempio n. 6
0
        public static List <IVertex> Search(IGraph myGraph, IVertex mySource, IVertex myTarget, Func <IVertex, bool> myMatchingFunc = null)
        {
            // queue for bfs
            var leftQueue  = new Queue <IVertex>();
            var rightQueue = new Queue <IVertex>();

            // store visited nodes in a hashset
            var visitedNodesLeft  = new HashSet <IVertex>();
            var visitedNodesRight = new HashSet <IVertex>();

            var doMatching = myMatchingFunc != null;

            IVertex intersectionVertex = null;

            // init the queue with the source vertex
            mySource[PREDECESSOR_ATTRIBUTE_KEY] = null;
            myTarget[SUCCESSOR_ATTRIBUTE_KEY]   = null;

            leftQueue.Enqueue(mySource);
            rightQueue.Enqueue(myTarget);

            visitedNodesLeft.Add(mySource);
            visitedNodesRight.Add(myTarget);

            IVertex currentLeftVertex  = null;
            IVertex currentRightVertex = null;

            List <IVertex> result = null;

            while (leftQueue.Count > 0 && rightQueue.Count > 0)
            {
                currentLeftVertex  = leftQueue.Dequeue();
                currentRightVertex = rightQueue.Dequeue();

                if (currentLeftVertex.Equals(myTarget))
                {
                    result = PathConcatenation.ConcatPath(myTarget, PREDECESSOR_ATTRIBUTE_KEY);
                    break;
                }
                else if (currentRightVertex.Equals(mySource))
                {
                    result = PathConcatenation.ConcatPath(mySource, PREDECESSOR_ATTRIBUTE_KEY, false);
                    break;
                }

                // check all children left
                foreach (var edge in currentLeftVertex.OutgoingEdges)
                {
                    if (!visitedNodesLeft.Contains(edge.Target))
                    {
                        edge.Target[PREDECESSOR_ATTRIBUTE_KEY] = currentLeftVertex;

                        if (doMatching)
                        {
                            if (myMatchingFunc(edge.Target))
                            {
                                leftQueue.Enqueue(edge.Target);
                                edge.Target[MATCHING_ATTRIBUTE_KEY] = true;
                            }
                            else
                            {
                                edge.Target[MATCHING_ATTRIBUTE_KEY] = false;
                            }
                        }
                        else
                        {
                            leftQueue.Enqueue(edge.Target);
                        }

                        visitedNodesLeft.Add(edge.Target);
                    }
                }

                // check all parents right
                foreach (var edge in currentRightVertex.IncomingEdges)
                {
                    if (!visitedNodesRight.Contains(edge.Source))
                    {
                        edge.Source[SUCCESSOR_ATTRIBUTE_KEY] = currentRightVertex;

                        if (doMatching)
                        {
                            if (myMatchingFunc(edge.Source))
                            {
                                rightQueue.Enqueue(edge.Source);
                                edge.Target[MATCHING_ATTRIBUTE_KEY] = true;
                            }
                            else
                            {
                                edge.Target[MATCHING_ATTRIBUTE_KEY] = false;
                            }
                        }
                        else
                        {
                            rightQueue.Enqueue(edge.Source);
                        }

                        visitedNodesRight.Add(edge.Source);
                    }
                }

                #region check intersect between visited nodes

                intersectionVertex = GetIntersectionVertex(visitedNodesLeft, visitedNodesRight, doMatching);

                if (intersectionVertex != null)
                {
                    // got a connection between the searches
                    List <IVertex> pathLeft  = null;
                    List <IVertex> pathRight = null;

                    if (intersectionVertex[PREDECESSOR_ATTRIBUTE_KEY].Equals(currentLeftVertex))
                    {
                        pathLeft  = PathConcatenation.ConcatPath(intersectionVertex, PREDECESSOR_ATTRIBUTE_KEY);
                        pathRight = PathConcatenation.ConcatPath((IVertex)intersectionVertex[SUCCESSOR_ATTRIBUTE_KEY], SUCCESSOR_ATTRIBUTE_KEY, false);
                    }
                    else
                    {
                        pathLeft  = PathConcatenation.ConcatPath((IVertex)intersectionVertex[PREDECESSOR_ATTRIBUTE_KEY], PREDECESSOR_ATTRIBUTE_KEY);
                        pathRight = PathConcatenation.ConcatPath(intersectionVertex, SUCCESSOR_ATTRIBUTE_KEY, false);
                    }

                    pathLeft.AddRange(pathRight);

                    result = pathLeft;
                    break;
                }

                #endregion
            }

            return(result);
        }
Esempio n. 7
0
 /// <summary>
 /// Compares vertices using <see cref="Vertex{T}.Data"/> property.
 /// </summary>
 /// <param name="x"></param>
 /// <param name="y"></param>
 /// <returns></returns>
 public bool Equals(IVertex <T> x, IVertex <T> y)
 {
     return(x.Equals(y.Data));
 }
Esempio n. 8
0
        /// <summary>
        /// Finds an efficiently directed path between specified start and destination(goal) vertices.
        /// </summary>
        /// <param name="p_start">The specific start of the search.</param>
        /// <param name="p_destination">The search destination.</param>
        /// <returns>The directed path between the specified start and destination, null if no such path exists.</returns>
        /// <remarks>
        /// <exception cref="ArgumentNullException">Start or destination is null.</exception>
        /// The A* search algorithm is known due its performance and accuracy.
        /// <para>
        /// https://en.wikipedia.org/wiki/A*_search_algorithm
        /// </para>
        /// </remarks>
        public IPath AStar(IVertex p_start, IVertex p_destination)
        {
            SearchResultPath                  rv               = null;
            IApproximations                   approxTable      = null;
            SearchVertex                      expanding        = null;         //current explored vertex
            IVertex                           expandingGVertex = null;         //current explored vertex of the graph(cache from object expanding)
            string                            expandingName    = string.Empty; //the name of the current explored vertex(cache from object expanding)
            Dictionary <string, byte>         visited          = null;         //Already visited vertices, we intersted in the key only.
            PriorityQueue <SearchVertex>      frontier         = null;
            Dictionary <string, SearchVertex> frontierLookup   = null;         //Quick search if expanded vertex is in the frontier already.
            SearchVertex                      goal             = null;

            if (null == p_start)
            {
                throw new ArgumentNullException("p_start", "Start vertex can not be null");
            }
            else if (null == p_destination)
            {
                throw new ArgumentNullException("p_destination", "Destination vertex can not be null");
            }


            if (p_start.Equals(p_destination))
            {
                goal = new SearchVertex(p_start, null, 0, 0);
            }
            else
            {
                approxTable    = m_graph.Approximations;
                frontier       = new MinPriorityQueue <SearchVertex>(m_graph.Vertices.Count);
                frontierLookup = new Dictionary <string, SearchVertex>();
                visited        = new Dictionary <string, byte>();

                //Initialize the frontier with our serach start
                SearchVertex start = new SearchVertex(p_start, null, 0, approxTable.GetH(p_start, p_destination));
                frontier.Enqueue(start);
                frontierLookup.Add(start.Name, start);

                //Let's roll ...
                while (!frontier.IsEmpty)
                {
                    //pick the best path so far, remove the vertex from the frontier and mark it as visited.
                    expanding        = frontier.Dequeue();
                    expandingGVertex = expanding.GraphVertex;
                    expandingName    = expandingGVertex.Name;
                    frontierLookup.Remove(expandingName);
                    visited.Add(expandingName, 0);

                    //Expand ...
                    foreach (IEdge e in expandingGVertex.OutEdges)
                    {
                        IVertex neighbor = e.Target;

                        if (null == neighbor)
                        {
                            continue; //Dead-end
                        }
                        else if (visited.ContainsKey(neighbor.Name))
                        {
                            continue; //We have been here before.
                        }

                        string neighborName = neighbor.Name;

                        SearchVertex discovery = new SearchVertex(neighbor, expanding, e.Weight, approxTable.GetH(neighbor, p_destination));

                        if (neighbor.Equals(p_destination))
                        {
                            //goal!!
                            if (null == goal)
                            {
                                goal = discovery;
                            }
                            else
                            {
                                if (discovery.Delta < goal.Delta)
                                {
                                    //Better path.
                                    goal = discovery;
                                }
                            }

                            continue;
                        }

                        if (frontierLookup.ContainsKey(neighborName))
                        {
                            //Still in the frontier.
                            SearchVertex exists = frontierLookup[neighborName];
                            if (discovery.Delta < exists.Delta)
                            {
                                frontier.Remove(exists);
                                frontierLookup.Remove(neighborName);

                                frontier.Enqueue(discovery);
                                frontierLookup.Add(discovery.Name, discovery);
                            }

                            continue;
                        }

                        //Don't bother if we have found a path and it is better that what we are still exploring.
                        if (null == goal || (null != goal && discovery.Delta < goal.Delta))
                        {
                            frontier.Enqueue(discovery);
                            frontierLookup.Add(discovery.Name, discovery);
                        }
                    } //foreach
                }     //while
            }         //start != destination

            if (null != goal)
            {
                rv = new SearchResultPath(goal);
            }

            return(rv);
        }