Ejemplo n.º 1
0
        public TargetAnalyzer(Node myStart, Node myEnd, UInt64 myMaxPathLength)
        {
            _Paths = new HashSet<List<Tuple<long, long>>>();

            _Uninteresting = new HashSet<Tuple<long, long>>();

            _PathsLeft = new HashSet<List<Tuple<long, long>>>();
            _PathsRight = new HashSet<List<Tuple<long, long>>>();

            _TempList = new List<Tuple<long, long>>();

            _TempListLeft = new List<Tuple<long, long>>();
            _TempListRight = new List<Tuple<long, long>>();

            _Start = myStart;

            _End = myEnd;

            _MaxPathLength = Convert.ToInt16(myMaxPathLength);
            _MaxPartLengthLeft = 0;
            _MaxPartLengthRight = 0;
        }
Ejemplo n.º 2
0
        private bool getPath(Node myCurrent)
        {
            bool currentIsInteresting = false;

            if (!_TempList.Contains(myCurrent.Key))
            {
                if (!_Uninteresting.Contains<Tuple<long, long>>(myCurrent.Key))
                {
                    //add myCurrent to actual path
                    _TempList.Add(myCurrent.Key);

                    //set flag to mark that myCurrent is in actual path
                    myCurrent.AlreadyInPath = true;

                    //abort recursion when myCurrent is the root node
                    if (_Start.Key.Equals(myCurrent.Key))
                    {
                        currentIsInteresting = true;

                        //duplicate list
                        var temp = new List<Tuple<long, long>>(_TempList);

                        //reverse because the path is calculated beginning at the target
                        temp.Reverse();

                        //add completed path to result list
                        _Paths.Add(temp);
                    }
                    //MaxPathLength is not reached
                    else if (_TempList.Count < _MaxPathLength)
                    {
                        //for all parent nodes which are not already in actual path
                        foreach (Node parent in myCurrent.Parents)
                        {
                            //if currentIsInteresting already true doen't set to false
                            if (currentIsInteresting)
                                getPath(parent);
                            else
                                currentIsInteresting = getPath(parent);
                        }
                    }
                    else
                        currentIsInteresting = true;

                    if (_TempList.Count != 0)
                    {
                        //remove last node from actual path
                        _TempList.Remove(_TempList.Last<Tuple<long, long>>());

                        //myCurrent isn't in actual path
                        myCurrent.AlreadyInPath = false;
                    }

                    if (!currentIsInteresting)
                        _Uninteresting.Add(myCurrent.Key);
                }
            }
            else
                currentIsInteresting = true;

            return currentIsInteresting;
        }
Ejemplo n.º 3
0
        private bool VisitedByRightSide(Tuple<long, long> myTuple, ref Node myCurrentNodeLeft)
        {
            //get node
            Node temp = _VisitedNodesRight[myTuple];
            //add parent new
            temp.addParent(myCurrentNodeLeft);
            //add as child
            myCurrentNodeLeft.addChild(temp);

            _VisitedNodesRight.Remove(temp.Key);
            _VisitedNodesRight.Add(temp.Key, temp);

            if (_VisitedNodesLeft.Remove(temp.Key))
            {
                _VisitedNodesLeft.Add(temp.Key, temp);
            }

            if (_ShortestOnly && !_FindAll)
            {
                if ((_DepthLeft + _DepthRight + 1) > _MaxPathLength)
                {
                    _ShortestPathLength = _MaxPathLength;
                }
                else
                {
                    _ShortestPathLength = Convert.ToUInt64(_DepthLeft + _DepthRight + 1);
                }

                return true;
            }
            else if (_ShortestOnly && _FindAll)
            {
                _MaxDepthLeft = _DepthLeft;

                _ShortestPathLength = Convert.ToUInt64(_MaxDepthLeft + _MaxDepthRight);
            }

            return false;
        }
Ejemplo n.º 4
0
        private void UpdateVisitedRight(Tuple<long, long> myTuple, ref Node myNode)
        {
            //set found children
            _VisitedNodesRight[myTuple].addChild(myNode);

            myNode.addParent(_VisitedNodesRight[myTuple]);
        }
