public List <LinkedList <UserNode> > GetShortestPaths(UserNode user1, UserNode user2)
        {
            var shortestPaths = new List <LinkedList <UserNode> >();

            if (user1 == user2)
            {
                shortestPaths.Add(new LinkedList <UserNode>(new UserNode[] { user1 }));
                return(shortestPaths);
            }

            if (user1.Friends.Contains(user2))
            {
                shortestPaths.Add(new LinkedList <UserNode>(new UserNode[] { user1, user2 }));
                return(shortestPaths);
            }

            var queue          = new Queue <LinkedList <UserNode> >();
            var checkedFriends = new HashSet <UserNode>();
            int closest        = int.MaxValue;

            foreach (var friend in user1.Friends)
            {
                var list = new LinkedList <UserNode>(new UserNode[] { user1, friend });
                queue.Enqueue(list);
                checkedFriends.Add(friend);
            }

            while (queue.Count > 0)
            {
                var list = queue.Dequeue();
                foreach (var friend in list.Last.Value.Friends)
                {
                    var newList = new LinkedList <UserNode>(list);
                    newList.AddLast(friend);
                    if (friend == user2 && closest >= newList.Count)
                    {
                        shortestPaths.Add(newList);
                        closest = newList.Count;
                    }
                    if (!checkedFriends.Contains(friend))
                    {
                        checkedFriends.Add(friend);
                    }
                    if (newList.Count < closest)
                    {
                        queue.Enqueue(newList);
                    }
                }
            }

            return(shortestPaths);
        }
        public List <UserNode> GetFriendsOfFriends(UserNode user, int depth)
        {
            if (depth < 1)
            {
                throw new ArgumentOutOfRangeException("Depth must be at least 1.");
            }

            int currentDepth = 1;

            HashSet <UserNode>     friends         = new HashSet <UserNode>();
            Queue <FriendDistance> friendsToDeepen = new Queue <FriendDistance>();
            HashSet <UserNode>     friendsDeepened = new HashSet <UserNode>();

            foreach (var friend in user.Friends)
            {
                friends.Add(friend);
                friendsDeepened.Add(friend);
            }
            if (depth > currentDepth)
            {
                foreach (var friend in user.Friends)
                {
                    friendsDeepened.Add(friend);
                    friendsToDeepen.Enqueue(new FriendDistance {
                        Friend = friend, Distance = currentDepth
                    });
                }
            }

            while (friendsToDeepen.Count > 0)
            {
                var friendDistance = friendsToDeepen.Dequeue();
                friends.Add(friendDistance.Friend);
                if (friendDistance.Distance < depth)
                {
                    foreach (var friend in friendDistance.Friend.Friends)
                    {
                        if (!friendsDeepened.Contains(friend))
                        {
                            friendsToDeepen.Enqueue(new FriendDistance {
                                Friend = friend, Distance = currentDepth
                            });
                            friendsDeepened.Add(friend);
                        }
                    }
                }
            }

            return(friends.ToList());
        }
        /// <summary>
        /// Gets the distance between two users in the graph using BFS.
        /// </summary>
        /// <param name="user1">Starting user.</param>
        /// <param name="user2">Target user.</param>
        /// <returns>The distance between two users or -1 if they have no connections.</returns>
        public int GetDistance(UserNode user1, UserNode user2)
        {
            if (user1 == user2)
            {
                return(0);
            }

            if (user1.Friends.Contains(user2))
            {
                return(1);
            }

            Queue <FriendDistance> queue          = new Queue <FriendDistance>();
            HashSet <UserNode>     checkedFriends = new HashSet <UserNode>();

            foreach (var friend in user1.Friends)
            {
                queue.Enqueue(new FriendDistance {
                    Friend = friend, Distance = 1
                });
            }

            while (queue.Count > 0)
            {
                var friendDistance = queue.Dequeue();
                foreach (var friend in friendDistance.Friend.Friends)
                {
                    if (friend == user2)
                    {
                        return(friendDistance.Distance + 1);
                    }
                    else
                    {
                        if (!checkedFriends.Contains(friend))
                        {
                            queue.Enqueue(new FriendDistance {
                                Friend = friend, Distance = friendDistance.Distance + 1
                            });
                            checkedFriends.Add(friend);
                        }
                    }
                }
            }

            return(-1);
        }
