Example #1
0
        public TargetAnalyzer(Node myStart, Node myEnd, byte myMaxPathLength)
        {
            _Paths = new HashSet<List<long>>();

            _TempList = new List<long>();

            _Start = myStart;

            _End = myEnd;

            if (myMaxPathLength != 0)
            {
                _MaxPathLength = Convert.ToByte(myMaxPathLength - 1);
            }
            else
            {
                _MaxPathLength = Convert.ToByte(myMaxPathLength);
            }
        }
Example #2
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="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<long>> Find(IAttributeDefinition myTypeAttribute, IVertex myStart, IVertex myEnd, bool shortestOnly, bool findAll, byte myMaxDepth, byte myMaxPathLength)
        {
            #region declarations

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

            //Dictionary to store visited TreeNodes
            var visitedNodesLeft = new Dictionary<long, Node>();
            var visitedNodesRight = new Dictionary<long, Node>();

            var visitedVerticesLeft = new HashSet<long>();
            var visitedVerticesRight = new HashSet<long>();

            //set current depth left
            byte depthLeft = 2;
            //set current depth right
            byte depthRight = 1;

            //maximum depth
            byte maxDepthLeft = 0;
            byte maxDepthRight = 0;

            #region initialize maxDepths
            //if the maxDepth is greater then maxPathLength, then set maxDepth to maxPathLength
            if (myMaxDepth > myMaxPathLength)
            {
                myMaxDepth = myMaxPathLength;
            }

            //set depth for left side
            maxDepthLeft = Convert.ToByte(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.ToByte(maxDepthLeft - 1);
            }

            #endregion

            //shortest path length
            byte shortestPathLength = 0;

            //target node, the target of the select
            var target = new Node(myEnd.VertexID);
            var root = new Node(myStart.VertexID);
            HashSet<long> rootFriends = new HashSet<long>();

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

            #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);

            visitedNodesLeft.Add(root.Key, root);
            //add root and target to visitedNodes
            visitedNodesRight.Add(target.Key, target);

            #endregion

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

            if (!myStart.HasOutgoingEdge(myTypeAttribute.ID))
            {
                return null;
            }
            if (!myEnd.HasIncomingVertices(myEnd.VertexTypeID, myTypeAttribute.ID))
            {
                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 there is a dummyNode at the beginning of a queue
                    //first of left queue is a dummy
                    if (queueLeft.First<IVertex>() == null)
                    {
                        //if maxDepth of a side is reached and there is a dummy, one level is totaly searched
                        if (depthLeft == maxDepthLeft)
                        {
                            depthLeft++;

                            continue;
                        }

                        //dequeue dummy
                        queueLeft.Dequeue();

                        //increase depth
                        depthLeft++;

                        //if left queue is empty continue
                        if (queueLeft.Count == 0)
                        {
                            continue;
                        }
                        //enqueue dummy
                        else
                        {
                            queueLeft.Enqueue(dummyLeft);
                        }
                    }

                    //first of right queue is a dummy
                    if (queueRight.First<IVertex>() == null)
                    {
                        //if maxDepth of a side is reached and there is a dummy, one level is totaly searched
                        if (depthRight == maxDepthRight)
                        {
                            depthRight++;

                            continue;
                        }

                        //dequeue dummy
                        queueRight.Dequeue();

                        //increase depth
                        depthRight++;

                        //if right queue is empty continue
                        if (queueRight.Count == 0)
                        {
                            continue;
                        }
                        //enqueue dummy
                        else
                        {
                            queueRight.Enqueue(dummyRight);
                        }
                    }
                    #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;

                    //get the first Object of the queue
                    currentVertexLeft = queueLeft.Dequeue();

                    if (visitedVerticesLeft.Contains(currentVertexLeft.VertexID))
                    {
                        continue;
                    }

                    //get the first Object of the queue
                    currentVertexRight = queueRight.Dequeue();

                    if (visitedVerticesRight.Contains(currentVertexRight.VertexID))
                    {
                        //enqueue already dequeued vertex
                        queueLeft.Enqueue(currentVertexLeft);

                        continue;
                    }

                    visitedVerticesLeft.Add(currentVertexLeft.VertexID);
                    visitedVerticesRight.Add(currentVertexRight.VertexID);

                    if (visitedNodesLeft.ContainsKey(currentVertexLeft.VertexID))
                    {
                        currentNodeLeft = visitedNodesLeft[currentVertexLeft.VertexID];
                    }
                    else
                    {
                        currentNodeLeft = new Node(currentVertexLeft.VertexID);
                    }

                    if (visitedNodesRight.ContainsKey(currentVertexRight.VertexID))
                    {
                        currentNodeRight = visitedNodesRight[currentVertexRight.VertexID];
                    }
                    else
                    {
                        currentNodeRight = new Node(currentVertexRight.VertexID);
                    }
                    #endregion

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

                        #region check left friends
                        foreach (var nextLeftVertex in leftVertices)
                        {
                            Node nextLeftNode;

                            #region if the child is the target

                            if (nextLeftVertex.VertexID.Equals(target.Key))
                            {
                                //set currentLeft as parent of target
                                target.addParent(currentNodeLeft);

                                #region check if already visited
                                if (visitedNodesLeft.ContainsKey(nextLeftVertex.VertexID))
                                {
                                    //set currentLeft as parent
                                    visitedNodesLeft[nextLeftVertex.VertexID].addParent(currentNodeLeft);

                                    //set currentNodeLeft as child
                                    currentNodeLeft.addChild(visitedNodesLeft[nextLeftVertex.VertexID]);
                                }
                                else
                                {
                                    //create a new node and set currentLeft = parent
                                    nextLeftNode = new Node(nextLeftVertex.VertexID, currentNodeLeft);

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

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

                                    //and put node into the queue
                                    queueLeft.Enqueue(nextLeftVertex);
                                }

                                #endregion

                                #region check how much parents are searched

                                if (shortestOnly && !findAll)
                                {
                                    if ((depthLeft + depthRight + 1) > myMaxPathLength)
                                    {
                                        shortestPathLength = myMaxPathLength;
                                    }
                                    else
                                    {
                                        shortestPathLength = Convert.ToByte(depthLeft + depthRight + 1);
                                    }

                                    return new TargetAnalyzer(root, target, shortestPathLength, shortestOnly, findAll).getPaths();
                                }
                                //if find all shortest paths
                                else if (shortestOnly && findAll)
                                {
                                    //set maxDepth to actual depth
                                    maxDepthLeft = depthLeft;
                                    maxDepthRight = depthRight;

                                    if ((depthLeft + depthRight) > myMaxPathLength)
                                    {
                                        shortestPathLength = myMaxPathLength;
                                    }
                                    else
                                    {
                                        shortestPathLength = Convert.ToByte(depthLeft + depthRight);
                                    }
                                }

                                #endregion
                            }

                            #endregion
                            #region already visited
                            else if (visitedNodesLeft.ContainsKey(nextLeftVertex.VertexID))
                            {
                                //set currentLeft as parent
                                visitedNodesLeft[nextLeftVertex.VertexID].addParent(currentNodeLeft);

                                //set currentNodeLeft as child
                                currentNodeLeft.addChild(visitedNodesLeft[nextLeftVertex.VertexID]);
                            }
                            #endregion already visited
                            #region set as visited
                            else
                            {
                                //create a new node and set currentLeft = parent
                                nextLeftNode = new Node(nextLeftVertex.VertexID, currentNodeLeft);

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

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

                                //and put node into the queue
                                queueLeft.Enqueue(nextLeftVertex);
                            }
                            #endregion set as visited
                        }
                        #endregion check left friends

                        //get all referenced ObjectUUIDs using the given Edge
                        var rightVertices = currentVertexRight.GetIncomingVertices(currentVertexRight.VertexTypeID, myTypeAttribute.ID);

                        #region check right friends
                        foreach (var nextRightVertex in rightVertices)
                        {
                            Node nextRightNode;

                            #region if the child is the target
                            if (root.Key.Equals(nextRightVertex.VertexID))
                            {
                                #region check if already visited
                                //mark node as visited
                                if (visitedNodesRight.ContainsKey(nextRightVertex.VertexID))
                                {
                                    //set found children
                                    visitedNodesRight[nextRightVertex.VertexID].addChild(currentNodeRight);

                                    currentNodeRight.addParent(visitedNodesRight[nextRightVertex.VertexID]);
                                }
                                else
                                {
                                    //create a new node and set currentRight = child
                                    nextRightNode = new Node(nextRightVertex.VertexID);
                                    nextRightNode.addChild(currentNodeRight);

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

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

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

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

                                if (shortestOnly && !findAll)
                                {
                                    if ((depthLeft + depthRight + 1) > myMaxPathLength)
                                    {
                                        shortestPathLength = myMaxPathLength;
                                    }
                                    else
                                    {
                                        shortestPathLength = Convert.ToByte(depthLeft + depthRight + 1);
                                    }

                                    return new TargetAnalyzer(root, target, shortestPathLength, shortestOnly, findAll).getPaths();
                                }
                                //if find all shortest paths
                                else if (shortestOnly && findAll)
                                {
                                    //set maxDepth to actual depth
                                    maxDepthLeft = depthLeft;
                                    maxDepthRight = depthRight;

                                    if ((depthLeft + depthRight) > myMaxPathLength)
                                    {
                                        shortestPathLength = myMaxPathLength;
                                    }
                                    else
                                    {
                                        shortestPathLength = Convert.ToByte(depthLeft + depthRight);
                                    }
                                }

                                #endregion check how much paths are searched
                            }
                            #endregion if the child is the target
                            #region already visited
                            else if (visitedNodesRight.ContainsKey(nextRightVertex.VertexID))
                            {
                                //set found children
                                visitedNodesRight[nextRightVertex.VertexID].addChild(currentNodeRight);

                                currentNodeRight.addParent(visitedNodesRight[nextRightVertex.VertexID]);
                            }
                            #endregion already visited
                            #region set as visited
                            else
                            {
                                //create a new node and set currentRight = child
                                nextRightNode = new Node(nextRightVertex.VertexID);
                                nextRightNode.addChild(currentNodeRight);

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

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

                                //and look what comes on the next level of depth
                                queueRight.Enqueue(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[node.Key] != null)
                            {
                                //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);

                                foundIntersect = true;
                            }
                        }
                        #endregion build intersection of visitedNodesLeft and visitedNodesRight

                        #region analyze intersection
                        //if intersection nodes existing
                        if (foundIntersect)
                        {
                            //only shortest path
                            if (shortestOnly && !findAll)
                            {
                                //_Logger.Info("found shortest path..starting analyzer");

                                if ((depthLeft + depthRight + 1) > myMaxPathLength)
                                {
                                    shortestPathLength = myMaxPathLength;
                                }
                                else
                                {
                                    shortestPathLength = Convert.ToByte(depthLeft + depthRight + 1);
                                }

                                return new TargetAnalyzer(root, target, shortestPathLength, shortestOnly, findAll).getPaths();
                            }
                            //if find all shortest paths
                            else if (shortestOnly && findAll)
                            {
                                //set maxDepth to actual depth
                                maxDepthLeft = depthLeft;
                                maxDepthRight = depthRight;

                                if ((depthLeft + depthRight + 1) > myMaxPathLength)
                                {
                                    shortestPathLength = myMaxPathLength;
                                }
                                else if (shortestPathLength == 0)
                                {
                                    shortestPathLength = Convert.ToByte(depthLeft + depthRight + 1);
                                }

                            }
                        }
                        #endregion analyze intersection
                    }
                    #endregion the edge and the backwardedge are existing
                    #region only the edge exists
                    else if (currentVertexLeft.HasOutgoingEdge(myTypeAttribute.ID))
                    {
                        //get all referenced ObjectUUIDs using the given Edge
                        var leftVertices = currentVertexLeft.GetOutgoingEdge(myTypeAttribute.ID).GetTargetVertices();

                        #region check left friends
                        foreach (var nextLeftVertex in leftVertices)
                        {
                            Node nextLeftNode;

                            #region if the child is the target
                            if (nextLeftVertex.VertexID.Equals(target.Key))
                            {
                                //set currentLeft as parent of target
                                target.addParent(currentNodeLeft);

                                #region check if already visited
                                if (visitedNodesLeft.ContainsKey(nextLeftVertex.VertexID))
                                {
                                    //set currentLeft as parent
                                    visitedNodesLeft[nextLeftVertex.VertexID].addParent(currentNodeLeft);

                                    //set currentNodeLeft as child
                                    currentNodeLeft.addChild(visitedNodesLeft[nextLeftVertex.VertexID]);
                                }
                                else
                                {
                                    //create a new node and set currentLeft = parent
                                    nextLeftNode = new Node(nextLeftVertex.VertexID, currentNodeLeft);

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

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

                                    //and put node into the queue
                                    queueLeft.Enqueue(nextLeftVertex);
                                }
                                #endregion

                                #region check how much parents are searched

                                if (shortestOnly && !findAll)
                                {
                                    if ((depthLeft + depthRight + 1) > myMaxPathLength)
                                    {
                                        shortestPathLength = myMaxPathLength;
                                    }
                                    else
                                    {
                                        shortestPathLength = Convert.ToByte(depthLeft + depthRight + 1);
                                    }

                                    return new TargetAnalyzer(root, target, shortestPathLength, shortestOnly, findAll).getPaths();
                                }
                                //if find all shortest paths
                                else if (shortestOnly && findAll)
                                {
                                    //set maxDepth to actual depth
                                    maxDepthLeft = depthLeft;
                                    maxDepthRight = depthRight;

                                    if ((depthLeft + depthRight) > myMaxPathLength)
                                    {
                                        shortestPathLength = myMaxPathLength;
                                    }
                                    else
                                    {
                                        shortestPathLength = Convert.ToByte(depthLeft + depthRight);
                                    }
                                }

                                #endregion
                            }
                            #endregion
                            #region already visited from right side
                            else if (visitedNodesRight.ContainsKey(nextLeftVertex.VertexID))
                            {
                                //get node
                                Node temp = visitedNodesRight[nextLeftVertex.VertexID];
                                //add parent new
                                temp.addParent(currentNodeLeft);
                                //add as child
                                currentNodeLeft.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) > myMaxPathLength)
                                    {
                                        shortestPathLength = myMaxPathLength;
                                    }
                                    else
                                    {
                                        shortestPathLength = Convert.ToByte(depthLeft + depthRight + 1);
                                    }

                                    return new TargetAnalyzer(root, target, shortestPathLength, shortestOnly, findAll).getPaths();
                                }
                                else if (shortestOnly && findAll)
                                {
                                    maxDepthLeft = depthLeft;

                                    shortestPathLength = Convert.ToByte(maxDepthLeft + maxDepthRight);
                                }
                            }
                            #endregion already visited from right side
                            #region already visited
                            else if (visitedNodesLeft.ContainsKey(nextLeftVertex.VertexID))
                            {
                                //set currentLeft as parent
                                visitedNodesLeft[nextLeftVertex.VertexID].addParent(currentNodeLeft);

                                //set currentNodeLeft as child
                                currentNodeLeft.addChild(visitedNodesLeft[nextLeftVertex.VertexID]);
                            }
                            #endregion already visited
                            #region set as visited
                            else
                            {
                                //create a new node and set currentLeft = parent
                                nextLeftNode = new Node(nextLeftVertex.VertexID, currentNodeLeft);

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

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

                                //and put node into the queue
                                queueLeft.Enqueue(nextLeftVertex);
                            }
                            #endregion set as visited
                        }
                        #endregion check left friends
                    }
                    #endregion only the edge exists
                    #region only the backwardedge exists
                    else if (currentVertexRight.HasIncomingVertices(currentVertexRight.VertexTypeID, myTypeAttribute.ID))
                    {
                        //get all referenced ObjectUUIDs using the given Edge
                        var rightVertices = currentVertexRight.GetIncomingVertices(currentVertexRight.VertexTypeID, myTypeAttribute.ID);

                        #region check right friends
                        foreach (var nextRightVertex in rightVertices)
                        {
                            Node nextRightNode;

                            #region if the child is the target
                            if (root.Key.Equals(nextRightVertex.VertexID))
                            {
                                #region check if already visited
                                //mark node as visited
                                if (visitedNodesRight.ContainsKey(nextRightVertex.VertexID))
                                {
                                    //set found children
                                    visitedNodesRight[nextRightVertex.VertexID].addChild(currentNodeRight);

                                    currentNodeRight.addParent(visitedNodesRight[nextRightVertex.VertexID]);
                                }
                                else
                                {
                                    //create a new node and set currentRight = child
                                    nextRightNode = new Node(nextRightVertex.VertexID);
                                    nextRightNode.addChild(currentNodeRight);

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

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

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

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

                                if (shortestOnly && !findAll)
                                {
                                    if ((depthLeft + depthRight + 1) > myMaxPathLength)
                                    {
                                        shortestPathLength = myMaxPathLength;
                                    }
                                    else
                                    {
                                        shortestPathLength = Convert.ToByte(depthLeft + depthRight + 1);
                                    }

                                    return new TargetAnalyzer(root, target, shortestPathLength, shortestOnly, findAll).getPaths();
                                }
                                //if find all shortest paths
                                else if (shortestOnly && findAll)
                                {
                                    //set maxDepth to actual depth
                                    maxDepthLeft = depthLeft;
                                    maxDepthRight = depthRight;

                                    if ((depthLeft + depthRight) > myMaxPathLength)
                                    {
                                        shortestPathLength = myMaxPathLength;
                                    }
                                    else
                                    {
                                        shortestPathLength = Convert.ToByte(depthLeft + depthRight);
                                    }
                                }

                                #endregion check how much paths are searched
                            }
                            #endregion if the child is the target
                            #region already visited from left side
                            else if (visitedNodesLeft.ContainsKey(nextRightVertex.VertexID))
                            {
                                //get node
                                Node temp = visitedNodesLeft[nextRightVertex.VertexID];
                                temp.addChild(currentNodeRight);
                                currentNodeRight.addParent(temp);

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

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

                                if (shortestOnly && !findAll)
                                {
                                    if ((depthLeft + depthRight + 1) > myMaxPathLength)
                                    {
                                        shortestPathLength = myMaxPathLength;
                                    }
                                    else
                                    {
                                        shortestPathLength = Convert.ToByte(depthLeft + depthRight + 1);
                                    }

                                    return new TargetAnalyzer(root, target, shortestPathLength, shortestOnly, findAll).getPaths();
                                }
                                else if (shortestOnly && findAll)
                                {
                                    maxDepthRight = depthRight;

                                    shortestPathLength = Convert.ToByte(maxDepthLeft + maxDepthRight);
                                }
                            }
                            #endregion already visited from left side
                            #region already visited
                            else if (visitedNodesRight.ContainsKey(nextRightVertex.VertexID))
                            {
                                //set found children
                                visitedNodesRight[nextRightVertex.VertexID].addChild(currentNodeRight);

                                currentNodeRight.addParent(visitedNodesRight[nextRightVertex.VertexID]);
                            }
                            #endregion already visited
                            #region set as visited
                            else
                            {
                                //create a new node and set currentRight = child
                                nextRightNode = new Node(nextRightVertex.VertexID);
                                nextRightNode.addChild(currentNodeRight);

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

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

                                //and look what comes on the next level of depth
                                queueRight.Enqueue(nextRightVertex);
                            }
                            #endregion set as visited
                        }
                        #endregion check right friends
                    }
                    #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
                    //dummy
                    if (queueLeft.First<IVertex>() == null)
                    {
                        queueLeft.Dequeue();

                        depthLeft++;

                        if (queueLeft.Count == 0)
                        {
                            continue;
                        }
                        else if (depthLeft > maxDepthLeft)
                        {
                            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();

                    if (visitedVerticesLeft.Contains(currentVertexLeft.VertexID))
                    {
                        continue;
                    }

                    visitedVerticesLeft.Add(currentVertexLeft.VertexID);

                    if (visitedNodesLeft.ContainsKey(currentVertexLeft.VertexID))
                    {
                        currentNodeLeft = visitedNodesLeft[currentVertexLeft.VertexID];
                    }
                    else
                    {
                        currentNodeLeft = new Node(currentVertexLeft.VertexID);
                    }
                    #endregion

                    if (currentVertexLeft.HasOutgoingEdge(myTypeAttribute.ID))
                    {
                        //get all referenced ObjectUUIDs using the given Edge
                        var leftVertices = currentVertexLeft.GetOutgoingEdge(myTypeAttribute.ID).GetTargetVertices();

                        #region check left friends
                        foreach (var nextLeftVertex in leftVertices)
                        {
                            Node nextLeftNode;

                            #region if the child is the target
                            if (nextLeftVertex.VertexID.Equals(target.Key))
                            {
                                //set currentLeft as parent of target
                                target.addParent(currentNodeLeft);

                                #region check if already visited
                                if (visitedNodesLeft.ContainsKey(nextLeftVertex.VertexID))
                                {
                                    //set currentLeft as parent
                                    visitedNodesLeft[nextLeftVertex.VertexID].addParent(currentNodeLeft);

                                    //set currentNodeLeft as child
                                    currentNodeLeft.addChild(visitedNodesLeft[nextLeftVertex.VertexID]);
                                }
                                else
                                {
                                    //create a new node and set currentLeft = parent
                                    nextLeftNode = new Node(nextLeftVertex.VertexID, currentNodeLeft);

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

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

                                    //and put node into the queue
                                    queueLeft.Enqueue(nextLeftVertex);
                                }
                                #endregion

                                #region check how much parents are searched

                                if (shortestOnly && !findAll)
                                {
                                    if ((depthLeft + depthRight + 1) > myMaxPathLength)
                                    {
                                        shortestPathLength = myMaxPathLength;
                                    }
                                    else
                                    {
                                        shortestPathLength = Convert.ToByte(depthLeft + depthRight + 1);
                                    }

                                    return new TargetAnalyzer(root, target, shortestPathLength, shortestOnly, findAll).getPaths();
                                }
                                //if find all shortest paths
                                else if (shortestOnly && findAll)
                                {
                                    //set maxDepth to actual depth
                                    maxDepthLeft = depthLeft;
                                    maxDepthRight = depthRight;

                                    if ((depthLeft + depthRight) > myMaxPathLength)
                                    {
                                        shortestPathLength = myMaxPathLength;
                                    }
                                    else
                                    {
                                        shortestPathLength = Convert.ToByte(depthLeft + depthRight);
                                    }
                                }

                                #endregion
                            }
                            #endregion
                            #region already visited from right side
                            else if (visitedNodesRight.ContainsKey(nextLeftVertex.VertexID))
                            {
                                //get node
                                Node temp = visitedNodesRight[nextLeftVertex.VertexID];
                                //add parent new
                                temp.addParent(currentNodeLeft);
                                //add as child
                                currentNodeLeft.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) > myMaxPathLength)
                                    {
                                        shortestPathLength = myMaxPathLength;
                                    }
                                    else
                                    {
                                        shortestPathLength = Convert.ToByte(depthLeft + depthRight + 1);
                                    }

                                    return new TargetAnalyzer(root, target, shortestPathLength, shortestOnly, findAll).getPaths();
                                }
                                else if (shortestOnly && findAll)
                                {
                                    maxDepthLeft = depthLeft;

                                    shortestPathLength = Convert.ToByte(maxDepthLeft + maxDepthRight);
                                }
                            }
                            #endregion already visited from right side
                            #region already visited
                            else if (visitedNodesLeft.ContainsKey(nextLeftVertex.VertexID))
                            {
                                //set currentLeft as parent
                                visitedNodesLeft[nextLeftVertex.VertexID].addParent(currentNodeLeft);

                                //set currentNodeLeft as child
                                currentNodeLeft.addChild(visitedNodesLeft[nextLeftVertex.VertexID]);
                            }
                            #endregion already visited
                            #region set as visited
                            else
                            {
                                //create a new node and set currentLeft = parent
                                nextLeftNode = new Node(nextLeftVertex.VertexID, currentNodeLeft);

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

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

                                //and put node into the queue
                                queueLeft.Enqueue(nextLeftVertex);
                            }
                            #endregion set as visited
                        }
                        #endregion check left friends
                    }
                }
                #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
                    //dummy
                    if (queueRight.First<IVertex>() == null)
                    {
                        queueRight.Dequeue();

                        depthRight++;

                        if (queueRight.Count == 0)
                        {
                            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();

                    if (visitedVerticesRight.Contains(currentVertexRight.VertexID))
                    {
                        continue;
                    }

                    visitedVerticesRight.Add(currentVertexRight.VertexID);

                    if (visitedNodesRight.ContainsKey(currentVertexRight.VertexID))
                    {
                        currentNodeRight = visitedNodesRight[currentVertexRight.VertexID];
                    }
                    else
                    {
                        currentNodeRight = new Node(currentVertexRight.VertexID);
                    }
                    #endregion

                    if (currentVertexRight.HasIncomingVertices(currentVertexRight.VertexTypeID, myTypeAttribute.ID))
                    {
                        //get all referenced ObjectUUIDs using the given Edge
                        var rightVertices = currentVertexRight.GetIncomingVertices(currentVertexRight.VertexTypeID, myTypeAttribute.ID);

                        #region check right friends
                        foreach (var nextRightVertex in rightVertices)
                        {
                            Node nextRightNode;

                            #region if the child is the target
                            if (root.Key.Equals(nextRightVertex.VertexID))
                            {
                                #region check if already visited
                                //mark node as visited
                                if (visitedNodesRight.ContainsKey(nextRightVertex.VertexID))
                                {
                                    //set found children
                                    visitedNodesRight[nextRightVertex.VertexID].addChild(currentNodeRight);

                                    currentNodeRight.addParent(visitedNodesRight[nextRightVertex.VertexID]);
                                }
                                else
                                {
                                    //create a new node and set currentRight = child
                                    nextRightNode = new Node(nextRightVertex.VertexID);
                                    nextRightNode.addChild(currentNodeRight);

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

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

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

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

                                if (shortestOnly && !findAll)
                                {
                                    if ((depthLeft + depthRight + 1) > myMaxPathLength)
                                    {
                                        shortestPathLength = myMaxPathLength;
                                    }
                                    else
                                    {
                                        shortestPathLength = Convert.ToByte(depthLeft + depthRight + 1);
                                    }

                                    return new TargetAnalyzer(root, target, shortestPathLength, shortestOnly, findAll).getPaths();
                                }
                                //if find all shortest paths
                                else if (shortestOnly && findAll)
                                {
                                    //set maxDepth to actual depth
                                    maxDepthLeft = depthLeft;
                                    maxDepthRight = depthRight;

                                    if ((depthLeft + depthRight) > myMaxPathLength)
                                    {
                                        shortestPathLength = myMaxPathLength;
                                    }
                                    else
                                    {
                                        shortestPathLength = Convert.ToByte(depthLeft + depthRight);
                                    }
                                }

                                #endregion check how much paths are searched
                            }
                            #endregion if the child is the target
                            #region already visited from left side
                            else if (visitedNodesLeft.ContainsKey(nextRightVertex.VertexID))
                            {
                                //get node
                                Node temp = visitedNodesLeft[nextRightVertex.VertexID];
                                temp.addChild(currentNodeRight);
                                currentNodeRight.addParent(temp);

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

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

                                if (shortestOnly && !findAll)
                                {
                                    if ((depthLeft + depthRight + 1) > myMaxPathLength)
                                    {
                                        shortestPathLength = myMaxPathLength;
                                    }
                                    else
                                    {
                                        shortestPathLength = Convert.ToByte(depthLeft + depthRight + 1);
                                    }

                                    return new TargetAnalyzer(root, target, shortestPathLength, shortestOnly, findAll).getPaths();
                                }
                                else if (shortestOnly && findAll)
                                {
                                    maxDepthRight = depthRight;

                                    shortestPathLength = Convert.ToByte(maxDepthLeft + maxDepthRight);
                                }
                            }
                            #endregion already visited from left side
                            #region already visited
                            else if (visitedNodesRight.ContainsKey(nextRightVertex.VertexID))
                            {
                                //set found children
                                visitedNodesRight[nextRightVertex.VertexID].addChild(currentNodeRight);

                                currentNodeRight.addParent(visitedNodesRight[nextRightVertex.VertexID]);
                            }
                            #endregion already visited
                            #region set as visited
                            else
                            {
                                //create a new node and set currentRight = child
                                nextRightNode = new Node(nextRightVertex.VertexID);
                                nextRightNode.addChild(currentNodeRight);

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

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

                                //and look what comes on the next level of depth
                                queueRight.Enqueue(nextRightVertex);
                            }
                            #endregion set as visited
                        }
                        #endregion check right friends
                    }
                }
                #endregion only right queue contain objects

                #region abort loop
                else
                {
                    break;
                }
                #endregion abort loop
            }

            //get result paths
            #region start TargetAnalyzer
            if (shortestOnly && findAll)
            {
                if (shortestPathLength > myMaxPathLength)
                {
                    shortestPathLength = myMaxPathLength;
                }

                return new TargetAnalyzer(root, target, shortestPathLength, shortestOnly, findAll).getPaths();
            }
            else
            {
                return new TargetAnalyzer(root, target, myMaxPathLength, shortestOnly, findAll).getPaths();
            }
            #endregion start TargetAnalyzer

            #endregion BidirectionalBFS
        }
