/// <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<SynSetRelation> relations) { var synSetRelations = relations as SynSetRelation[] ?? Enumerable.ToArray(relations); var synsetsEncountered = new List<SynSet> { this }; var searchQueue = new Queue<SynSet>(); searchQueue.Enqueue(this); // run search SynSet closest = null; while (searchQueue.Count > 0 && closest == null) { var 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, synSetRelations) != null) closest = currSynSet; // otherwise, expand the search along the given relations else foreach (var relatedSynset in currSynSet.GetRelatedSynSets(synSetRelations, false)) if (!synsetsEncountered.Contains(relatedSynset)) { searchQueue.Enqueue(relatedSynset); synsetsEncountered.Add(relatedSynset); } } return closest; }
/// <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 <SynSetRelation> relations) { var synSetRelations = relations == null ? Enum.GetValues(typeof(SynSetRelation)) as SynSetRelation[] : (relations as SynSetRelation[] ?? Enumerable.ToArray(relations)); // make sure the backpointer on the current synset is null - can't predict what other functions might do SearchBackPointer = null; // avoid cycles var synsetsEncountered = new List <SynSet> { this }; // start search queue var searchQueue = new Queue <SynSet>(); searchQueue.Enqueue(this); // run search List <SynSet> path = null; while (searchQueue.Count > 0 && path == null) { var 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 (var synset in currSynSet.GetRelatedSynSets(synSetRelations, false)) { if (!synsetsEncountered.Contains(synset)) { synset.SearchBackPointer = currSynSet; searchQueue.Enqueue(synset); synsetsEncountered.Add(synset); } } } } // null-out all search backpointers foreach (var synset in synsetsEncountered) { synset.SearchBackPointer = null; } return(path); }
/// <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<SynSetRelation> relations) { var synSetRelations = relations == null ? Enum.GetValues(typeof(SynSetRelation)) as SynSetRelation[] : (relations as SynSetRelation[] ?? Enumerable.ToArray(relations)); // make sure the backpointer on the current synset is null - can't predict what other functions might do SearchBackPointer = null; // avoid cycles var synsetsEncountered = new List<SynSet> { this }; // start search queue var searchQueue = new Queue<SynSet>(); searchQueue.Enqueue(this); // run search List<SynSet> path = null; while (searchQueue.Count > 0 && path == null) { var 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 (var synset in currSynSet.GetRelatedSynSets(synSetRelations, false)) if (!synsetsEncountered.Contains(synset)) { synset.SearchBackPointer = currSynSet; searchQueue.Enqueue(synset); synsetsEncountered.Add(synset); } } } // null-out all search backpointers foreach (var synset in synsetsEncountered) synset.SearchBackPointer = null; return path; }