gov.sandia.cognition.framework.DefaultSemanticNetwork Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cognitive-foundry Show documentation
Show all versions of cognitive-foundry Show documentation
A single jar with all the Cognitive Foundry components.
/*
* File: DefaultSemanticNetwork.java
* Authors: Justin Basilico and Kevin R. Dixon
* Company: Sandia National Laboratories
* Project: Cognitive Framework Lite
*
* Copyright February 10, 2006, Sandia Corporation. Under the terms of Contract
* DE-AC04-94AL85000, there is a non-exclusive license for use of this work by
* or on behalf of the U.S. Government. Export of this program may require a
* license from the United States Government. See CopyrightHistory.txt for
* complete details.
*
*
*/
package gov.sandia.cognition.framework;
import java.util.Collection;
import java.util.TreeMap;
/**
* This class contains a default implementation of a SemanticNetwork. It uses
* a sparse graph representation using TreeMaps to map from nodes to links.
* All of the links are doubly linked, being stored by both their from and to
* nodes. This allows for fast addition, removal, and lookup.
*
* @author Justin Basilico
* @author Kevin R. Dixon
* @since 1.0
*/
public class DefaultSemanticNetwork
extends java.lang.Object
implements SemanticNetwork
{
/**
* The mapping of labels onto nodes in the network.
*/
private TreeMap
labelNodeMap = null;
/**
* Creates a new instance of DefaultSemanticNetwork
*/
public DefaultSemanticNetwork()
{
super();
this.setLabelNodeMap(
new TreeMap());
}
/**
* {@inheritDoc}
*
* @return {@inheritDoc}
*/
public int getNumNodes()
{
return this.getLabelNodeMap().size();
}
/**
* {@inheritDoc}
*
* @param label {@inheritDoc}
* @return {@inheritDoc}
*/
public boolean isNode(
SemanticLabel label)
{
return this.getLabelNodeMap().containsKey(label);
}
/**
* {@inheritDoc}
*
* @return {@inheritDoc}
*/
public Collection getNodes()
{
return this.getLabelNodeMap().keySet();
}
/**
* {@inheritDoc}
*
* @param nodeLabel {@inheritDoc}
* @return {@inheritDoc}
*/
public Collection getOutLinks(
SemanticLabel nodeLabel)
{
DefaultSemanticNetworkNode node = this.getLabelNodeMap().get(nodeLabel);
if ( node == null )
{
// No such node.
return null;
}
else
{
return node.getOutLinks().keySet();
}
}
/**
* {@inheritDoc}
*
* @param from {@inheritDoc}
* @param to {@inheritDoc}
* @return {@inheritDoc}
*/
public double getAssociation(
SemanticLabel from,
SemanticLabel to)
{
// Get the link between the nodes.
DefaultSemanticNetworkLink link = this.getLink(from, to);
if ( link == null )
{
// No association.
return 0.0;
}
else
{
// Return the weight.
return link.getWeight();
}
}
/**
* Adds a node to the semantic network. If the node is already in the
* network then nothing changes.
*
* @param nodeLabel The semantic label of the node.
*/
public void addNode(
SemanticLabel nodeLabel)
{
if ( this.isNode(nodeLabel) )
{
// This is already a node so do nothing.
return;
}
// Add the node.
this.getLabelNodeMap().put(
nodeLabel, new DefaultSemanticNetworkNode(nodeLabel));
}
/**
* Removes a node from the semantic network including all of the incoming
* and outgoing links of the node. If the node is not in the network then
* nothing changes.
*
* @param nodeLabel The node to remove from the network.
*/
public void removeNode(
SemanticLabel nodeLabel)
{
// Remove the node from our node table.
DefaultSemanticNetworkNode node =
this.getLabelNodeMap().remove(nodeLabel);
if ( node == null )
{
// DefaultSemanticNetworkNode was already removed so
// that there is nothing to update.
return;
}
// Remove the links that the node has outgoing links to.
for ( DefaultSemanticNetworkLink link : node.getOutLinks().values() )
{
link.getToNode().getInLinks().remove(nodeLabel);
}
// Remove the links that the node has incoming links from.
for ( DefaultSemanticNetworkLink link : node.getInLinks().values() )
{
link.getFromNode().getOutLinks().remove(nodeLabel);
}
}
/**
* Sets the association between two nodes in the network.
*
* @param from The node that the link is from.
* @param to The node that the link is to.
* @param weight The weight of the association.
* @throws IllegalArgumentException Thrown if either the from or to node
* is not in the network.
*/
public void setAssociation(
SemanticLabel from,
SemanticLabel to,
double weight)
{
// Get the from and to nodes.
DefaultSemanticNetworkNode fromNode = this.getLabelNodeMap().get(from);
DefaultSemanticNetworkNode toNode = this.getLabelNodeMap().get(to);
if ( fromNode == null )
{
// Error: Bad from node.
throw new IllegalArgumentException("No such 'from node' exists.");
}
else if ( toNode == null )
{
// Error: Bad to node.
throw new IllegalArgumentException("No such 'to node' exists.");
}
// Look for the link between the two nodes, if it exists.
DefaultSemanticNetworkLink link = this.getLink(from, to);
if ( link != null )
{
if ( weight == 0.0 )
{
// The association is now zero so remove the link from the
// nodes.
link.getFromNode().getOutLinks().remove(to);
link.getToNode().getInLinks().remove(from);
}
else
{
// Set the association
link.setWeight(weight);
}
}
else if ( weight != 0.0 )
{
// Create the link between the nodes.
link = new DefaultSemanticNetworkLink(fromNode, toNode, weight);
fromNode.getOutLinks().put(to, link);
toNode.getInLinks().put(from, link);
}
// else - The weight was zero so there is nothing to update.
}
/**
* Gets the DefaultSemanticNetwork between two nodes if it exists,
* otherwise it returns null.
*
* @param from The from node.
* @param to The to node.
* @return The DefaultSemanticNetwork between the two given nodes,
* if one exists.
*/
private DefaultSemanticNetworkLink getLink(
SemanticLabel from,
SemanticLabel to)
{
if ( from == null || to == null )
{
// Error: Bad parameter.
return null;
}
// Get the two nodes.
DefaultSemanticNetworkNode fromNode = this.getLabelNodeMap().get(from);
DefaultSemanticNetworkNode toNode = this.getLabelNodeMap().get(to);
if ( fromNode == null || toNode == null )
{
// One of the nodes was not good.
return null;
}
// Attempt to get the link.
return fromNode.getOutLinks().get(to);
}
/**
* Getter for labelNodeMap
*
* @return The mapping of labels onto nodes in the network.
*/
TreeMap
getLabelNodeMap()
{
return this.labelNodeMap;
}
/**
* Setter for labelNodeMap
*
* @param labelNodeMap The mapping of labels onto nodes in the network.
*/
void setLabelNodeMap(
TreeMap labelNodeMap)
{
if( labelNodeMap == null )
{
// Error: Bad nodes.
throw new NullPointerException("The nodes cannot be null.");
}
this.labelNodeMap = labelNodeMap;
}
/**
* The DefaultSemanticNetworkNode class represents a node in the
* semantic network.
*
* @author Justin Basilico
* @since 1.0
*/
private static class DefaultSemanticNetworkNode
extends java.lang.Object
{
/** The SemanticLabel of the node. */
private SemanticLabel label = null;
/** The mapping of incoming links to the node. */
private TreeMap
inLinks = null;
/** The mapping of outgoing links from the node. */
private TreeMap
outLinks = null;
/**
* Creates a new instance of DefaultSemanticNetworkNode.
*
* @param label The label for the DefaultSemanticNetworkNode.
*/
private DefaultSemanticNetworkNode(
SemanticLabel label)
{
super();
this.setLabel(label);
this.setInLinks(
new TreeMap());
this.setOutLinks(
new TreeMap());
}
/**
* Gets the label of the node.
*
* @return The label of the node.
*/
private SemanticLabel getLabel()
{
return this.label;
}
/**
* Gets the links going into the node.
*
* @return The links going into the node.
*/
private TreeMap getInLinks()
{
return this.inLinks;
}
/**
* Gets the links coming out of a node.
*
* @return The links coming out of a node.
*/
private TreeMap getOutLinks()
{
return this.outLinks;
}
/**
* Sets the label of the node.
*
* @param label The new label.
*/
private void setLabel(
SemanticLabel label)
{
this.label = label;
}
/**
* Sets the incoming links for the node.
*
* @param inLinks The incoming links.
*/
private void setInLinks(
TreeMap inLinks)
{
this.inLinks = inLinks;
}
/**
* Sets the outgoing links of the node.
*
* @param outLinks The outgoing links.
*/
private void setOutLinks(
TreeMap outLinks)
{
this.outLinks = outLinks;
}
}
/**
* The DefaultSemanticNetworkLink class represents a link between two
* nodes in the semantic network.
*
* @author Justin Basilico
* @since 1.0
*/
private static class DefaultSemanticNetworkLink
extends java.lang.Object
{
/**
* The DefaultSemanticNetworkNode the link comes from.
*/
private DefaultSemanticNetworkNode fromNode = null;
/** The node the link goes to. */
private DefaultSemanticNetworkNode toNode = null;
/** The weight strength of the link. */
private double weight = 0.0;
/**
* Creates a new instance of DefaultSemanticNetworkLink.
*
* @param fromNode The node the link comes from.
* @param toNode The node the link goes to.
* @param weight The assocation weight between the two nodes.
*/
private DefaultSemanticNetworkLink(
DefaultSemanticNetworkNode fromNode,
DefaultSemanticNetworkNode toNode,
double weight)
{
super();
this.setFromNode(fromNode);
this.setToNode(toNode);
this.setWeight(weight);
}
/**
* Gets the node the link comes from.
*
* @return The DefaultSemanticNetworkNode that the link comes from.
*/
private DefaultSemanticNetworkNode getFromNode()
{
return this.fromNode;
}
/**
* Gets the node that the link goes to.
*
* @return The DefaultSemanticNetworkNode that the link goes to.
*/
private DefaultSemanticNetworkNode getToNode()
{
return this.toNode;
}
/**
* Gets the association weight between the nodes.
*
* @return The association weight between the nodes.
*/
private double getWeight()
{
return this.weight;
}
/**
* Sets the node the link comes from.
*
* @param fromNode The new from DefaultSemanticNetworkNode.
*/
private void setFromNode(
DefaultSemanticNetworkNode fromNode)
{
this.fromNode = fromNode;
}
/**
* Sets the node the link goes to.
*
* @param toNode The new to DefaultSemanticNetworkNode.
*/
private void setToNode(
DefaultSemanticNetworkNode toNode)
{
this.toNode = toNode;
}
/**
* Sets the association weight between the nodes.
*
* @param weight The new weight.
*/
private void setWeight(
double weight)
{
this.weight = weight;
}
}
}