Construct version 5.3.9
An agent based modeling framework
Nodeset Class Reference

A container for nodes. More...

Public Types

using iterator = std::vector< Node >::const_iterator
 

Public Member Functions

 Nodeset (const std::string &_name)
 
 ~Nodeset ()
 Deallocates the attribute pointers of all nodes it contains.
 
iterator begin (void) const
 Returns an iterator pointing the beginning of the vector of nodes. More...
 
iterator end (void) const
 Returns an iterator pointing the beyond the last node in the vector of nodes. More...
 
unsigned int size (void) const
 Returns the number of nodes in the nodeset More...
 
bool add_node (const dynet::ParameterMap *attributes)
 Adds a node to the Nodeset. More...
 
bool add_node (const std::string &node_name, const dynet::ParameterMap *attributes)
 Adds a node to the Nodeset. More...
 
const Nodeget_node_by_index (unsigned int index) const
 Finds a node using the node's index. More...
 
const Nodeget_node_by_name (const std::string &name) const noexcept
 Finds a node using the node's name. More...
 
template<typename T >
void check_attributes (std::string attribute, T min, T max) const
 Checks that all nodes in the nodeset for the specified attribute. More...
 
template<typename T >
void check_attributes (std::string attribute) const
 Checks that all nodes in the nodeset for the specified attribute. More...
 
void turn_to_const () noexcept
 Modifies the nodeset such that is findable by this class and can no longer have nodes added to it. More...
 
void import_dynetml (const std::string &fname, const std::string &dynetml_ns_name)
 Imports information from a DyNetML style xml file into the nodeset.

Parameters
fnameThe file name with either an absolute or relative directory path.
dynetml_ns_nameThe name of nodeset stored in the DyNetML file that is to be imported.

Exception Safety More...

 
bool is_const () const noexcept
 Returns true if the nodeset can no longer be modified.
 
template<>
void check_attributes (std::string attribute) const
 
template<>
void check_attributes (std::string attribute) const
 
template<>
void check_attributes (std::string attribute) const
 
template<>
void check_attributes (std::string attribute) const
 

Public Attributes

const std::string name
 

Detailed Description

A container for nodes.

A nodeset is a container for Nodes. This includes basic functions for accessing and interacting with the nodes in the nodeset.

Nodesets are created by the NodesetManager. It is not expected that other classes in Construct would create a nodeset. Rather a pointer to an existing nodeset to find a node is the primary way a nodeset is used.

Member Function Documentation

◆ add_node() [1/2]

bool Nodeset::add_node ( const dynet::ParameterMap attributes)

Adds a node to the Nodeset.

Nodes are added to the nodeset with index equal to the previous nodeset size. The nodes name is created using the nodeset's name plus the node's index. If the submitted pointer is added to the nodeset, the nodeset assumes ownership of the pointer and will deallocate when its deconstructor is called. Ownership not being passed to the nodeset happens when the node attribute's contents equals the previous node attribute's contents, but have differing pointers. Pointers whose ownership is not transferred over should be deallocated using delete.

Parameters
attributesA pointer to the node attributes to be added. This pointer should allocated using new.
Returns
True if the pointer ownership was not transferred the nodeset and should be deallocated, and false otherwise.

Example

