Пример #1
0
        /// <summary>
        /// Gets the closest synset that is reachable from the current and another synset along the given relations. For example,
        /// given two synsets and the Hypernym relation, this will return the lowest synset that is a hypernym of both synsets. If
        /// the hypernym hierarchy forms a tree, this will be the lowest common ancestor.
        /// </summary>
        /// <param name="synset">Other synset</param>
        /// <param name="relations">Relations to follow</param>
        /// <returns>Closest mutually reachable synset</returns>
        public SynSet GetClosestMutuallyReachableSynset(SynSet synset, IEnumerable <WordNetEngine.SynSetRelation> relations)
        {
            // avoid cycles
            Set <SynSet> synsetsEncountered = new Set <SynSet>();

            synsetsEncountered.Add(this);

            // start search queue
            Queue <SynSet> searchQueue = new Queue <SynSet>();

            searchQueue.Enqueue(this);

            // run search
            SynSet closest = null;

            while (searchQueue.Count > 0 && closest == null)
            {
                SynSet currSynSet = searchQueue.Dequeue();

                /* check for a path between the given synset and the current one. if such a path exists, the current
                 * synset is the closest mutually reachable synset. */
                if (synset.GetShortestPathTo(currSynSet, relations) != null)
                {
                    closest = currSynSet;
                }
                // otherwise, expand the search along the given relations
                else
                {
                    foreach (SynSet relatedSynset in currSynSet.GetRelatedSynSets(relations, false))
                    {
                        if (!synsetsEncountered.Contains(relatedSynset))
                        {
                            searchQueue.Enqueue(relatedSynset);
                            synsetsEncountered.Add(relatedSynset);
                        }
                    }
                }
            }

            return(closest);
        }
Пример #2
0
        /// <summary>
        /// Gets the shortest path from the current synset to another, following the given synset relations.
        /// </summary>
        /// <param name="destination">Destination synset</param>
        /// <param name="relations">Relations to follow, or null for all relations.</param>
        /// <returns>Synset path, or null if none exists.</returns>
        public List <SynSet> GetShortestPathTo(SynSet destination, IEnumerable <WordNetEngine.SynSetRelation> relations)
        {
            if (relations == null)
            {
                relations = Enum.GetValues(typeof(WordNetEngine.SynSetRelation)) as WordNetEngine.SynSetRelation[];
            }

            // make sure the backpointer on the current synset is null - can't predict what other functions might do
            _searchBackPointer = null;

            // avoid cycles
            Set <SynSet> synsetsEncountered = new Set <SynSet>();

            synsetsEncountered.Add(this);

            // start search queue
            Queue <SynSet> searchQueue = new Queue <SynSet>();

            searchQueue.Enqueue(this);

            // run search
            List <SynSet> path = null;

            while (searchQueue.Count > 0 && path == null)
            {
                SynSet currSynSet = searchQueue.Dequeue();

                // see if we've finished the search
                if (currSynSet == destination)
                {
                    // gather synsets along path
                    path = new List <SynSet>();
                    while (currSynSet != null)
                    {
                        path.Add(currSynSet);
                        currSynSet = currSynSet.SearchBackPointer;
                    }

                    // reverse for the correct order
                    path.Reverse();
                }
                // expand the search one level
                else
                {
                    foreach (SynSet synset in currSynSet.GetRelatedSynSets(relations, false))
                    {
                        if (!synsetsEncountered.Contains(synset))
                        {
                            synset.SearchBackPointer = currSynSet;
                            searchQueue.Enqueue(synset);

                            synsetsEncountered.Add(synset);
                        }
                    }
                }
            }

            // null-out all search backpointers
            foreach (SynSet synset in synsetsEncountered)
            {
                synset.SearchBackPointer = null;
            }

            return(path);
        }