mirror of
https://gitcode.com/gh_mirrors/ope/OpenFace.git
synced 2026-05-14 03:12:42 +00:00
Master commit of OpenFace.
This commit is contained in:
628
lib/3rdParty/dlib/include/dlib/graph/graph_kernel_1.h
vendored
Normal file
628
lib/3rdParty/dlib/include/dlib/graph/graph_kernel_1.h
vendored
Normal file
@@ -0,0 +1,628 @@
|
||||
// Copyright (C) 2007 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_GRAPH_KERNEl_1_
|
||||
#define DLIB_GRAPH_KERNEl_1_
|
||||
|
||||
#include "../serialize.h"
|
||||
#include "../noncopyable.h"
|
||||
#include "../std_allocator.h"
|
||||
#include "../smart_pointers.h"
|
||||
#include "../algs.h"
|
||||
#include <vector>
|
||||
#include "graph_kernel_abstract.h"
|
||||
#include "../is_kind.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <typename node_type, typename graph, bool is_checked>
|
||||
struct graph_checker_helper
|
||||
{
|
||||
/*!
|
||||
This object is used to check preconditions based on the value of is_checked
|
||||
!*/
|
||||
|
||||
static void check_neighbor (
|
||||
unsigned long edge_index,
|
||||
const node_type& self
|
||||
)
|
||||
{
|
||||
// make sure requires clause is not broken
|
||||
DLIB_CASSERT(edge_index < self.number_of_neighbors(),
|
||||
"\tnode_type& graph::node_type::neighbor(edge_index)"
|
||||
<< "\n\tYou have specified an invalid index"
|
||||
<< "\n\tedge_index: " << edge_index
|
||||
<< "\n\tnumber_of_neighbors(): " << self.number_of_neighbors()
|
||||
<< "\n\tthis: " << &self
|
||||
);
|
||||
}
|
||||
|
||||
static void check_edge (
|
||||
unsigned long edge_index,
|
||||
const node_type& self
|
||||
)
|
||||
{
|
||||
// make sure requires clause is not broken
|
||||
DLIB_CASSERT(edge_index < self.number_of_neighbors(),
|
||||
"\tE& graph::node_type::edge(edge_index)"
|
||||
<< "\n\tYou have specified an invalid index"
|
||||
<< "\n\tedge_index: " << edge_index
|
||||
<< "\n\tnumber_of_neighbors(): " << self.number_of_neighbors()
|
||||
<< "\n\tthis: " << &self
|
||||
);
|
||||
}
|
||||
|
||||
static void check_node (
|
||||
unsigned long index,
|
||||
const graph& self
|
||||
)
|
||||
{
|
||||
// make sure requires clause is not broken
|
||||
DLIB_CASSERT(index < self.number_of_nodes(),
|
||||
"\tnode_type& graph::node(index)"
|
||||
<< "\n\tYou have specified an invalid index"
|
||||
<< "\n\tindex: " << index
|
||||
<< "\n\tnumber_of_nodes(): " << self.number_of_nodes()
|
||||
<< "\n\tthis: " << &self
|
||||
);
|
||||
}
|
||||
|
||||
static void check_has_edge (
|
||||
unsigned long node_index1,
|
||||
unsigned long node_index2,
|
||||
const graph& self
|
||||
)
|
||||
{
|
||||
// make sure requires clause is not broken
|
||||
DLIB_CASSERT(node_index1 < self.number_of_nodes() &&
|
||||
node_index2 < self.number_of_nodes(),
|
||||
"\tvoid graph::has_edge(node_index1, node_index2)"
|
||||
<< "\n\tYou have specified an invalid index"
|
||||
<< "\n\tnode_index1: " << node_index1
|
||||
<< "\n\tnode_index2: " << node_index2
|
||||
<< "\n\tnumber_of_nodes(): " << self.number_of_nodes()
|
||||
<< "\n\tthis: " << &self
|
||||
);
|
||||
}
|
||||
|
||||
static void check_add_edge (
|
||||
unsigned long node_index1,
|
||||
unsigned long node_index2,
|
||||
const graph& self
|
||||
)
|
||||
{
|
||||
DLIB_CASSERT(node_index1 < self.number_of_nodes() &&
|
||||
node_index2 < self.number_of_nodes(),
|
||||
"\tvoid graph::add_edge(node_index1, node_index2)"
|
||||
<< "\n\tYou have specified an invalid index"
|
||||
<< "\n\tnode_index1: " << node_index1
|
||||
<< "\n\tnode_index2: " << node_index2
|
||||
<< "\n\tnumber_of_nodes(): " << self.number_of_nodes()
|
||||
<< "\n\tthis: " << &self
|
||||
);
|
||||
|
||||
DLIB_CASSERT( self.has_edge(node_index1, node_index2) == false,
|
||||
"\tvoid graph::add_edge(node_index1, node_index2)"
|
||||
<< "\n\tYou can't add an edge if it already exists in the graph"
|
||||
<< "\n\tnode_index1: " << node_index1
|
||||
<< "\n\tnode_index2: " << node_index2
|
||||
<< "\n\tnumber_of_nodes(): " << self.number_of_nodes()
|
||||
<< "\n\tthis: " << &self
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
static void check_remove_edge (
|
||||
unsigned long node_index1,
|
||||
unsigned long node_index2,
|
||||
const graph& self
|
||||
)
|
||||
{
|
||||
DLIB_CASSERT(node_index1 < self.number_of_nodes() &&
|
||||
node_index2 < self.number_of_nodes(),
|
||||
"\tvoid graph::remove_edge(node_index1, node_index2)"
|
||||
<< "\n\tYou have specified an invalid index"
|
||||
<< "\n\tnode_index1: " << node_index1
|
||||
<< "\n\tnode_index2: " << node_index2
|
||||
<< "\n\tnumber_of_nodes(): " << self.number_of_nodes()
|
||||
<< "\n\tthis: " << &self
|
||||
);
|
||||
|
||||
DLIB_CASSERT( self.has_edge(node_index1, node_index2) == true,
|
||||
"\tvoid graph::remove_edge(node_index1, node_index2)"
|
||||
<< "\n\tYou can't remove an edge if it isn't in the graph"
|
||||
<< "\n\tnode_index1: " << node_index1
|
||||
<< "\n\tnode_index2: " << node_index2
|
||||
<< "\n\tnumber_of_nodes(): " << self.number_of_nodes()
|
||||
<< "\n\tthis: " << &self
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
static void check_remove_node (
|
||||
unsigned long index,
|
||||
const graph& self
|
||||
)
|
||||
{
|
||||
// make sure requires clause is not broken
|
||||
DLIB_CASSERT(index < self.number_of_nodes(),
|
||||
"\tvoid graph::remove_node(index)"
|
||||
<< "\n\tYou have specified an invalid index"
|
||||
<< "\n\tindex: " << index
|
||||
<< "\n\tnumber_of_nodes(): " << self.number_of_nodes()
|
||||
<< "\n\tthis: " << &self
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename node_type, typename graph>
|
||||
struct graph_checker_helper <node_type, graph, false>
|
||||
{
|
||||
static inline void check_edge ( unsigned long , const node_type& ) { }
|
||||
static inline void check_neighbor ( unsigned long , const node_type& ) { }
|
||||
static inline void check_node ( unsigned long , const graph& ) { }
|
||||
static inline void check_has_edge ( unsigned long , unsigned long , const graph& ) { }
|
||||
static inline void check_add_edge ( unsigned long , unsigned long , const graph& ) { }
|
||||
static inline void check_remove_edge ( unsigned long , unsigned long , const graph& ) { }
|
||||
static inline void check_remove_node ( unsigned long , const graph& ) { }
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename E = char,
|
||||
typename mem_manager = default_memory_manager,
|
||||
bool is_checked = true
|
||||
>
|
||||
class graph_kernel_1 : noncopyable
|
||||
{
|
||||
|
||||
/*!
|
||||
INITIAL VALUE
|
||||
- nodes.size() == 0
|
||||
|
||||
CONVENTION
|
||||
- nodes.size() == number_of_nodes()
|
||||
- for all valid i:
|
||||
- *nodes[i] == node(i)
|
||||
- nodes[i]->neighbors.size() == nodes[i]->number_of_neighbors(i)
|
||||
- nodes[i]->idx == i == nodes[i]->index()
|
||||
- for all valid n:
|
||||
- nodes[i]->neighbors[n] == pointer to the n'th parent node of i
|
||||
- *nodes[i]->neighbors[n] == node(i).neighbor(n)
|
||||
- *nodes[i]->edges[n] == node(i).edge(n)
|
||||
!*/
|
||||
|
||||
public:
|
||||
struct node_type;
|
||||
|
||||
private:
|
||||
typedef graph_checker_helper<node_type, graph_kernel_1, is_checked> checker;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
typedef T type;
|
||||
typedef E edge_type;
|
||||
typedef mem_manager mem_manager_type;
|
||||
|
||||
graph_kernel_1(
|
||||
) {}
|
||||
|
||||
virtual ~graph_kernel_1(
|
||||
) {}
|
||||
|
||||
void clear(
|
||||
) { nodes.clear(); }
|
||||
|
||||
void set_number_of_nodes (
|
||||
unsigned long new_size
|
||||
);
|
||||
|
||||
unsigned long number_of_nodes (
|
||||
) const { return nodes.size(); }
|
||||
|
||||
node_type& node (
|
||||
unsigned long index
|
||||
) { checker::check_node(index,*this); return *nodes[index]; }
|
||||
|
||||
const node_type& node (
|
||||
unsigned long index
|
||||
) const { checker::check_node(index,*this); return *nodes[index]; }
|
||||
|
||||
bool has_edge (
|
||||
unsigned long node_index1,
|
||||
unsigned long node_index2
|
||||
) const;
|
||||
|
||||
void add_edge (
|
||||
unsigned long node_index1,
|
||||
unsigned long node_index2
|
||||
);
|
||||
|
||||
void remove_edge (
|
||||
unsigned long node_index1,
|
||||
unsigned long node_index2
|
||||
);
|
||||
|
||||
unsigned long add_node (
|
||||
);
|
||||
|
||||
void remove_node (
|
||||
unsigned long index
|
||||
);
|
||||
|
||||
void swap (
|
||||
graph_kernel_1& item
|
||||
) { nodes.swap(item.nodes); }
|
||||
|
||||
public:
|
||||
|
||||
struct node_type
|
||||
{
|
||||
T data;
|
||||
typedef graph_kernel_1 graph_type;
|
||||
|
||||
unsigned long index(
|
||||
) const { return idx; }
|
||||
|
||||
unsigned long number_of_neighbors (
|
||||
) const { return neighbors.size(); }
|
||||
|
||||
const node_type& neighbor (
|
||||
unsigned long edge_index
|
||||
) const { checker::check_neighbor(edge_index,*this); return *neighbors[edge_index]; }
|
||||
|
||||
node_type& neighbor (
|
||||
unsigned long edge_index
|
||||
) { checker::check_neighbor(edge_index,*this); return *neighbors[edge_index]; }
|
||||
|
||||
const E& edge (
|
||||
unsigned long edge_index
|
||||
) const { checker::check_edge(edge_index,*this); return *edges[edge_index]; }
|
||||
|
||||
E& edge (
|
||||
unsigned long edge_index
|
||||
) { checker::check_edge(edge_index,*this); return *edges[edge_index]; }
|
||||
|
||||
private:
|
||||
friend class graph_kernel_1;
|
||||
typedef std_allocator<node_type*,mem_manager> alloc_type;
|
||||
typedef std_allocator<shared_ptr<E>,mem_manager> alloc_edge_type;
|
||||
std::vector<node_type*,alloc_type> neighbors;
|
||||
std::vector<shared_ptr<E>,alloc_edge_type> edges;
|
||||
unsigned long idx;
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
typedef std_allocator<shared_ptr<node_type>,mem_manager> alloc_type;
|
||||
typedef std::vector<shared_ptr<node_type>, alloc_type> vector_type;
|
||||
vector_type nodes;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename E,
|
||||
typename mem_manager,
|
||||
bool is_checked
|
||||
>
|
||||
inline void swap (
|
||||
graph_kernel_1<T,E,mem_manager,is_checked>& a,
|
||||
graph_kernel_1<T,E,mem_manager,is_checked>& b
|
||||
) { a.swap(b); }
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename E,
|
||||
typename mem_manager,
|
||||
bool is_checked
|
||||
>
|
||||
struct is_graph<graph_kernel_1<T,E,mem_manager, is_checked> >
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename E,
|
||||
typename mem_manager,
|
||||
bool is_checked
|
||||
>
|
||||
void serialize (
|
||||
const graph_kernel_1<T,E,mem_manager,is_checked>& item,
|
||||
std::ostream& out
|
||||
)
|
||||
{
|
||||
try
|
||||
{
|
||||
serialize(item.number_of_nodes(), out);
|
||||
|
||||
// serialize each node
|
||||
for (unsigned long i = 0; i < item.number_of_nodes(); ++i)
|
||||
{
|
||||
serialize(item.node(i).data, out);
|
||||
|
||||
// serialize all the edges
|
||||
for (unsigned long n = 0; n < item.node(i).number_of_neighbors(); ++n)
|
||||
{
|
||||
// only serialize edges that we haven't already serialized
|
||||
if (item.node(i).neighbor(n).index() >= i)
|
||||
{
|
||||
serialize(item.node(i).neighbor(n).index(), out);
|
||||
serialize(item.node(i).edge(n), out);
|
||||
}
|
||||
}
|
||||
const unsigned long stop_mark = 0xFFFFFFFF;
|
||||
serialize(stop_mark, out);
|
||||
}
|
||||
}
|
||||
catch (serialization_error& e)
|
||||
{
|
||||
throw serialization_error(e.info + "\n while serializing object of type graph_kernel_1");
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename E,
|
||||
typename mem_manager,
|
||||
bool is_checked
|
||||
>
|
||||
void deserialize (
|
||||
graph_kernel_1<T,E,mem_manager,is_checked>& item,
|
||||
std::istream& in
|
||||
)
|
||||
{
|
||||
try
|
||||
{
|
||||
unsigned long size;
|
||||
deserialize(size, in);
|
||||
|
||||
item.clear();
|
||||
item.set_number_of_nodes(size);
|
||||
|
||||
// deserialize each node
|
||||
for (unsigned long i = 0; i < item.number_of_nodes(); ++i)
|
||||
{
|
||||
deserialize(item.node(i).data, in);
|
||||
|
||||
const unsigned long stop_mark = 0xFFFFFFFF;
|
||||
// Add all the edges going to this node's neighbors
|
||||
unsigned long index;
|
||||
deserialize(index, in);
|
||||
while (index != stop_mark)
|
||||
{
|
||||
item.add_edge(i, index);
|
||||
// find the edge
|
||||
unsigned long j = 0;
|
||||
for (j = 0; j < item.node(i).number_of_neighbors(); ++j)
|
||||
if (item.node(i).neighbor(j).index() == index)
|
||||
break;
|
||||
|
||||
deserialize(item.node(i).edge(j), in);
|
||||
deserialize(index, in);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
catch (serialization_error& e)
|
||||
{
|
||||
throw serialization_error(e.info + "\n while deserializing object of type graph_kernel_1");
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// member function definitions
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename E,
|
||||
typename mem_manager,
|
||||
bool is_checked
|
||||
>
|
||||
void graph_kernel_1<T,E,mem_manager,is_checked>::
|
||||
set_number_of_nodes (
|
||||
unsigned long new_size
|
||||
)
|
||||
{
|
||||
try
|
||||
{
|
||||
nodes.resize(new_size);
|
||||
for (unsigned long i = 0; i < nodes.size(); ++i)
|
||||
{
|
||||
nodes[i].reset(new node_type);
|
||||
nodes[i]->idx = i;
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
clear();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename E,
|
||||
typename mem_manager,
|
||||
bool is_checked
|
||||
>
|
||||
bool graph_kernel_1<T,E,mem_manager,is_checked>::
|
||||
has_edge (
|
||||
unsigned long node_index1,
|
||||
unsigned long node_index2
|
||||
) const
|
||||
{
|
||||
checker::check_has_edge(node_index1, node_index2, *this);
|
||||
|
||||
node_type& n = *nodes[node_index1];
|
||||
|
||||
// search all the child nodes to see if there is a link to the right node
|
||||
for (unsigned long i = 0; i < n.neighbors.size(); ++i)
|
||||
{
|
||||
if (n.neighbors[i]->idx == node_index2)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename E,
|
||||
typename mem_manager,
|
||||
bool is_checked
|
||||
>
|
||||
void graph_kernel_1<T,E,mem_manager,is_checked>::
|
||||
add_edge (
|
||||
unsigned long node_index1,
|
||||
unsigned long node_index2
|
||||
)
|
||||
{
|
||||
checker::check_add_edge(node_index1, node_index2, *this);
|
||||
try
|
||||
{
|
||||
node_type& n1 = *nodes[node_index1];
|
||||
node_type& n2 = *nodes[node_index2];
|
||||
|
||||
n1.neighbors.push_back(&n2);
|
||||
|
||||
shared_ptr<E> e(new E);
|
||||
n1.edges.push_back(e);
|
||||
|
||||
// don't add this twice if this is an edge from node_index1 back to itself
|
||||
if (node_index1 != node_index2)
|
||||
{
|
||||
n2.neighbors.push_back(&n1);
|
||||
n2.edges.push_back(e);
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
clear();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename E,
|
||||
typename mem_manager,
|
||||
bool is_checked
|
||||
>
|
||||
void graph_kernel_1<T,E,mem_manager,is_checked>::
|
||||
remove_edge (
|
||||
unsigned long node_index1,
|
||||
unsigned long node_index2
|
||||
)
|
||||
{
|
||||
checker::check_remove_edge(node_index1, node_index2, *this);
|
||||
|
||||
node_type& n1 = *nodes[node_index1];
|
||||
node_type& n2 = *nodes[node_index2];
|
||||
|
||||
// remove the record of the link from n1
|
||||
unsigned long pos = static_cast<unsigned long>(find(n1.neighbors.begin(), n1.neighbors.end(), &n2) - n1.neighbors.begin());
|
||||
n1.neighbors.erase(n1.neighbors.begin() + pos);
|
||||
n1.edges.erase(n1.edges.begin() + pos);
|
||||
|
||||
// check if this is an edge that goes from node_index1 back to itself
|
||||
if (node_index1 != node_index2)
|
||||
{
|
||||
// remove the record of the link from n2
|
||||
unsigned long pos = static_cast<unsigned long>(find(n2.neighbors.begin(), n2.neighbors.end(), &n1) - n2.neighbors.begin());
|
||||
n2.neighbors.erase(n2.neighbors.begin() + pos);
|
||||
n2.edges.erase(n2.edges.begin() + pos);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename E,
|
||||
typename mem_manager,
|
||||
bool is_checked
|
||||
>
|
||||
unsigned long graph_kernel_1<T,E,mem_manager,is_checked>::
|
||||
add_node (
|
||||
)
|
||||
{
|
||||
try
|
||||
{
|
||||
shared_ptr<node_type> n(new node_type);
|
||||
n->idx = nodes.size();
|
||||
nodes.push_back(n);
|
||||
return n->idx;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
clear();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename E,
|
||||
typename mem_manager,
|
||||
bool is_checked
|
||||
>
|
||||
void graph_kernel_1<T,E,mem_manager,is_checked>::
|
||||
remove_node (
|
||||
unsigned long index
|
||||
)
|
||||
{
|
||||
checker::check_remove_node(index,*this);
|
||||
|
||||
node_type& n = *nodes[index];
|
||||
|
||||
// remove all edges pointing to this node from its neighbors
|
||||
for (unsigned long i = 0; i < n.neighbors.size(); ++i)
|
||||
{
|
||||
// remove the edge from this specific parent
|
||||
unsigned long pos = static_cast<unsigned long>(find(n.neighbors[i]->neighbors.begin(), n.neighbors[i]->neighbors.end(), &n) -
|
||||
n.neighbors[i]->neighbors.begin());
|
||||
n.neighbors[i]->neighbors.erase(n.neighbors[i]->neighbors.begin() + pos);
|
||||
n.neighbors[i]->edges.erase(n.neighbors[i]->edges.begin() + pos);
|
||||
}
|
||||
|
||||
// now remove this node by replacing it with the last node in the nodes vector
|
||||
nodes[index] = nodes[nodes.size()-1];
|
||||
|
||||
// update the index for the node we just moved
|
||||
nodes[index]->idx = index;
|
||||
|
||||
// now remove the duplicated node at the end of the vector
|
||||
nodes.pop_back();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_GRAPH_KERNEl_1_
|
||||
|
||||
329
lib/3rdParty/dlib/include/dlib/graph/graph_kernel_abstract.h
vendored
Normal file
329
lib/3rdParty/dlib/include/dlib/graph/graph_kernel_abstract.h
vendored
Normal file
@@ -0,0 +1,329 @@
|
||||
// Copyright (C) 2007 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#undef DLIB_GRAPH_KERNEl_ABSTRACT_
|
||||
#ifdef DLIB_GRAPH_KERNEl_ABSTRACT_
|
||||
|
||||
#include "../serialize.h"
|
||||
#include "../algs.h"
|
||||
#include "../noncopyable.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename E = char,
|
||||
typename mem_manager = default_memory_manager
|
||||
>
|
||||
class graph : noncopyable
|
||||
{
|
||||
|
||||
/*!
|
||||
REQUIREMENTS ON T
|
||||
T must be swappable by a global swap() and
|
||||
T must have a default constructor
|
||||
|
||||
REQUIREMENTS ON E
|
||||
E must be swappable by a global swap() and
|
||||
E must have a default constructor
|
||||
|
||||
REQUIREMENTS ON mem_manager
|
||||
must be an implementation of memory_manager/memory_manager_kernel_abstract.h or
|
||||
must be an implementation of memory_manager_global/memory_manager_global_kernel_abstract.h or
|
||||
must be an implementation of memory_manager_stateless/memory_manager_stateless_kernel_abstract.h
|
||||
mem_manager::type can be set to anything.
|
||||
|
||||
POINTERS AND REFERENCES TO INTERNAL DATA
|
||||
The only time pointers or references to nodes or edges become invalid is when
|
||||
they reference nodes or edges that have been removed from a graph.
|
||||
|
||||
INITIAL VALUE
|
||||
number_of_nodes() == 0
|
||||
|
||||
WHAT THIS OBJECT REPRESENTS
|
||||
This object represents an undirected graph which is a set of nodes with undirected
|
||||
edges connecting various nodes.
|
||||
|
||||
Also note that unless specified otherwise, no member functions
|
||||
of this object throw exceptions.
|
||||
!*/
|
||||
|
||||
public:
|
||||
|
||||
typedef T type;
|
||||
typedef E edge_type;
|
||||
typedef mem_manager mem_manager_type;
|
||||
|
||||
graph(
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #*this is properly initialized
|
||||
throws
|
||||
- std::bad_alloc or any exception thrown by T's constructor.
|
||||
!*/
|
||||
|
||||
virtual ~graph(
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- all resources associated with *this has been released
|
||||
!*/
|
||||
|
||||
void clear(
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #*this has its initial value
|
||||
throws
|
||||
- std::bad_alloc or any exception thrown by T's constructor.
|
||||
If this exception is thrown then *this is unusable
|
||||
until clear() is called and succeeds
|
||||
!*/
|
||||
|
||||
void set_number_of_nodes (
|
||||
unsigned long new_size
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #number_of_nodes() == new_size
|
||||
- for all i < new_size:
|
||||
- number_of_neighbors(i) == 0
|
||||
throws
|
||||
- std::bad_alloc or any exception thrown by T's constructor.
|
||||
If this exception is thrown then this object reverts back
|
||||
to its initial state.
|
||||
!*/
|
||||
|
||||
unsigned long number_of_nodes (
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- returns the number of nodes in this graph
|
||||
!*/
|
||||
|
||||
struct node_type
|
||||
{
|
||||
T data;
|
||||
typedef graph graph_type;
|
||||
|
||||
unsigned long index(
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- let G be the graph that contains the node *this
|
||||
- returns a number N such that G.node(N) == *this
|
||||
(i.e. returns the index of this node in the graph)
|
||||
!*/
|
||||
|
||||
unsigned long number_of_neighbors (
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- returns the number of nodes in this graph that are
|
||||
adjacent to this node. I.e. the number of nodes
|
||||
that are directly connected to this node via an edge.
|
||||
!*/
|
||||
|
||||
const node_type& neighbor (
|
||||
unsigned long edge_index
|
||||
) const;
|
||||
/*!
|
||||
requires
|
||||
- edge_index < number_of_neighbors()
|
||||
ensures
|
||||
- returns a const reference to the edge_index'th neighbor of *this
|
||||
!*/
|
||||
|
||||
node_type& neighbor (
|
||||
unsigned long edge_index
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- edge_index < number_of_neighbors()
|
||||
ensures
|
||||
- returns a non-const reference to the edge_index'th neighbor of *this
|
||||
!*/
|
||||
|
||||
const E& edge (
|
||||
unsigned long edge_index
|
||||
) const;
|
||||
/*!
|
||||
requires
|
||||
- edge_index < number_of_neighbors()
|
||||
ensures
|
||||
- returns a const reference to the edge_index'th edge data for the
|
||||
edge connecting to neighbor this->neighbor(edge_index)
|
||||
!*/
|
||||
|
||||
E& edge (
|
||||
unsigned long edge_index
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- edge_index < number_of_neighbors()
|
||||
ensures
|
||||
- returns a non-const reference to the edge_index'th edge data for the
|
||||
edge connecting to neighbor this->neighbor(edge_index)
|
||||
!*/
|
||||
|
||||
};
|
||||
|
||||
node_type& node (
|
||||
unsigned long index
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- index < number_of_nodes()
|
||||
ensures
|
||||
- returns a non-const reference to the node with the given index
|
||||
!*/
|
||||
|
||||
const node_type& node (
|
||||
unsigned long index
|
||||
) const;
|
||||
/*!
|
||||
requires
|
||||
- index < number_of_nodes()
|
||||
ensures
|
||||
- returns a const reference to the node with the given index
|
||||
!*/
|
||||
|
||||
bool has_edge (
|
||||
unsigned long node_index1,
|
||||
unsigned long node_index2
|
||||
) const;
|
||||
/*!
|
||||
requires
|
||||
- node_index1 < number_of_nodes()
|
||||
- node_index2 < number_of_nodes()
|
||||
ensures
|
||||
- if (there is an edge connecting node(node_index1) and node(node_index2)) then
|
||||
- returns true
|
||||
- else
|
||||
- returns false
|
||||
!*/
|
||||
|
||||
void add_edge (
|
||||
unsigned long node_index1,
|
||||
unsigned long node_index2
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- node_index1 < number_of_nodes()
|
||||
- node_index2 < number_of_nodes()
|
||||
- has_edge(node_index1, node_index2) == false
|
||||
ensures
|
||||
- #has_edge(node_index1, node_index2) == true
|
||||
throws
|
||||
- std::bad_alloc
|
||||
If this exception is thrown then this object reverts back
|
||||
to its initial state.
|
||||
!*/
|
||||
|
||||
void remove_edge (
|
||||
unsigned long node_index1,
|
||||
unsigned long node_index2
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- node_index1 < number_of_nodes()
|
||||
- node_index2 < number_of_nodes()
|
||||
- has_edge(node_index1, node_index2) == true
|
||||
ensures
|
||||
- #has_edge(node_index1, node_index2) == false
|
||||
throws
|
||||
- std::bad_alloc
|
||||
If this exception is thrown then this object reverts back
|
||||
to its initial state.
|
||||
!*/
|
||||
|
||||
unsigned long add_node (
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- does not change the index number of existing nodes
|
||||
- adds a node with index N == number_of_nodes() such that:
|
||||
- #node(N).number_of_neighbors() == 0
|
||||
- #number_of_nodes() == number_of_nodes() + 1
|
||||
- returns N
|
||||
throws
|
||||
- std::bad_alloc or any exception thrown by T's constructor.
|
||||
If this exception is thrown then this object reverts back
|
||||
to its initial state.
|
||||
!*/
|
||||
|
||||
void remove_node (
|
||||
unsigned long index
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- index < number_of_nodes()
|
||||
ensures
|
||||
- removes the node with the given index from the graph.
|
||||
- removes all edges linking the removed node to the rest
|
||||
of the graph.
|
||||
- the remaining node indexes are remapped so that they remain
|
||||
contiguous. (This means that for all valid N, node(N) doesn't
|
||||
necessarily reference the same node as #node(N))
|
||||
- #number_of_nodes() == number_of_nodes() - 1
|
||||
throws
|
||||
- std::bad_alloc or any exception thrown by T's constructor.
|
||||
If this exception is thrown then this object reverts back
|
||||
to its initial state.
|
||||
!*/
|
||||
|
||||
void swap (
|
||||
graph& item
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- swaps *this and item
|
||||
!*/
|
||||
|
||||
};
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename E,
|
||||
typename mem_manager
|
||||
>
|
||||
inline void swap (
|
||||
graph<T,E,mem_manager>& a,
|
||||
graph<T,E,mem_manager>& b
|
||||
) { a.swap(b); }
|
||||
/*!
|
||||
provides a global swap function
|
||||
!*/
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename E,
|
||||
typename mem_manager
|
||||
>
|
||||
void serialize (
|
||||
const graph<T,E,mem_manager>& item,
|
||||
std::ostream& out
|
||||
);
|
||||
/*!
|
||||
provides deserialization support
|
||||
!*/
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename E,
|
||||
typename mem_manager
|
||||
>
|
||||
void deserialize (
|
||||
graph<T,E,mem_manager>& item,
|
||||
std::istream& in
|
||||
);
|
||||
/*!
|
||||
provides deserialization support
|
||||
!*/
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_GRAPH_KERNEl_ABSTRACT_
|
||||
|
||||
|
||||
Reference in New Issue
Block a user