Nodeset* my_nodeset = construct->ns_manager->create_nodeset("my_nodeset");
my_attributes->insert(std::make_pair("my att1 name", "my att1 value"));
//At this point we know that the nodeset will take ownership of the submitted attribute pointer
//This is because only one pointer has been submitted in the nodeset's history.
my_nodeset->add_node("Mary", my_attributes);
//Once the nodeset takes ownership of the pointer, it can be repeatedly submitted to the function.
my_nodeset->add_node("Joe", my_attributes);
my_attributes = new dynet::ParameterMap();
my_attributes->insert(std::make_pair("my att1 name", "my att1 value"));
//because the nodeset will attempt to optimize memory usage, it will reject ownership of this pointer
//as its contents are equal to the previous node's (Joe) attributes.
//The nodeset will then use that attribute pointer rather than the submitted pointer.
if (my_nodeset->add_node("John", my_attributes)) {
std::cout << "attribute pointer not added and requires deallocation" << std::endl;
delete my_attributes;
}
my_attributes = new dynet::ParameterMap();
my_attributes->insert(std::make_pair("my att2 name", "my att2 value"));
//if you're sure the nodeset will not reject ownership you need not check each function return
my_nodeset->add_node("Rebecca", my_attributes);
//any previous pointer that the nodeset has taken ownership of can be used with a check on the function return
//if no name is given a unique name is given based on the nodeset name and the node's index
auto first_node = my_nodeset->begin();
my_nodeset->add_node(first_node->attributes);
for (auto node = my_nodeset->begin(); node != my_nodeset->end(); ++node) {
std::cout << "Node name, index: " << node->name << ", " << std::to_string(node->index) << std::endl;
std::cout << "Node attributes:" << std::endl;
for (auto att = node->attributes->begin(); att != node->attributes->end(); ++att) {
std::cout << "/t" << att->first << " -> " << att->second << std::endl;
}
}
A container for nodes.
Definition: NodesetManager.h:145
bool add_node(const dynet::ParameterMap *attributes)
Adds a node to the Nodeset.
Definition: NodesetManager.cpp:16
iterator end(void) const
Returns an iterator pointing the beyond the last node in the vector of nodes.
Definition: NodesetManager.cpp:9
iterator begin(void) const
Returns an iterator pointing the beginning of the vector of nodes.
Definition: NodesetManager.cpp:8
Definition: utils.h:96

Output:

attribute pointer not added and requires deallocation
Node name, index: Mary, 0
Node attributes:
    my att1 name -> my att1 value
Node name, index: Joe, 1
Node attributes:
    my att1 name -> my att1 value
Node name, index: John, 2
Node attributes:
    my att1 name -> my att1 value
Node name, index: Rebecca, 3
Node attributes:
    my att2 name -> my att2 value
Node name, index: my_nodeset_4, 4
Node attributes:
    my att1 name -> my att1 value

Complexity

Constant

Iterator validity

If a reallocation happens, all iterators, pointers and references related to the container are invalidated. Otherwise, only the end iterator is invalidated, and all iterators, pointers and references to elements are guaranteed to keep referring to the same elements they were referring to before the call.

Exception Safety

An assertion is raised if the submitted ParameterMap pointer is a NULL pointer or if the nodeset has been turned to a constant nodeset.

A dynet::already_exists is thrown if the created node name (nodeset name + "_" + index) matches any previous node name.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ add_node() [2/2]

bool Nodeset::add_node ( const std::string &  node_name,
const dynet::ParameterMap attributes 
)

Adds a node to the Nodeset.

Nodes are added to the nodeset with index equal to the previous nodeset size. The nodes name is created using the nodeset's name plus the node's index. If the submitted pointer is added to the nodeset, the nodeset assumes ownership of the pointer and will deallocate when its deconstructor is called. Ownership not being passed to the nodeset happens when the node attribute's contents equals the previous node attribute's contents, but have differing pointers. Pointers whose ownership is not transferred over should be deallocated using delete.

Parameters
node_nameName of the node to be added to the end of the Nodeset.
attributesA pointer to the node attributes to be added. This pointer should allocated using new.
Returns
True if the pointer ownership was not transferred the nodeset and should be deallocated, and false otherwise.

Example

Nodeset* my_nodeset = construct->ns_manager->create_nodeset("my_nodeset");
my_attributes->insert(std::make_pair("my att1 name", "my att1 value"));
//At this point we know that the nodeset will take ownership of the submitted attribute pointer
//This is because only one pointer has been submitted in the nodeset's history.
my_nodeset->add_node("Mary", my_attributes);
//Once the nodeset takes ownership of the pointer, it can be repeatedly submitted to the function.
my_nodeset->add_node("Joe", my_attributes);
my_attributes = new dynet::ParameterMap();
my_attributes->insert(std::make_pair("my att1 name", "my att1 value"));
//because the nodeset will attempt to optimize memory usage, it will reject ownership of this pointer
//as its contents are equal to the previous node's (Joe) attributes.
//The nodeset will then use that attribute pointer rather than the submitted pointer.
if (my_nodeset->add_node("John", my_attributes)) {
std::cout << "attribute pointer not added and requires deallocation" << std::endl;
delete my_attributes;
}
my_attributes = new dynet::ParameterMap();
my_attributes->insert(std::make_pair("my att2 name", "my att2 value"));
//if you're sure the nodeset will not reject ownership you need not check each function return
my_nodeset->add_node("Rebecca", my_attributes);
//any previous pointer that the nodeset has taken ownership of can be used with a check on the function return
//if no name is given a unique name is given based on the nodeset name and the node's index
auto first_node = my_nodeset->begin();
my_nodeset->add_node(first_node->attributes);
for (auto node = my_nodeset->begin(); node != my_nodeset->end(); ++node) {
std::cout << "Node name, index: " << node->name << ", " << std::to_string(node->index) << std::endl;
std::cout << "Node attributes:" << std::endl;
for (auto att = node->attributes->begin(); att != node->attributes->end(); ++att) {
std::cout << "/t" << att->first << " -> " << att->second << std::endl;
}
}