Ejemplo n.º 5
0
        private void UpdateVisitedLeft(Tuple<long, long> myTuple, ref Node myNode)
        {
            //set currentLeft as parent
            _VisitedNodesLeft[myTuple].addParent(myNode);

            //set currentNodeLeft as child
            myNode.addChild(_VisitedNodesLeft[myTuple]);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Checks if the search should be aborted.
        /// </summary>
        /// <param name="myTuple">the Tuple of the current Vertex.</param>
        /// <param name="myCurrentNode">The current Node.</param>
        /// <param name="myNextNode">The next Node.</param>
        /// <param name="myVertex">The actual Vertex.</param>
        /// <returns>True, if the target is found AND the BFS could be finished. False, if the BFS should be continued.</returns>
        private bool TargetFoundCheckAbort(Tuple<long, long> myTuple, ref Node myCurrentNode, ref Node myNextNode, IVertex myVertex)
        {
            if (myTuple.Equals(_Target.Key))
            {
                //set currentLeft as parent of _Target
                _Target.addParent(myCurrentNode);

                #region check if already visited
                if (_VisitedNodesLeft.ContainsKey(myTuple))
                {
                    //set currentLeft as parent
                    _VisitedNodesLeft[myTuple].addParent(myCurrentNode);

                    //set currentNodeLeft as child
                    myCurrentNode.addChild(_VisitedNodesLeft[myTuple]);
                }
                else
                {
                    //create a new node and set currentLeft = parent
                    myNextNode = new Node(myTuple, myCurrentNode);

                    //set currentNodeLeft as child of currentLeft
                    myCurrentNode.addChild(myNextNode);

                    //never seen before
                    //mark the node as visited
                    _VisitedNodesLeft.Add(myNextNode.Key, myNextNode);

                    //and put node into the queue
                    _QueueLeft.Enqueue(myVertex);
                }

                #endregion

                #region check how much parents are searched

                if (_ShortestOnly && !_FindAll)
                {
                    if ((_DepthLeft + _DepthRight + 1) > _MaxPathLength)
                    {
                        _ShortestPathLength = _MaxPathLength;
                    }
                    else
                    {
                        _ShortestPathLength = Convert.ToUInt64(_DepthLeft + _DepthRight + 1);
                    }

                    return true;
                }
                //if find all shortest paths
                else if (_ShortestOnly && _FindAll)
                {
                    //set maxDepth to actual depth
                    _MaxDepthLeft = _DepthLeft;
                    _MaxDepthRight = _DepthRight;

                    if ((_DepthLeft + _DepthRight) > _MaxPathLength)
                    {
                        _ShortestPathLength = _MaxPathLength;
                    }
                    else
                    {
                        _ShortestPathLength = Convert.ToUInt64(_DepthLeft + _DepthRight);
                    }
                }

                #endregion
            }

            return false;
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Fügt dem Knoten ein Parent hinzu, existiert dieser schon, werden die Parents und Children des existierenden aktualisiert.
        /// </summary>
        /// <param name="myParent">Parent welcher hinzugefügt werden soll.</param>
        /// <returns></returns>
        public bool addParent(Node myParent)
        {
            bool equal = false;

            foreach (var thisParent in _Parents)
            {
                //check if the node wich should be added IS already existing
                if (thisParent.Equals(myParent))
                {
                    //exists
                    equal = true;

                    break;
                }
            }

            //node is NOT already existing, add
            if (!equal)
            {
                return _Parents.Add(myParent);
            }

            return false;
        }
Ejemplo n.º 8
0
 public TargetAnalyzer(Node myStart, Node myEnd, UInt64 myMaxPathLength, bool myShortestOnly, bool myFindAll)
     : this(myStart, myEnd, myMaxPathLength)
 {
     _ShortestOnly = myShortestOnly;
     _FindAll = myFindAll;
 }
Ejemplo n.º 9
0
        private bool RootFoundCheckAbort(Tuple<long, long> myTuple, ref Node myCurrentNode, ref Node myNextNode, IVertex myVertex)
        {
            #region check if already visited
            //mark node as visited
            if (_VisitedNodesRight.ContainsKey(myTuple))
            {
                //set found children
                _VisitedNodesRight[myTuple].addChild(myCurrentNode);

                myCurrentNode.addParent(_VisitedNodesRight[myTuple]);
            }
            else
            {
                //create a new node and set currentRight = child
                myNextNode = new Node(myTuple);
                myNextNode.addChild(myCurrentNode);

                //set currentNodeRight as parent of current Right
                myCurrentNode.addParent(myNextNode);

                //never seen before
                //mark the node as visited
                _VisitedNodesRight.Add(myNextNode.Key, myNextNode);

                //and look what comes on the next level of depth
                _QueueRight.Enqueue(myVertex);
            }

            #endregion check if already visited
            #region check how much paths are searched

            if (_ShortestOnly && !_FindAll)
            {
                if ((_DepthLeft + _DepthRight + 1) > _MaxPathLength)
                {
                    _ShortestPathLength = _MaxPathLength;
                }
                else
                {
                    _ShortestPathLength = Convert.ToUInt64(_DepthLeft + _DepthRight + 1);
                }

                return true;
            }
            //if find all shortest paths
            else if (_ShortestOnly && _FindAll)
            {
                //set maxDepth to actual depth
                _MaxDepthLeft = _DepthLeft;
                _MaxDepthRight = _DepthRight;

                if ((_DepthLeft + _DepthRight) > _MaxPathLength)
                {
                    _ShortestPathLength = _MaxPathLength;
                }
                else
                {
                    _ShortestPathLength = Convert.ToUInt64(_DepthLeft + _DepthRight);
                }
            }
            #endregion check how much paths are searched

            return false;
        }
Ejemplo n.º 10
0
        private HashSet<List<Tuple<long, long>>> CheckNextVerticesOfRightSide(ref IVertex myCurrentVertexRight, ref Node myCurrentNodeRight)
        {
            //get all referenced ObjectUUIDs using the given Edge
            var rightVertices = GetIncomingVertices(myCurrentVertexRight);

            #region check right friends
            foreach (var nextRightVertex in rightVertices)
            {
                Node nextRightNode = null;
                Tuple<long, long> nextRight = new Tuple<long, long>(nextRightVertex.VertexTypeID, nextRightVertex.VertexID);

                #region if the child is the _Target
                if (_Root.Key.Equals(nextRight))
                {
                    if (RootFoundCheckAbort(nextRight, ref myCurrentNodeRight, ref nextRightNode, nextRightVertex))
                        return new TargetAnalyzer(_Root, _Target, _ShortestPathLength, _ShortestOnly, _FindAll).GetPaths();
                }
                #endregion if the child is the _Target
                #region already visited from right side
                else if (_VisitedNodesLeft.ContainsKey(nextRight))
                {
                    if (VisitedByLeftSide(nextRight, ref myCurrentNodeRight))
                        return new TargetAnalyzer(_Root, _Target, _ShortestPathLength, _ShortestOnly, _FindAll).GetPaths();
                }
                #endregion already visited from left side
                #region already visited
                else if (_VisitedNodesRight.ContainsKey(nextRight))
                {
                    UpdateVisitedRight(nextRight, ref myCurrentNodeRight);
                }
                #endregion already visited
                #region set as visited
                else
                {
                    SetAsVisitedRight(nextRight, ref myCurrentNodeRight, ref nextRightNode, nextRightVertex);
                }
                #endregion set as visited
            }
            #endregion check right friends

            return null;
        }
Ejemplo n.º 11
0
        private HashSet<List<Tuple<long, long>>> CheckNextVerticesOfLeftSide(ref IVertex myCurrentVertexLeft, ref Node myCurrentNodeLeft)
        {
            //get all referenced ObjectUUIDs using the given Edge
            var leftVertices = myCurrentVertexLeft.GetOutgoingEdge(_AttributeDefinition.ID).GetTargetVertices();

            #region check left friends
            foreach (var nextLeftVertex in leftVertices)
            {
                Node nextLeftNode = null;
                Tuple<long, long> nextLeft = new Tuple<long, long>(nextLeftVertex.VertexTypeID, nextLeftVertex.VertexID);

                #region if the child is the _Target
                if (nextLeft.Equals(_Target.Key))
                {
                    if (TargetFoundCheckAbort(nextLeft, ref myCurrentNodeLeft, ref nextLeftNode, nextLeftVertex))
                        return new TargetAnalyzer(_Root, _Target, _ShortestPathLength, _ShortestOnly, _FindAll).GetPaths();
                }
                #endregion
                #region already visited from right side
                else if (_VisitedNodesRight.ContainsKey(nextLeft))
                {
                    if (VisitedByRightSide(nextLeft, ref myCurrentNodeLeft))
                        return new TargetAnalyzer(_Root, _Target, _ShortestPathLength, _ShortestOnly, _FindAll).GetPaths();
                }
                #endregion already visited from right side
                #region already visited
                else if (_VisitedNodesLeft.ContainsKey(nextLeft))
                {
                    UpdateVisitedLeft(nextLeft, ref myCurrentNodeLeft);
                }
                #endregion already visited
                #region set as visited
                else
                {
                    SetAsVisitedLeft(nextLeft, ref myCurrentNodeLeft, ref nextLeftNode, nextLeftVertex);
                }
                #endregion set as visited
            }
            #endregion check left friends

            return null;
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Please look at the class documentation for detailed description how this algorithm works.
        /// </summary>
        /// <param name="myTypeAttribute">The Attribute representing the edge to follow (p.e. "Friends")</param>
        /// <param name="myVertexType">The type of the start node.</param>
        /// <param name="myStart">The start node</param>
        /// <param name="myEnd">The end node</param>
        /// <param name="shortestOnly">true, if only shortest path shall be found</param>
        /// <param name="findAll">if true and shortestOnly is true, all shortest paths will be found. 
        /// If true, and shortest only is false, all paths will be searched</param>
        /// <param name="myMaxDepth">The maximum depth to search</param>
        /// <param name="myMaxPathLength">The maximum path length which shall be analyzed</param>
        /// <returns>A HashSet which contains all found paths. Every path is represented by a List of ObjectUUIDs</returns>m>
        public HashSet<List<Tuple<long, long>>> Find(IAttributeDefinition myTypeAttribute,
            IVertexType myVertexType,
            IVertex myStart,
            IVertex myEnd,
            bool shortestOnly,
            bool findAll,
            UInt64 myMaxDepth,
            UInt64 myMaxPathLength)
        {
            #region declarations

            //set current depth
            _DepthLeft = 1;
            _DepthRight = 1;

            //maximum depth
            _MaxDepthLeft = 0;
            _MaxDepthRight = 0;

            _MaxPathLength = myMaxPathLength;

            #region initialize maxDepths

            //if the maxDepth is greater then maxPathLength, then set maxDepth to maxPathLength
            if (myMaxDepth > _MaxPathLength)
                myMaxDepth = _MaxPathLength;
            else if (_MaxPathLength > myMaxDepth)
                _MaxPathLength = myMaxDepth;

            //set depth for left side
            _MaxDepthLeft = Convert.ToUInt64(myMaxDepth / 2 + 1);

            //if myMaxDepth is 1 _MaxDepthRight keeps 0, just one side is searching
            if (myMaxDepth > 1)
                //both sides have the same depth
                _MaxDepthRight = _MaxDepthLeft;

            //if myMaxDepth is even, one side has to search in a greater depth
            if ((myMaxDepth % 2) == 0)
                _MaxDepthRight = Convert.ToUInt64(_MaxDepthLeft - 1);

            #endregion

            //shortest path length
            _ShortestPathLength = 0;

            //_Target node, the _Target of the select
            _Target = new Node(myEnd.VertexTypeID, myEnd.VertexID);
            _Root = new Node(myStart.VertexTypeID, myStart.VertexID);

            //the attribute (edge) which is used for the search
            _AttributeDefinition = myTypeAttribute;

            //search the type on which the attribute is defined
            IVertexType current = myVertexType;
            List<IVertexType> tempList = new List<IVertexType>();
            tempList.Add(current);

            bool foundDefinedType = false;

            while (current.HasParentType && !foundDefinedType)
            {
                if (current.ParentVertexType.HasAttribute(_AttributeDefinition.Name))
                {
                    foundDefinedType = true;
                }

                current = current.ParentVertexType;
                tempList.Add(current);
            }

            if (foundDefinedType)
                _Types = tempList;
            else
                _Types.Add(myVertexType);

            //dummy node to check in which level the BFS is
            _DummyLeft = null;
            _DummyRight = null;

            _FindAll = findAll;
            _ShortestOnly = shortestOnly;

            #endregion

            #region BidirectionalBFS
            //check if the EdgeType is ASetReferenceEdgeType

            #region initialize variables

            //enqueue start node to start from left side
            _QueueLeft.Enqueue(myStart);
            //enqueue _DummyLeft to analyze the depth of the left side
            _QueueLeft.Enqueue(_DummyLeft);

            //enqueue _Target node to start from right side
            _QueueRight.Enqueue(myEnd);
            //enqueue _DummyRight to analyze the depth of the right side
            _QueueRight.Enqueue(_DummyRight);

            //add _Root and _Target to visitedNodes
            _VisitedNodesLeft.Add(_Root.Key, _Root);
            _VisitedNodesRight.Add(_Target.Key, _Target);

            #endregion

            #region check if start has outgoing and _Target has incoming edge

            //check that the start node has the outgoing edge and the target has incoming vertices
            if (!myStart.HasOutgoingEdge(_AttributeDefinition.ID) && !HasIncomingVertices(myEnd))
            {
                return null;
            }

            #endregion

            //if there is more than one object in the queue and the actual depth is less than MaxDepth
            while (((_QueueLeft.Count > 0) && (_QueueRight.Count > 0)) &&
                   ((_DepthLeft <= _MaxDepthLeft) || (_DepthRight <= _MaxDepthRight)))
            {
                #region both queues contain objects and both depths are not reached
                if (((_QueueLeft.Count > 0) && (_QueueRight.Count > 0)) &&
                    ((_DepthLeft <= _MaxDepthLeft) && (_DepthRight <= _MaxDepthRight)))
                {
                    #region check if a level is completely searched

                    if (LeftLevelCompleted())
                        continue;

                    if (RightLevelCompleted())
                        continue;

                    #endregion check if there is a dummyNode at the beginning of a queue

                    #region get first nodes of the queues

                    //hold the actual element of the queues
                    Node currentNodeLeft;
                    Node currentNodeRight;

                    IVertex currentVertexLeft;
                    IVertex currentVertexRight;

                    Tuple<long, long> currentLeft;
                    Tuple<long, long> currentRight;

                    //get the first Object of the queue
                    currentVertexLeft = _QueueLeft.Dequeue();
                    currentLeft = new Tuple<long, long>(currentVertexLeft.VertexTypeID,
                                                        currentVertexLeft.VertexID);

                    if (_VisitedNodesLeft.ContainsKey(currentLeft))
                        currentNodeLeft = _VisitedNodesLeft[currentLeft];
                    else
                        currentNodeLeft = new Node(currentLeft);

                    //get the first Object of the queue
                    currentVertexRight = _QueueRight.Dequeue();
                    currentRight = new Tuple<long, long>(currentVertexRight.VertexTypeID,
                                                            currentVertexRight.VertexID);

                    if (_VisitedNodesRight.ContainsKey(currentRight))
                        currentNodeRight = _VisitedNodesRight[currentRight];
                    else
                        currentNodeRight = new Node(currentRight);

                    #endregion

                    #region the edge and the backwardedge are existing
                    if (currentVertexLeft.HasOutgoingEdge(_AttributeDefinition.ID)
                        && HasIncomingVertices(currentVertexRight))
                    {
                        //get all referenced ObjectUUIDs using the given Edge
                        var leftVertices = currentVertexLeft.GetOutgoingEdge(_AttributeDefinition.ID).GetTargetVertices();

                        #region check left friends
                        foreach (var nextLeftVertex in leftVertices)
                        {
                            Node nextLeftNode = null;
                            Tuple<long, long> nextLeft = new Tuple<long, long>(nextLeftVertex.VertexTypeID, nextLeftVertex.VertexID);

                            #region if the child is the _Target
                            if (nextLeft.Equals(_Target.Key))
                            {
                                if (TargetFoundCheckAbort(nextLeft, ref currentNodeLeft, ref nextLeftNode, nextLeftVertex))
                                    return new TargetAnalyzer(_Root, _Target, _ShortestPathLength, _ShortestOnly, _FindAll).GetPaths();
                            }
                            #endregion
                            #region already visited
                            else if (_VisitedNodesLeft.ContainsKey(nextLeft))
                            {
                                UpdateVisitedLeft(nextLeft, ref currentNodeLeft);
                            }
                            #endregion already visited
                            #region set as visited
                            else
                            {
                                SetAsVisitedLeft(nextLeft, ref currentNodeLeft, ref nextLeftNode, nextLeftVertex);
                            }
                            #endregion set as visited
                        }
                        #endregion check left friends

                        //get all referenced ObjectUUIDs using the given Edge
                        var rightVertices = GetIncomingVertices(currentVertexRight);

                        #region check right friends
                        foreach (var nextRightVertex in rightVertices)
                        {
                            Node nextRightNode = null;
                            Tuple<long, long> nextRight = new Tuple<long, long>(nextRightVertex.VertexTypeID, nextRightVertex.VertexID);

                            #region if the child is the _Target
                            if (_Root.Key.Equals(nextRight))
                            {
                                if (RootFoundCheckAbort(nextRight, ref currentNodeRight, ref nextRightNode, nextRightVertex))
                                    return new TargetAnalyzer(_Root, _Target, _ShortestPathLength, _ShortestOnly, _FindAll).GetPaths();
                            }
                            #endregion if the child is the _Target
                            #region already visited
                            else if (_VisitedNodesRight.ContainsKey(nextRight))
                            {
                                UpdateVisitedRight(nextRight, ref currentNodeRight);
                            }
                            #endregion already visited
                            #region set as visited
                            else
                            {
                                SetAsVisitedRight(nextRight, ref currentNodeRight, ref nextRightNode, nextRightVertex);
                            }
                            #endregion set as visited
                        }
                        #endregion check right friends

                        #region build intersection of _VisitedNodesLeft and _VisitedNodesRight
                        //marks if intersection nodes are existing
                        bool foundIntersect = false;

                        foreach (var node in _VisitedNodesLeft)
                        {
                            if (_VisitedNodesRight.ContainsKey(node.Key))
                            {
                                //set nodes children and parents
                                node.Value.addChildren(_VisitedNodesRight[node.Key].Children);
                                node.Value.addParents(_VisitedNodesRight[node.Key].Parents);

                                //set nodes children and parents
                                _VisitedNodesRight[node.Key].addChildren(node.Value.Children);
                                _VisitedNodesRight[node.Key].addParents(node.Value.Parents);

                                _IntersectNodes.Add(_VisitedNodesRight[node.Key]);

                                foundIntersect = true;
                            }
                        }
                        #endregion build intersection of _VisitedNodesLeft and _VisitedNodesRight

                        #region analyze intersection
                        //if intersection nodes existing
                        if (foundIntersect)
                        {
                            //only shortest path
                            if (_ShortestOnly && !_FindAll)
                            {
                                if ((_DepthLeft + _DepthRight + 1) > _MaxPathLength)
                                {
                                    _ShortestPathLength = _MaxPathLength;
                                }
                                else
                                {
                                    _ShortestPathLength = Convert.ToUInt64(_DepthLeft + _DepthRight + 1);
                                }

                                //return new TargetAnalyzer(_Root, _Target, _ShortestPathLength, _ShortestOnly, _FindAll).GetPaths();
                                return new TargetAnalyzer(_Root, _Target, _ShortestPathLength, _ShortestOnly, _FindAll)
                                            .GetShortestPath(_IntersectNodes);
                            }
                            //if find all shortest paths
                            else if (_ShortestOnly && _FindAll)
                            {
                                //set maxDepth to actual depth
                                _MaxDepthLeft = _DepthLeft;
                                _MaxDepthRight = _DepthRight;

                                if ((_DepthLeft + _DepthRight + 1) > _MaxPathLength)
                                {
                                    _ShortestPathLength = _MaxPathLength;
                                }
                                else if (_ShortestPathLength == 0)
                                {
                                    _ShortestPathLength = Convert.ToUInt64(_DepthLeft + _DepthRight + 1);
                                }

                            }
                        }
                        #endregion analyze intersection
                    }
                    #endregion the edge and the backwardedge are existing
                    #region only the edge exists
                    else if (currentVertexLeft.HasOutgoingEdge(_AttributeDefinition.ID))
                    {
                        var result = CheckNextVerticesOfLeftSide(ref currentVertexLeft, ref currentNodeLeft);

                        if (result != null)
                            return result;
                    }
                    #endregion only the edge exists
                    #region only the backwardedge exists
                    else if (HasIncomingVertices(currentVertexRight))
                    {
                        var result = CheckNextVerticesOfRightSide(ref currentVertexRight, ref currentNodeRight);

                        if (result != null)
                            return result;
                    }
                    #endregion only the backwardedge exists
                }
                #endregion  both queues contain objects and both depths are not reached
                #region only left queue contain objects
                else if ((_QueueLeft.Count > 0) && (_DepthLeft <= _MaxDepthLeft))
                {
                    #region check if first element of queue is a dummy

                    if (LeftLevelCompleted())
                        continue;

                    #endregion check if first element of queue is a dummy

                    #region get first nodes of the queues

                    //hold the actual element of the queues
                    Node currentNodeLeft;
                    IVertex currentVertexLeft;

                    //get the first Object of the queue
                    currentVertexLeft = _QueueLeft.Dequeue();
                    Tuple<long, long> currentLeft = new Tuple<long, long>(currentVertexLeft.VertexTypeID, currentVertexLeft.VertexID);

                    if (_VisitedNodesLeft.ContainsKey(currentLeft))
                        continue;

                    if (_VisitedNodesLeft.ContainsKey(currentLeft))
                        currentNodeLeft = _VisitedNodesLeft[currentLeft];
                    else
                        currentNodeLeft = new Node(currentLeft);

                    #endregion

                    #region check next vertices

                    if (currentVertexLeft.HasOutgoingEdge(_AttributeDefinition.ID))
                    {
                        var result = CheckNextVerticesOfLeftSide(ref currentVertexLeft, ref currentNodeLeft);

                        if (result != null)
                            return result;
                    }

                    #endregion
                }
                #endregion only left queue contain objects
                #region only right queue contain objects
                else if ((_QueueRight.Count > 0) && (_DepthRight <= _MaxDepthRight))
                {
                    #region check if first element of the queue is a dummy

                    if (RightLevelCompleted())
                        continue;

                    #endregion check if first element of the queue is a dummy

                    #region get first nodes of the queues

                    //hold the actual element of the queues
                    Node currentNodeRight;
                    IVertex currentVertexRight;

                    //get the first Object of the queue
                    currentVertexRight = _QueueRight.Dequeue();
                    Tuple<long, long> currentRight = new Tuple<long, long>(currentVertexRight.VertexTypeID, currentVertexRight.VertexID);

                    if (_VisitedNodesRight.ContainsKey(currentRight))
                        continue;

                    if (_VisitedNodesRight.ContainsKey(currentRight))
                        currentNodeRight = _VisitedNodesRight[currentRight];
                    else
                        currentNodeRight = new Node(currentRight);

                    #endregion

                    #region check next vertices

                    if (HasIncomingVertices(currentVertexRight))
                    {
                        var result = CheckNextVerticesOfRightSide(ref currentVertexRight, ref currentNodeRight);

                        if (result != null)
                            return result;
                    }

                    #endregion
                }
                #endregion only right queue contain objects
                #region abort loop

                else
                    break;

                #endregion abort loop
            }

            #region nothing found
            if (_ShortestOnly && !_FindAll)
                return null;
            #endregion

            //get result paths
            #region start TargetAnalyzer
            if (_ShortestOnly && _FindAll)
            {
                if (_ShortestPathLength > _MaxPathLength)
                {
                    _ShortestPathLength = _MaxPathLength;
                }

                return new TargetAnalyzer(_Root, _Target, _ShortestPathLength, _ShortestOnly, _FindAll).GetPaths();
            }
            else
            {
                return new TargetAnalyzer(_Root, _Target, _MaxPathLength, _ShortestOnly, _FindAll).GetPaths();
            }
            #endregion start TargetAnalyzer

            #endregion BidirectionalBFS
        }
Ejemplo n.º 13
0
 public Node(Tuple<long, long> myKey, Node myParent)
     : this(myKey.Item1, myKey.Item2)
 {
     _Parents.Add(myParent);
 }
Ejemplo n.º 14
0
 public Node(long myTypeID, long myVertexID, Node myParent)
     : this(myTypeID, myVertexID)
 {
     _Parents.Add(myParent);
 }
Ejemplo n.º 15
0
        private void getShortestPathUpwards(Node myCurrent)
        {
            if (!_TempListRight.Contains(myCurrent.Key) && !foundRight)
            {
                //add myCurrent to actual path
                _TempListRight.Add(myCurrent.Key);

                //set flag to mark that myCurrent is in actual path
                myCurrent.AlreadyInPath = true;

                //abort recursion when myCurrent is the root node
                if (_Start.Key.Equals(myCurrent.Key) &&
                    _TempListRight.Count <= _MaxPartLengthRight)
                {
                    //duplicate list
                    var temp = new List<Tuple<long, long>>(_TempListRight);

                    //actualize the max part length
                    _MaxPartLengthRight = temp.Count;

                    _PathsRight.Add(temp);

                    if (_ShortestOnly)
                        foundRight = true;
                }
                //MaxPathLength is not reached
                else if (_TempListRight.Count <= _MaxPartLengthRight)
                    //for all parent nodes which are not already in actual path
                    foreach (Node parent in myCurrent.Parents.Where(_ => !_.AlreadyInPath))
                    {
                        getShortestPathUpwards(parent);
                    }

                if (_TempListRight.Count != 0)
                {
                    //remove last node from actual path
                    _TempListRight.Remove(_TempListRight.Last<Tuple<long, long>>());

                    //myCurrent isn't in actual path
                    myCurrent.AlreadyInPath = false;
                }
            }
            return;
        }
Ejemplo n.º 16
0
        private void SetAsVisitedLeft(Tuple<long, long> myTuple, ref Node myCurrentNode, ref Node myNextNode, IVertex myVertex)
        {
            //create a new node
            myNextNode = new Node(myTuple, myCurrentNode);

            //set currentNode
            myCurrentNode.addChild(myNextNode);

            //never seen before
            //mark the node as visited
            //_VisitedNodesLeft.Add(currentNodeLeft.Key, currentNodeLeft);
            _VisitedNodesLeft.Add(myNextNode.Key, myNextNode);

            //and put node into the queue
            _QueueLeft.Enqueue(myVertex);
        }
Ejemplo n.º 17
0
        private void SetAsVisitedRight(Tuple<long, long> myTuple, ref Node myCurrentNode, ref Node myNextNode, IVertex myVertex)
        {
            //create a new node and set currentRight = child
            myNextNode = new Node(myTuple);
            myNextNode.addChild(myCurrentNode);

            //set currentNodeRight as parent of current Right
            myCurrentNode.addParent(myNextNode);

            //never seen before
            //mark the node as visited
            _VisitedNodesRight.Add(myNextNode.Key, myNextNode);

            //and look what comes on the next level of depth
            _QueueRight.Enqueue(myVertex);
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Searches shortest, all shortest or all paths starting from "myStart" to "myEnd".
        /// </summary>
        /// <param name="myTypeAttribute">The Attribute representing the edge to follow (p.e. "Friends")</param>
        /// <param name="myTypeManager">The TypeManager for the Node type</param>
        /// <param name="myDBObjectCache">The Object Cache for faster object lookup</param>
        /// <param name="myStart">The start node</param>
        /// <param name="myEnd">The end node</param>
        /// <param name="shortestOnly">true, if only shortest path shall be found</param>
        /// <param name="findAll">if true and shortestOnly is true, all shortest paths will be found. if true, and shortest only is false, all paths will be searched</param>
        /// <param name="myMaxDepth">The maximum depth to search</param>
        /// <param name="myMaxPathLength">The maximum path length which shall be analyzed</param>
        /// <returns>A HashSet which contains all found paths. Every path is represented by a List of ObjectUUIDs</returns>
        public HashSet<List<Tuple<long, long>>> Find(IAttributeDefinition myTypeAttribute, 
            IVertexType myVertexType,
            IVertex myStart,
            IVertex myEnd,
            bool shortestOnly,
            bool findAll,
            UInt64 myMaxDepth,
            UInt64 myMaxPathLength)
        {
            #region data

            //queue for BFS
            Queue<IVertex> queue = new Queue<IVertex>();

            //Dictionary to store visited TreeNodes
            Dictionary<Tuple<long, long>, Node> visitedNodes = new Dictionary<Tuple<long, long>, Node>();

            HashSet<Tuple<long, long>> visitedVertices = new HashSet<Tuple<long, long>>();

            //current depth
            UInt64 depth = 1;

            //first node in path tree, the start of the select
            Node root = new Node(myStart.VertexTypeID, myStart.VertexID);

            //target node, the target of the select
            Node target = new Node(myEnd.VertexTypeID, myEnd.VertexID);

            //dummy node to check in which level the BFS is
            IVertex dummy = null;

            //if the maxDepth is greater then maxPathLength, then set maxDepth to maxPathLength
            if (myMaxDepth > myMaxPathLength)
                myMaxDepth = myMaxPathLength;
            else if (myMaxPathLength > myMaxDepth)
                myMaxPathLength = myMaxDepth;

            //enqueue first node to start the BFS
            queue.Enqueue(myStart);
            queue.Enqueue(dummy);

            //add root to visitedNodes
            visitedNodes.Add(root.Key, root);

            //search the type on which the attribute is defined
            IVertexType currentType = myVertexType;
            List<IVertexType> tempList = new List<IVertexType>();
            tempList.Add(currentType);

            bool foundDefinedType = false;

            while (currentType.HasParentType && !foundDefinedType)
            {
                if (currentType.ParentVertexType.HasAttribute(myTypeAttribute.Name))
                {
                    foundDefinedType = true;
                }

                currentType = currentType.ParentVertexType;
                tempList.Add(currentType);
            }

            if (foundDefinedType)
                _Types = tempList;
            else
                _Types.Add(myVertexType);

            #endregion

            #region BFS

            //check that the start node has the outgoing edge and the target has incoming vertices
            if (!myStart.HasOutgoingEdge(myTypeAttribute.ID) && !HasIncomingVertices(myEnd, myTypeAttribute.ID))
            {
                return null;
            }

            //if there is more than one object in the queue and the actual depth is less than MaxDepth
            while ((queue.Count > 0) && (depth < myMaxDepth))
            {
                //get the first Object of the queue
                IVertex currentVertex = queue.Dequeue();

                //dummy
                if (currentVertex == null || visitedVertices.Contains(new Tuple<long, long>(currentVertex.VertexTypeID, currentVertex.VertexID)))
                {
                    continue;
                }

                Tuple<long, long> current = new Tuple<long, long>(currentVertex.VertexTypeID, currentVertex.VertexID);
                Node currentNode;

                visitedVertices.Add(current);

                if (visitedNodes.ContainsKey(current))
                {
                    currentNode = visitedNodes[current];
                }
                else
                {
                    currentNode = new Node(current);
                }

                if (currentVertex.HasOutgoingEdge(myTypeAttribute.ID))
                {
                    var vertices = currentVertex.GetOutgoingEdge(myTypeAttribute.ID).GetTargetVertices();

                    Node nextNode;
                    Tuple<long, long> next;

                    foreach (var vertex in vertices)
                    {
                        //create a new node and set currentNode = parent, nextNode = child
                        next = new Tuple<long, long>(vertex.VertexTypeID, vertex.VertexID);
                        nextNode = new Node(next, currentNode);
                        currentNode.addChild(nextNode);

                        //if the child is the target
                        if (nextNode.Equals(target))
                        {
                            //node points on the target
                            target.Parents.Add(currentNode);

                            //if shortestOnly == true we are finished here
                            if (shortestOnly)
                            {
                                if (findAll)
                                {
                                    if (Convert.ToUInt64(depth + 1) <= myMaxPathLength)
                                    {
                                        //continue searching the current depth if there are any other shortest paths
                                        myMaxDepth = Convert.ToUInt64(depth + 1);

                                        myMaxPathLength = Convert.ToUInt64(depth + 1);
                                    }
                                }
                                else
                                {
                                    //got the shortest, finished
                                    return new TargetAnalyzer(root, target, myMaxPathLength, shortestOnly, findAll).GetPaths();
                                }
                            }
                        }
                        else
                        {
                            //been there before
                            if (visitedNodes.ContainsKey(nextNode.Key))
                            {
                                //node has more then one parent
                                visitedNodes[nextNode.Key].Parents.Add(currentNode);
                            }
                            //never seen before
                            else
                            {
                                //mark the node as visited
                                visitedNodes.Add(nextNode.Key, nextNode);
                            }

                            //and look what comes on the next level of depth
                            queue.Enqueue(vertex);
                        }
                    }
                }

                //if a new depth is reached
                if (queue.First() == null)
                {
                    //enqueue the dummy at the end of to mark the next depth
                    queue.Enqueue(queue.Dequeue());
                    //one step deeper in the dungen
                    depth++;
                }
            }

            #endregion

            //analyze paths
            return new TargetAnalyzer(root, target, myMaxPathLength, shortestOnly, findAll).GetPaths();
        }
Ejemplo n.º 19
0
        /// <summary>
        /// Fügt dem Knoten ein Child hinzu, existiert dieser schon, werden die Parents und Children des existierenden aktualisiert.
        /// </summary>
        /// <param name="myChild">Child welches hinzugefügt werden soll.</param>
        /// <returns></returns>
        public bool addChild(Node myChild)
        {
            bool equal = false;

            foreach (var thisChild in _Children)
            {
                //check if the node wich should be added IS already existing
                if (thisChild.Equals(myChild))
                {
                    equal = true;

                    break;
                }
            }

            if (!equal)
            {
                return _Children.Add(myChild);
            }

            return false;
        }