import java.util.ArrayList;
import edu.smu.tspell.wordnet.NounSynset;
import edu.smu.tspell.wordnet.Synset;
import edu.smu.tspell.wordnet.SynsetType;
import edu.smu.tspell.wordnet.VerbSynset;
import edu.smu.tspell.wordnet.WordNetDatabase;
/**
*
*/
/**
* @author Abhijeet
* @this class implements Dijkstra's to find the shortest path between two synsets
*
*/
public class PathSimilarity {
WordNetDatabase wordnet;
public PathSimilarity()
{
wordnet = CalculateSimilarity.wordnet;
}
/*@params
* Synset source
* Synset target
* ArrayList<Vertex> unvisited
* ArrayList<Vertex> path
* returns path
*/
private ArrayList<Vertex> Dijkstras(Synset source , Synset target)
{
int edgeWeight = 1;
ArrayList<Vertex> unvisited = new ArrayList<Vertex>();
ArrayList<Vertex> path = new ArrayList<Vertex>();
Vertex current = null;
// create a vertex for source
Vertex node = new Vertex();
node.synset = source;
node.dist = 0; // set source distance to 0
// add source to unvisited
unvisited.add(node);
while(!unvisited.isEmpty())
{
ArrayList<NounSynset> noun_neighbours = new ArrayList<NounSynset>();
ArrayList<VerbSynset> verb_neighbours = new ArrayList<VerbSynset>();
// find from unvisited the node with least distance
// use brute force for now...later sort using QuickSort
int min = Integer.MAX_VALUE;
for(Vertex v : unvisited)
{
if(v.dist < min)
{
min = v.dist;
current = v; // current points to the node with minimum distance
}
}
if(current.dist == Integer.MAX_VALUE)
{
break; // all remaining vertices are inaccessible
}
// add it to the path list
path.add(current);
// if reached target then return the path
if(current.synset.equals(target))
{
return path;
}
/* if(unvisited.size() > bound)
{
System.out.println("MEMORY LIMIT REACHED");
return null;
}*/
// get all the neighbours of the current node
if(current.synset.getType() == SynsetType.NOUN)
{
NounSynset nounsyn = (NounSynset) (current.synset);
NounSynset [] hyponyms = nounsyn.getHyponyms();
NounSynset [] hypernyms = nounsyn.getHypernyms();
// NounSynset[] partMeronyms = nounsyn.getPartMeronyms();
// NounSynset[] memberMeronyms = nounsyn.getMemberMeronyms();
// add all the neighbours in a single arraylist
if(hyponyms != null)
for(int i = 0 ; i < hyponyms.length ; i++)
noun_neighbours.add(hyponyms[i]);
if(hypernyms != null)
for(int i = 0 ; i < hypernyms.length ; i++)
noun_neighbours.add(hypernyms[i]);
// if(partMeronyms != null)
// for(int i = 0 ; i < partMeronyms.length ; i++)
// noun_neighbours.add(partMeronyms[i]);
// if(memberMeronyms != null)
// for(int i = 0 ; i < memberMeronyms.length ; i++)
// noun_neighbours.add(memberMeronyms[i]);
boolean found = false;
Vertex neighbourVertex = null;
for(NounSynset n : noun_neighbours)
{
for(Vertex v : unvisited)
if(v.synset.equals(n))
{
found = true;
neighbourVertex = v;
}
else
{
found = false;
neighbourVertex = null;
}
if(!found) // if not added to unvisited do the following
{
Vertex ver = new Vertex(); // create a vertex for them
ver.dist = current.dist + edgeWeight; // calculate their distance from the current node
ver.synset = n;
ver.previous = current; // make previous as current
unvisited.add(ver); // and add them to the unvisited list
}
if(found) // if already added to list do the following
{
if(neighbourVertex.dist > (current.dist + edgeWeight)) // check their distance from current node
neighbourVertex.dist = current.dist + edgeWeight; // if existing distance greater then replace
neighbourVertex.previous = current; // make previous as current
}
}
}
if(current.synset.getType() == SynsetType.VERB)
{
VerbSynset verbsyn = (VerbSynset) (current.synset);
VerbSynset [] hypernyms = verbsyn.getHypernyms();
VerbSynset [] troponyms = verbsyn.getTroponyms();
// add all the neighbours in a single arraylist
if(hypernyms != null)
for(int i = 0 ; i < hypernyms.length ; i++)
verb_neighbours.add(hypernyms[i]);
if(troponyms != null)
for(int i = 0 ; i < troponyms.length ; i++)
verb_neighbours.add(troponyms[i]);
boolean found = false;
Vertex neighbourVertex = null;
for(VerbSynset n : verb_neighbours)
{
for(Vertex v : unvisited)
if(v.synset.equals(n))
{
found = true;
neighbourVertex = v;
}
else
{
found = false;
neighbourVertex = null;
}
if(!found) // if not added to unvisited do the following
{
Vertex ver = new Vertex(); // create a vertex for them
ver.dist = current.dist + edgeWeight; // calculate their distance from the current node
ver.synset = n;
ver.previous = current; // make previous as current
unvisited.add(ver); // and add them to the unvisited list
}
if(found) // if already added to list do the following
{
if(neighbourVertex.dist > (current.dist + edgeWeight)) // check their distance from current node
neighbourVertex.dist = current.dist + edgeWeight; // if existing distance greater then replace
neighbourVertex.previous = current; // make previous as current
}
}
}
// remove the current node from unvisited
unvisited.remove(current);
}
return null;
}
public double getPathSimilarity(Synset s1 , Synset s2)
{
ArrayList<Vertex> path = Dijkstras(s1,s2);
if(path != null)
{
// System.out.println("GLOSS OF SOURCE = "+path.get(0).synset.getDefinition());
// System.out.println("GLOSS OF TARGET = "+path.get(path.size()-1).synset.getDefinition());
int numberOfNodes = path.size();
System.out.println("Number of nodes in path = " +path.size());
return (double)1/numberOfNodes;
}
return 0;
}
// inner class vertex
private class Vertex{
int dist = Integer.MAX_VALUE;
Vertex previous = null;
Synset synset;
}
}