Example #3
0
File: Node.cs Project: loubo/sones
 public Node(long myObjectID, Node myParent)
     : this(myObjectID)
 {
     _Parents.Add(myParent);
 }
Example #4
0
File: Node.cs Project: loubo/sones
        /// <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;
        }
Example #5
0
File: Node.cs Project: loubo/sones
        /// <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;
        }
Example #6
0
 public TargetAnalyzer(Node myStart, Node myEnd, byte myMaxPathLength, bool myShortestOnly, bool myFindAll)
     : this(myStart, myEnd, myMaxPathLength)
 {
     _ShortestOnly = myShortestOnly;
     _FindAll = myFindAll;
 }
Example #7
0
        private void getPath(Node myCurrent)
        {
            if (!_TempList.Contains(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))
                {
                    //duplicate list
                    var temp = new List<long>(_TempList);

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

                    //add completed path to result list
                    _Paths.Add(temp);
                }

                foreach (Node parent in myCurrent.Parents)
                {
                    //if parent node not already in actual path
                    if (!parent.AlreadyInPath)
                    {
                        //and MaxPathLength is not reached
                        if (_TempList.Count < _MaxPathLength)
                        {
                            getPath(parent);
                        }
                    }
                }

                if (_TempList.Count != 0)
                {
                    //remove last node from actual path
                    _TempList.Remove(_TempList.Last<long>());
                    //myCurrent isn't in actual path
                    myCurrent.AlreadyInPath = false;
                }
            }
            return;
        }