Output:

attribute pointer not added and requires deallocation
Node name, index: Mary, 0
Node attributes:
    my att1 name -> my att1 value
Node name, index: Joe, 1
Node attributes:
    my att1 name -> my att1 value
Node name, index: John, 2
Node attributes:
    my att1 name -> my att1 value
Node name, index: Rebecca, 3
Node attributes:
    my att2 name -> my att2 value
Node name, index: my_nodeset_4, 4
Node attributes:
    my att1 name -> my att1 value

Complexity

Constant

Iterator validity

If a reallocation happens, all iterators, pointers and references related to the container are invalidated. Otherwise, only the end iterator is invalidated, and all iterators, pointers and references to elements are guaranteed to keep referring to the same elements they were referring to before the call.

Exception Safety

An assertion is raised if the submitted ParameterMap pointer is a NULL pointer or if the nodeset has been turned to a constant nodeset.

A dynet::already_exists is thrown if the submitted node_name matches any previous node name.

Here is the call graph for this function:

◆ begin()

Nodeset::iterator Nodeset::begin ( void  ) const

Returns an iterator pointing the beginning of the vector of nodes.

Returns
A random access iterator pointing to the first node in the nodeset.

Example

//nodeset has been preloaded with some agents; Mary, John, and Joe.
const Nodeset* agents = construct->ns_manager->get_nodeset(nodeset_names::agent);
std::cout << "This nodeset conatins:" << std::endl;
for(Nodeset::iterator it = agents->begin(); it != agents->end(); ++it) {
std::cout << it->name << std::endl;
}

Output:

This nodeset contains:
Mary
John
Joe

Complexity

Constant

Iterator validity

No changes

Exception Safety

No-throw guarantee: this member function never throws exceptions.

Here is the caller graph for this function:

◆ check_attributes() [1/2]

template<typename T >
void Nodeset::check_attributes ( std::string  attribute) const

Checks that all nodes in the nodeset for the specified attribute.

The attribute values are converted to the data type dictated the explicit instantiation of the template.

Parameters
attributeName of the attribute that each node should have.

Example

const Nodeset* ns = _construct->ns_manager->get_nodeset("ns");
// following node has been loaded into the nodeset "ns" with the following attributes
// <node name="node1">
// <attribute name="attribute1" value="0.5"/>
// <attribute name="attribute2" value="-2"/>
// </node>
try {
ns->check_attributes<float>("attribute1");
ns->check_attributes<unsigned int>("attribute2");
}
std::cout << "Error: " << e.string() << std::endl;
}
void check_attributes(std::string attribute, T min, T max) const
Checks that all nodes in the nodeset for the specified attribute.
Definition: NodesetManager.cpp:137
Exception meant to add attribute information based on a could_not_convert exception.
Definition: utils.h:201

Output:

Error: Could not convert value to unsigned int for attribute "attribute2" for node "node1". 

Complexity

Linear in number of nodes in the specified nodeset.

Iterator validity

No changes.

Exception Safety

A dynet::missing_node_attribute is thrown if a node is missing the attribute. A dynet::could_not_convert_attribute is thrown if the attribute could not be converted to the data type of the template instantiation.

◆ check_attributes() [2/2]

template<typename T >
void Nodeset::check_attributes ( std::string  attribute,
min,
max 
) const

Checks that all nodes in the nodeset for the specified attribute.

These attributes are converted to the type determined by the submitted parameters. The converted values are then checked to ensure the it lies between the submitted bounds for that attribute. The only template instantiations available are int, unsigned int, float.