示例#4
0
        public HashSet <UserNode> FriendsOfFriends(UserNode start, int distance)
        {
            Queue <UserNode>   users      = new Queue <UserNode>();
            HashSet <UserNode> discovered = new HashSet <UserNode> {
                start
            };
            HashSet <UserNode> results   = new HashSet <UserNode>();
            List <int>         distances = new List <int> {
                0
            };

            users.Enqueue(start);
            int counter = 0;
            int searchDistance;

            while (users.Count > 0)
            {
                searchDistance = distances[counter];
                var v = users.Dequeue();
                if (searchDistance > distance)
                {
                    results.Remove(start);
                    return(results);
                }
                counter++;
                searchDistance++;
                foreach (var friend in v.Friends)
                {
                    if (!discovered.Contains(friend))
                    {
                        discovered.Add(friend);
                        users.Enqueue(friend);
                        distances.Add(searchDistance);
                    }
                    if (searchDistance <= distance)
                    {
                        results.Add(friend);
                    }
                }
            }
            results.Remove(start);
            return(results);
        }
示例#5
0
        public static int DistanceBetweenUsers(UserNode user1, UserNode user2)
        {
            Queue <UserNode>   userQueue = new Queue <UserNode>();
            HashSet <UserNode> lookedAt  = new HashSet <UserNode>()
            {
                user1
            };

            userQueue.Enqueue(user1);
            int distance = 1;

            while (userQueue.Count != 0)
            {
                userQueue = GetFriends(userQueue, lookedAt);
                if (userQueue.Contains(user2))
                {
                    return(distance);
                }
                distance++;
            }
            return(-1);
        }
示例#6
0
        public int DistanceBetween(UserNode start, UserNode end)
        {
            Queue <UserNode>   users      = new Queue <UserNode>();
            HashSet <UserNode> discovered = new HashSet <UserNode> {
                start
            };
            List <int> distances = new List <int> {
                0
            };

            users.Enqueue(start);
            int counter = 0;
            int distance;

            while (users.Count > 0)
            {
                distance = distances[counter];
                var v = users.Dequeue();
                if (v.Equals(end))
                {
                    return(distance);
                }
                counter++;
                distance++;
                foreach (var friend in v.Friends)
                {
                    if (!discovered.Contains(friend))
                    {
                        discovered.Add(friend);
                        users.Enqueue(friend);
                        distances.Add(distance);
                    }
                }
            }
            return(0);
        }
示例#7
0
 public void AddFriend(UserNode friend)
 {
     Friends.Add(friend);
     friend.Friends.Add(this);
 }
        private IEnumerable <UserNode> ReconstructShortestPath(Dictionary <UserNode, UserNode> path, UserNode start, UserNode end)
        {
            var shortestPath = new Stack <UserNode>();
            var currentNode  = end;

            while (currentNode != start)
            {
                shortestPath.Push(currentNode);
                currentNode = path[currentNode];
            }

            shortestPath.Push(start);

            return(shortestPath);
        }
 public int GetShortestDistanceBetweenNodes(UserNode start, UserNode end)
 {
     return(GetShortestPathBetweenNodes(start, end).Count - 1);
 }
 public void Add(UserNode user)
 {
     _users.Add(user);
 }
示例#11
0
 public HashSet <UserNode> ShortestPathBetween(UserNode start, UserNode end)
 {
     throw new NotImplementedException();
 }
示例#12
0
 public void DistanceRec(UserNode current, UserNode searched)
 {
 }
 public int MinDistanceFrom(UserNode b)
 {
     return(MinDistanceBetween(this, b));
 }
示例#14
0
 static List <List <UserNode> > ShortestPathBetweenUsers(UserNode user1, UserNode user2)
 {
     throw new NotImplementedException();
 }