Example #8
0
File: BFS.cs Project: loubo/sones
        ///// <summary>
        ///// Sucht im Graphen nach Knoten "myEnd" ausgehend vom Knoten "myStart", bis zur max. Tiefe "myMaxDepth".
        ///// </summary>
        ///// <param name="myTypeAttribute">Kante über die gesucht werden soll</param>
        ///// <param name="myDBContext"></param>
        ///// <param name="myStart">Startknoten</param>
        ///// <param name="myEnd">gesuchter Knoten</param>
        ///// <param name="myMaxDepth">max. Tiefe</param>
        ///// <returns>true wenn gesuchter Knoten min. 1 mal gefunden, false sonst</returns>
        //public bool Find(IAttributeDefinition myTypeAttribute, IVertex myStart, IVertex myEnd, byte myMaxDepth)
        //{
        //    #region data
        //    //queue for BFS
        //    Queue<long> queue = new Queue<ObjectUUID>();
        //    //Dictionary to store visited TreeNodes
        //    HashSet<ObjectUUID> visitedNodes = new HashSet<ObjectUUID>();
        //    //current depth
        //    byte depth = 1;
        //    //first node in path tree, the start of the select
        //    ObjectUUID root = myStart.ObjectUUID;
        //    //target node, the target of the select
        //    ObjectUUID target = myEnd.ObjectUUID;
        //    //dummy node to check in which level the BFS is
        //    ObjectUUID dummy = null;
        //    //enqueue first node to start the BFS
        //    queue.Enqueue(root);
        //    queue.Enqueue(dummy);
        //    //add root to visitedNodes
        //    visitedNodes.Add(root);
        //    //holds the actual DBObject
        //    Exceptional<DBObjectStream> currentDBObject;
        //    #endregion data
        //    #region BFS
        //    #region validate root
        //    //check if root has edge
        //    var dbo = myDBContext.DBObjectCache.LoadDBObjectStream(myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager), root);
        //    if (dbo.Failed())
        //    {
        //        throw new NotImplementedException();
        //    }
        //    if (!dbo.Value.HasAttribute(myTypeAttribute.UUID, myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager)))
        //    {
        //        return false;
        //    }
        //    #endregion validate root
        //    //if there is more than one object in the queue and the actual depth is less than MaxDepth
        //    while ((queue.Count > 1) && (depth <= myMaxDepth))
        //    {
        //        //get the first Object of the queue
        //        ObjectUUID nodeOfQueue = queue.Dequeue();
        //        #region check if nodeOfQueue is a dummy
        //        //if nodeOfQueue is a dummy, this level is completely worked off
        //        if (nodeOfQueue == null)
        //        {
        //            depth++;
        //            queue.Enqueue(nodeOfQueue);
        //            continue;
        //        }
        //        #endregion check if current is a dummy
        //        //load DBObject
        //        currentDBObject = myDBContext.DBObjectCache.LoadDBObjectStream(myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager), nodeOfQueue);
        //        if (currentDBObject.Failed())
        //        {
        //            throw new NotImplementedException();
        //        }
        //        if (currentDBObject.Value.HasAttribute(myTypeAttribute.UUID, myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager)))
        //        {
        //            #region EdgeType is ASetOfReferencesEdgeType
        //            if (myTypeAttribute.EdgeType is ASetOfReferencesEdgeType)
        //            {
        //                //get all referenced ObjectUUIDs using the given Edge
        //                var objectUUIDs = (currentDBObject.Value.GetAttribute(myTypeAttribute.UUID) as ASetOfReferencesEdgeType).GetAllReferenceIDs();
        //                ObjectUUID currentNode;
        //                foreach (ObjectUUID obj in objectUUIDs)
        //                {
        //                    #region obj is target
        //                    //if the child is the target
        //                    if (target.Equals(obj))
        //                    {
        //                        return true;
        //                    }
        //                    #endregion obj is target
        //                    #region never seen before
        //                    else if (!visitedNodes.Contains(obj))
        //                    {
        //                        //create new node and set nodeOfQueue as parent
        //                        currentNode = new ObjectUUID(obj.ToString());
        //                        //mark the node as visited
        //                        visitedNodes.Add(currentNode);
        //                        //put created node in queue
        //                        queue.Enqueue(currentNode);
        //                    }
        //                    #endregion never seen before
        //                }
        //            }
        //            #endregion EdgeType is ASetOfReferencesEdgeType
        //            #region EdgeType is ASingleReferenceEdgeType
        //            else if (myTypeAttribute.EdgeType is ASingleReferenceEdgeType)
        //            {
        //                //get all referenced ObjectUUIDs using the given Edge
        //                var objectUUIDs = (currentDBObject.Value.GetAttribute(myTypeAttribute.UUID) as ASingleReferenceEdgeType).GetAllReferenceIDs();
        //                ObjectUUID objectUUID = objectUUIDs.First<ObjectUUID>();
        //                ObjectUUID currentNode;
        //                #region obj is target
        //                //if the child is the target
        //                if (target.Equals(objectUUID))
        //                {
        //                    return true;
        //                }
        //                #endregion obj is target
        //                #region never seen before
        //                else if (!visitedNodes.Contains(objectUUID))
        //                {
        //                    //create new node and set nodeOfQueue as parent
        //                    currentNode = new ObjectUUID(objectUUID.ToString());
        //                    //mark the node as visited
        //                    visitedNodes.Add(currentNode);
        //                    //put created node in queue
        //                    queue.Enqueue(currentNode);
        //                }
        //                #endregion never seen before
        //            }
        //            #endregion EdgeType is ASingleReferenceEdgeType
        //            else
        //            {
        //                throw new NotImplementedException();
        //            }
        //        }
        //    }
        //    #endregion BFS
        //    return false;
        //}
        ///// <summary>
        ///// Sucht im Graphen nach Knoten "myEnd" ausgehend von der Knotenmenge "myEdge", bis zur max. Tiefe "myMaxDepth".
        ///// </summary>
        ///// <param name="myTypeAttribute">Kante über die gesucht werden soll</param>
        ///// <param name="myDBContext"></param>
        ///// <param name="myStart">Startknoten</param>
        ///// <param name="myEnd">gesuchter Knoten</param>
        ///// <param name="myEdge">Menge an Knoten, ausgehend vom Startknoten welche mittels einer Funktion eingeschränkt wurde</param>
        ///// <param name="myMaxDepth">max. Tiefe</param>
        ///// <returns>true wenn gesuchter Knoten min. 1 mal gefunden, false sonst</returns>
        //public bool Find(IAttributeDefinition myTypeAttribute, IVertex myStart, IVertex myEnd, IEdge myEdge, byte myMaxDepth)
        //{
        //    #region data
        //    //queue for BFS
        //    Queue<ObjectUUID> queue = new Queue<ObjectUUID>();
        //    //Dictionary to store visited TreeNodes
        //    BigHashSet<ObjectUUID> visitedNodes = new BigHashSet<ObjectUUID>();
        //    //current depth
        //    byte depth = 2;
        //    //first node in path tree, the start of the select
        //    ObjectUUID root = myStart.ObjectUUID;
        //    //constrainted set of nodes, of start node
        //    HashSet<ObjectUUID> rootFriends = new HashSet<ObjectUUID>();
        //    //target node, the target of the select
        //    ObjectUUID target = myEnd.ObjectUUID;
        //    //dummy node to check in which level the BFS is
        //    ObjectUUID dummy = null;
        //    //add root to visitedNodes
        //    visitedNodes.Add(root);
        //    //holds the actual DBObject
        //    Exceptional<DBObjectStream> currentDBObject;
        //    #endregion data
        //    #region validate root
        //    //check if root has edge
        //    var dbo = myDBContext.DBObjectCache.LoadDBObjectStream(myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager), root);
        //    if (dbo.Failed())
        //    {
        //        throw new NotImplementedException();
        //    }
        //    if (!dbo.Value.HasAttribute(myTypeAttribute.UUID, myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager)))
        //    {
        //        return false;
        //    }
        //    #endregion validate root
        //    #region get friends of startElement and check if they are the target and valid
        //    //instead of inserting only the startObject, we are using the startObject and the friends of the startObject (which could be restricted)
        //    var firstUUIDs = myEdge.GetAllReferenceIDs();
        //    for (int i = 0; i < firstUUIDs.Count(); i++)
        //    {
        //        var element = firstUUIDs.ElementAt(i);
        //        if (element != null)
        //        {
        //            //create a new node and set root = parent
        //            var currentNode = element;
        //            #region check if the child is the target
        //            //start and target are conntected directly
        //            if (currentNode.Equals(myEnd.ObjectUUID))
        //            {
        //                //add node (which coud be the target) to startFriends (if start and target are directly connected, the target in the rootFriends list is needed)
        //                rootFriends.Add(currentNode);
        //                return true;
        //            }
        //            #endregion check if the child is the target
        //            //check if element has edge
        //            var dbobject = myDBContext.DBObjectCache.LoadDBObjectStream(myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager), currentNode);
        //            if (dbobject.Failed())
        //            {
        //                continue;
        //            }
        //            if (!dbobject.Value.HasAttribute(myTypeAttribute.UUID, myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager)))
        //            {
        //                continue;
        //            }
        //            //enqueue node to start from left side
        //            queue.Enqueue(currentNode);
        //            //add node to visitedNodes
        //            visitedNodes.Add(currentNode);
        //            //add node to startFriends
        //            rootFriends.Add(currentNode);
        //        }
        //    }
        //    #endregion get friends of startElement and check if they are the target and valid
        //    //enqueue dummy
        //    queue.Enqueue(dummy);
        //    #region BFS
        //    //if there is more than one object in the queue and the actual depth is less than MaxDepth
        //    while ((queue.Count > 1) && (depth <= myMaxDepth))
        //    {
        //        //get the first Object of the queue
        //        ObjectUUID nodeOfQueue = queue.Dequeue();
        //        #region check if nodeOfQueue is a dummy
        //        //if nodeOfQueue is a dummy, this level is completely worked off
        //        if (nodeOfQueue == null)
        //        {
        //            depth++;
        //            queue.Enqueue(nodeOfQueue);
        //            continue;
        //        }
        //        #endregion check if current is a dummy
        //        //load DBObject
        //        currentDBObject = myDBContext.DBObjectCache.LoadDBObjectStream(myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager), nodeOfQueue);
        //        if (currentDBObject.Failed())
        //        {
        //            throw new NotImplementedException();
        //        }
        //        if (currentDBObject.Value.HasAttribute(myTypeAttribute.UUID, myTypeAttribute.GetRelatedType(myDBContext.DBTypeManager)))
        //        {
        //            #region EdgeType is ASetOfReferencesEdgeType
        //            if (myTypeAttribute.EdgeType is ASetOfReferencesEdgeType)
        //            {
        //                //get all referenced ObjectUUIDs using the given Edge
        //                var objectUUIDs = (currentDBObject.Value.GetAttribute(myTypeAttribute.UUID) as ASetOfReferencesEdgeType).GetAllReferenceIDs();
        //                ObjectUUID currentNode;
        //                foreach (ObjectUUID obj in objectUUIDs)
        //                {
        //                    #region obj is target
        //                    //if the child is the target
        //                    if (target.Equals(obj))
        //                    {
        //                        return true;
        //                    }
        //                    #endregion obj is target
        //                    #region never seen before
        //                    else if (!visitedNodes.Contains(obj))
        //                    {
        //                        //create new node and set nodeOfQueue as parent
        //                        currentNode = new ObjectUUID(obj.ToString());
        //                        //mark the node as visited
        //                        visitedNodes.Add(currentNode);
        //                        //put created node in queue
        //                        queue.Enqueue(currentNode);
        //                    }
        //                    #endregion never seen before
        //                }
        //            }
        //            #endregion EdgeType is ASetOfReferencesEdgeType
        //            #region EdgeType is ASingleReferenceEdgeType
        //            else if (myTypeAttribute.EdgeType is ASingleReferenceEdgeType)
        //            {
        //                //get all referenced ObjectUUIDs using the given Edge
        //                var objectUUIDs = (currentDBObject.Value.GetAttribute(myTypeAttribute.UUID) as ASingleReferenceEdgeType).GetAllReferenceIDs();
        //                ObjectUUID objectUUID = objectUUIDs.First<ObjectUUID>();
        //                ObjectUUID currentNode;
        //                #region obj is target
        //                //if the child is the target
        //                if (target.Equals(objectUUID))
        //                {
        //                    return true;
        //                }
        //                #endregion obj is target
        //                #region never seen before
        //                else if (!visitedNodes.Contains(objectUUID))
        //                {
        //                    //create new node and set nodeOfQueue as parent
        //                    currentNode = new ObjectUUID(objectUUID.ToString());
        //                    //mark the node as visited
        //                    visitedNodes.Add(currentNode);
        //                    //put created node in queue
        //                    queue.Enqueue(currentNode);
        //                }
        //                #endregion never seen before
        //            }
        //            #endregion EdgeType is ASingleReferenceEdgeType
        //            else
        //            {
        //                throw new NotImplementedException();
        //            }
        //        }
        //    }
        //    #endregion BFS
        //    return false;
        //}
        /// <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<long>> Find(IAttributeDefinition myTypeAttribute, IVertex myStart, IVertex myEnd, bool shortestOnly, bool findAll, byte myMaxDepth, byte myMaxPathLength)
        {
            #region data

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

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

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

            //current depth
            byte depth = 0;

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

            //target node, the target of the select
            Node target = new Node(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;
            }

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

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

            #endregion

            #region BFS

            //check if root node has edge and target has backwardedge
            if (!myStart.HasOutgoingEdge(myTypeAttribute.ID))
            {
                return null;
            }

            if (!myEnd.HasIncomingVertices(myEnd.VertexTypeID, 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(currentVertex.VertexID))
                {
                    continue;
                }

                visitedVertices.Add(currentVertex.VertexID);

                Node currentNode;

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

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

                    Node nextNode;

                    foreach (var vertex in vertices)
                    {
                        //create a new node and set currentNode = parent, nextNode = child
                        nextNode = new Node(vertex.VertexID, 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)
                                {
                                    //continue searching the current depth if there are any other shortest paths
                                    myMaxDepth = Convert.ToByte(depth);
                                    myMaxPathLength = Convert.ToByte(depth + 2);
                                }
                                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
                            //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();
        }