Parameters
attributeName of the attribute that each node should have.
minThe minimum value the attribute can have. Any attribute value that is smaller than min will cause a string exception to be thrown.
maxThe maximum value the attribute can have. Any attribute value that is greater than max will cause a string exception to be thrown.

Example

const Nodeset* ns = _construct->ns_manager->get_nodeset("ns");
// following node has been loaded into the nodeset "ns" with the following attributes
// <node name="node1">
// <attribute name="attribute1" value="0.5"/>
// <attribute name="attribute2" value="2"/>
// </node>
ns->check_attributes("attribute1", 0.0f, 1.0f);
ns->check_attributes("attribute2", 0, 1);

Output:

Error: "attribute2" for node "node1" is out of range [0,1]. 

Complexity

Linear in number of nodes in the specified nodeset.

Iterator validity

No changes.

Exception Safety

A dynet::missing_node_attribute is thrown if a node is missing the attribute. A dynet::could_not_convert_attribute is thrown if the attribute could not be converted to the template specialization. A dynet::out_of_range is thrown if the converted attribute value is greater than max or less than min.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ end()

Nodeset::iterator Nodeset::end ( void  ) const

Returns an iterator pointing the beyond the last node in the vector of nodes.

Returns
An iterator pointing to the beyond the last node in the nodeset.

Example

//nodeset has been preloaded with some agents; Mary, John, and Joe.
const Nodeset* agents = construct->ns_manager->get_nodeset(nodeset_names::agent);
std::cout << "This nodeset conatins:" << std::endl;
for(Nodeset::iterator it = agents->begin(); it != agents->end(); ++it) {
std::cout << it->name << std::endl;
}

Output:

This nodeset contains:
Mary
John
Joe

Complexity

Constant

Iterator validity

No changes

Exception Safety

No-throw guarantee: this member function never throws exceptions.

Here is the caller graph for this function:

◆ get_node_by_index()

const Node * Nodeset::get_node_by_index ( unsigned int  index) const

Finds a node using the node's index.

This function provides drastic speed up compared to get_node_by_name as this function references a vector while the former references a binary tree.

Parameters
indexThe node's index in the nodeset.
Returns
A constant pointer to the node with index matching the parameter index. Only constant functions of a class pointed to by a constant pointer can be called.

Example

//nodeset has been preloaded with some agents; Mary, John, and Joe.
const Nodeset* agents = construct->ns_manager->get_nodeset(nodeset_names::agent);
const Node* agent = agents->get_node_by_index(0);
std::cout << "Node at index 0 is " << agent->name << std::endl;
Nodes are any type of entity with or without attributes.
Definition: NodesetManager.h:67
const std::string name
Name of the node
Definition: NodesetManager.h:79

Output:

Node at index 0 is Mary 

Complexity

Constant

Iterator validity

No changes

Exception Safety

An assertion is raised if index is out of bounds for the nodeset.

Here is the caller graph for this function:

◆ get_node_by_name()

const Node * Nodeset::get_node_by_name ( const std::string &  name) const
noexcept

Finds a node using the node's name.

This function uses a binary tree to find a node, making its speed slower than get_node_by_index.

Parameters
nameThe node's name in the nodeset.
Returns
A constant pointer to the node with name matching the parameter name. Only constant functions of a class pointed to by a constant pointer can be called. If a node with the matching name is not found, a null pointer is returned instead.

Example

//nodeset has been preloaded with some agents; Mary, John, and Joe.
const Nodeset* agents = construct->ns_manager->get_nodeset(nodeset_names::agent);
const Node* agent = agents->get_node_by_name("Mary");
std::cout << "Node Mary is at index " << agent->index << std::endl;
const unsigned int index
Node index of the node
Definition: NodesetManager.h:82

Output:

Node Mary is at index 0 

Complexity

Logarithmic in size of nodeset. Underlying function uses map::find

Iterator validity

No changes

Exception Safety

No-throw guarantee: this member function never throws exceptions. If the node was not found, a null pointer is returned.

◆ import_dynetml()

void Nodeset::import_dynetml ( const std::string &  fname,
const std::string &  dynetml_ns_name 
)

Imports information from a DyNetML style xml file into the nodeset.

Parameters
fnameThe file name with either an absolute or relative directory path.
dynetml_ns_nameThe name of nodeset stored in the DyNetML file that is to be imported.

Exception Safety

Various exceptions can be raised if the DyNetML file is not formatted correctly or if information is missing.

◆ size()

unsigned int Nodeset::size ( void  ) const

Returns the number of nodes in the nodeset

Returns
A count of how many nodes are in the nodeset as an unsigned int.

Example

//nodeset has been preloaded with some agents; Mary, John, and Joe.
const Nodeset* agents = construct->ns_manager->get_nodeset(nodeset_names::agent);
std::cout << "The number of nodes in this nodeset: " << agents->size() << std::endl;

Output:

The number of nodes in this nodeset: 3 

Complexity

Constant

Iterator validity

No changes

Exception Safety

No-throw guarantee: this member function never throws exceptions.

Here is the caller graph for this function:

◆ turn_to_const()

void Nodeset::turn_to_const ( )
noexcept

Modifies the nodeset such that is findable by this class and can no longer have nodes added to it.

Once a nodeset has all the nodes that one wishes to add to this nodeset, this function should be called. If this function has been called, Nodeset::add_node will not execute any actions and return true. If this function has not been called, this class will throw a string exception when the nodeset is searched for.

Parameters
nodesetPointer to the nodeset that should be converted.

Example

Nodeset* my_nodeset = construct->ns_manager->create_nodeset("my_nodeset");
my_attributes->insert(std::make_pair("my att1 name", "my att1 value"));
//At this point we know that the nodeset will take ownership of the submitted attribute pointer
//This is because only one pointer has been submitted in the nodeset's history.
my_nodeset->add_node("Mary", my_attributes);
//Once the nodeset takes ownership of the pointer, it can be repeatedly submitted to the function.
my_nodeset->add_node("Joe", my_attributes);
my_attributes = new dynet::ParameterMap();
my_attributes->insert(std::make_pair("my att1 name", "my att1 value"));
//because the nodeset will attempt to optimize memory usage, it will reject ownership of this pointer
//as its contents are equal to the previous node's (Joe) attributes.
//The nodeset will then use that attribute pointer rather than the submitted pointer.
if (my_nodeset->add_node("John", my_attributes)) {
std::cout << "attribute pointer not added and requires deallocation" << std::endl;
delete my_attributes;
}
my_attributes = new dynet::ParameterMap();
my_attributes->insert(std::make_pair("my att2 name", "my att2 value"));
//if you're sure the nodeset will not reject ownership you need not check each function return
my_nodeset->add_node("Rebecca", my_attributes);
//any previous pointer that the nodeset has taken ownership of can be used with a check on the function return
//if no name is given a unique name is given based on the nodeset name and the node's index
auto first_node = my_nodeset->begin();
my_nodeset->add_node(first_node->attributes);
my_nodeset->turn_to_const();
const Nodeset* loaded_nodeset = construct->ns_manager->get_nodeset("my_nodeset");
for (auto node = loaded_nodeset->begin(); node != loaded_nodeset->end(); ++node) {
std::cout << "Node name, index: " << node->name << ", " << std::to_string(node->index) << std::endl;
std::cout << "Node attributes:" << std::endl;
for (auto att = node->attributes->begin(); att != node->attributes->end(); ++att) {
std::cout << "/t" << att->first << " -> " << att->second << std::endl;
}
}
const std::string name
Definition: NodesetManager.h:156
void turn_to_const() noexcept
Modifies the nodeset such that is findable by this class and can no longer have nodes added to it.
Definition: NodesetManager.cpp:76

Output:

attribute pointer not added and requires deallocation
Node name, index: Mary, 0
Node attributes:
    my att1 name -> my att1 value
Node name, index: Joe, 1
Node attributes:
    my att1 name -> my att1 value
Node name, index: John, 2
Node attributes:
    my att1 name -> my att1 value
Node name, index: Rebecca, 3
Node attributes:
    my att2 name -> my att2 value
Node name, index: my_nodeset_4, 4
Node attributes:
    my att1 name -> my att1 value

Complexity

Average is constant. The number of nodesets is not expected to be large. Underlying function uses unordered_map::find

Exception Safety

No-throw guarantee: this member function never throws exceptions.

Member Data Documentation

◆ name

const std::string Nodeset::name