2009-08-07 02:25:12 +02:00
|
|
|
//===-- GraphBase.h - Abstract Base PBQP Graph -----------------*- C++ --*-===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// Base class for PBQP Graphs.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
|
2009-08-07 01:32:48 +02:00
|
|
|
#ifndef LLVM_CODEGEN_PBQP_GRAPHBASE_H
|
|
|
|
#define LLVM_CODEGEN_PBQP_GRAPHBASE_H
|
|
|
|
|
|
|
|
#include "PBQPMath.h"
|
|
|
|
|
|
|
|
#include <list>
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
namespace PBQP {
|
|
|
|
|
|
|
|
// UGLY, but I'm not sure there's a good way around this: We need to be able to
|
|
|
|
// look up a Node's "adjacent edge list" structure type before the Node type is
|
|
|
|
// fully constructed. We can enable this by pushing the choice of data type
|
|
|
|
// out into this traits class.
|
|
|
|
template <typename Graph>
|
|
|
|
class NodeBaseTraits {
|
|
|
|
public:
|
|
|
|
typedef std::list<typename Graph::EdgeIterator> AdjEdgeList;
|
|
|
|
typedef typename AdjEdgeList::iterator AdjEdgeIterator;
|
|
|
|
typedef typename AdjEdgeList::const_iterator ConstAdjEdgeIterator;
|
|
|
|
};
|
|
|
|
|
|
|
|
/// \brief Base for concrete graph classes. Provides a basic set of graph
|
|
|
|
/// operations which are useful for PBQP solvers.
|
|
|
|
template <typename NodeEntry, typename EdgeEntry>
|
|
|
|
class GraphBase {
|
|
|
|
private:
|
|
|
|
|
|
|
|
typedef GraphBase<NodeEntry, EdgeEntry> ThisGraphT;
|
|
|
|
|
|
|
|
typedef std::list<NodeEntry> NodeList;
|
|
|
|
typedef std::list<EdgeEntry> EdgeList;
|
|
|
|
|
|
|
|
NodeList nodeList;
|
|
|
|
unsigned nodeListSize;
|
|
|
|
|
|
|
|
EdgeList edgeList;
|
|
|
|
unsigned edgeListSize;
|
|
|
|
|
|
|
|
GraphBase(const ThisGraphT &other) { abort(); }
|
|
|
|
void operator=(const ThisGraphT &other) { abort(); }
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
/// \brief Iterates over the nodes of a graph.
|
|
|
|
typedef typename NodeList::iterator NodeIterator;
|
|
|
|
/// \brief Iterates over the nodes of a const graph.
|
|
|
|
typedef typename NodeList::const_iterator ConstNodeIterator;
|
|
|
|
/// \brief Iterates over the edges of a graph.
|
|
|
|
typedef typename EdgeList::iterator EdgeIterator;
|
|
|
|
/// \brief Iterates over the edges of a const graph.
|
|
|
|
typedef typename EdgeList::const_iterator ConstEdgeIterator;
|
|
|
|
|
|
|
|
/// \brief Iterates over the edges attached to a node.
|
|
|
|
typedef typename NodeBaseTraits<ThisGraphT>::AdjEdgeIterator
|
|
|
|
AdjEdgeIterator;
|
|
|
|
|
|
|
|
/// \brief Iterates over the edges attached to a node in a const graph.
|
|
|
|
typedef typename NodeBaseTraits<ThisGraphT>::ConstAdjEdgeIterator
|
|
|
|
ConstAdjEdgeIterator;
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
typedef std::vector<NodeIterator> IDToNodeMap;
|
|
|
|
|
|
|
|
IDToNodeMap idToNodeMap;
|
|
|
|
bool nodeIDsValid;
|
|
|
|
|
|
|
|
void invalidateNodeIDs() {
|
|
|
|
if (nodeIDsValid) {
|
|
|
|
idToNodeMap.clear();
|
|
|
|
nodeIDsValid = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename ItrT>
|
|
|
|
bool iteratorInRange(ItrT itr, const ItrT &begin, const ItrT &end) {
|
|
|
|
for (ItrT t = begin; t != end; ++t) {
|
|
|
|
if (itr == t)
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
|
|
|
GraphBase() : nodeListSize(0), edgeListSize(0), nodeIDsValid(false) {}
|
|
|
|
|
|
|
|
NodeEntry& getNodeEntry(const NodeIterator &nodeItr) { return *nodeItr; }
|
|
|
|
const NodeEntry& getNodeEntry(const ConstNodeIterator &nodeItr) const {
|
|
|
|
return *nodeItr;
|
|
|
|
}
|
|
|
|
|
|
|
|
EdgeEntry& getEdgeEntry(const EdgeIterator &edgeItr) { return *edgeItr; }
|
|
|
|
const EdgeEntry& getEdgeEntry(const ConstEdgeIterator &edgeItr) const {
|
|
|
|
return *edgeItr;
|
|
|
|
}
|
|
|
|
|
|
|
|
NodeIterator addConstructedNode(const NodeEntry &nodeEntry) {
|
|
|
|
++nodeListSize;
|
|
|
|
|
|
|
|
invalidateNodeIDs();
|
|
|
|
|
|
|
|
NodeIterator newNodeItr = nodeList.insert(nodeList.end(), nodeEntry);
|
|
|
|
|
|
|
|
return newNodeItr;
|
|
|
|
}
|
|
|
|
|
|
|
|
EdgeIterator addConstructedEdge(const EdgeEntry &edgeEntry) {
|
|
|
|
|
|
|
|
assert((findEdge(edgeEntry.getNode1Itr(), edgeEntry.getNode2Itr())
|
|
|
|
== edgeList.end()) && "Attempt to add duplicate edge.");
|
|
|
|
|
|
|
|
++edgeListSize;
|
|
|
|
|
|
|
|
// Add the edge to the graph.
|
|
|
|
EdgeIterator edgeItr = edgeList.insert(edgeList.end(), edgeEntry);
|
|
|
|
|
|
|
|
// Get a reference to the version in the graph.
|
|
|
|
EdgeEntry &newEdgeEntry = getEdgeEntry(edgeItr);
|
|
|
|
|
|
|
|
// Node entries:
|
|
|
|
NodeEntry &node1Entry = getNodeEntry(newEdgeEntry.getNode1Itr()),
|
|
|
|
&node2Entry = getNodeEntry(newEdgeEntry.getNode2Itr());
|
|
|
|
|
|
|
|
// Sanity check on matrix dimensions.
|
2009-08-08 02:40:46 +02:00
|
|
|
assert((node1Entry.getCosts().getLength() ==
|
|
|
|
newEdgeEntry.getCosts().getRows()) &&
|
|
|
|
(node2Entry.getCosts().getLength() ==
|
|
|
|
newEdgeEntry.getCosts().getCols()) &&
|
2009-08-07 01:32:48 +02:00
|
|
|
"Matrix dimensions do not match cost vector dimensions.");
|
|
|
|
|
|
|
|
// Create links between nodes and edges.
|
|
|
|
newEdgeEntry.setNode1ThisEdgeItr(
|
|
|
|
node1Entry.addAdjEdge(edgeItr));
|
|
|
|
newEdgeEntry.setNode2ThisEdgeItr(
|
|
|
|
node2Entry.addAdjEdge(edgeItr));
|
|
|
|
|
|
|
|
return edgeItr;
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
/// \brief Returns the number of nodes in this graph.
|
|
|
|
unsigned getNumNodes() const { return nodeListSize; }
|
|
|
|
|
|
|
|
/// \brief Returns the number of edges in this graph.
|
|
|
|
unsigned getNumEdges() const { return edgeListSize; }
|
|
|
|
|
|
|
|
/// \brief Return the cost vector for the given node.
|
|
|
|
Vector& getNodeCosts(const NodeIterator &nodeItr) {
|
|
|
|
return getNodeEntry(nodeItr).getCosts();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Return the cost vector for the give node.
|
|
|
|
const Vector& getNodeCosts(const ConstNodeIterator &nodeItr) const {
|
|
|
|
return getNodeEntry(nodeItr).getCosts();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Return the degree of the given node.
|
|
|
|
unsigned getNodeDegree(const NodeIterator &nodeItr) const {
|
|
|
|
return getNodeEntry(nodeItr).getDegree();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Assigns sequential IDs to the nodes, starting at 0, which
|
|
|
|
/// remain valid until the next addition or removal of a node.
|
|
|
|
void assignNodeIDs() {
|
|
|
|
unsigned curID = 0;
|
|
|
|
idToNodeMap.resize(getNumNodes());
|
|
|
|
for (NodeIterator nodeItr = nodesBegin(), nodeEnd = nodesEnd();
|
|
|
|
nodeItr != nodeEnd; ++nodeItr, ++curID) {
|
|
|
|
getNodeEntry(nodeItr).setID(curID);
|
|
|
|
idToNodeMap[curID] = nodeItr;
|
|
|
|
}
|
|
|
|
nodeIDsValid = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Assigns sequential IDs to the nodes using the ordering of the
|
|
|
|
/// given vector.
|
|
|
|
void assignNodeIDs(const std::vector<NodeIterator> &nodeOrdering) {
|
|
|
|
assert((getNumNodes() == nodeOrdering.size()) &&
|
|
|
|
"Wrong number of nodes in node ordering.");
|
|
|
|
idToNodeMap = nodeOrdering;
|
|
|
|
for (unsigned nodeID = 0; nodeID < idToNodeMap.size(); ++nodeID) {
|
|
|
|
getNodeEntry(idToNodeMap[nodeID]).setID(nodeID);
|
|
|
|
}
|
|
|
|
nodeIDsValid = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Returns true if valid node IDs are assigned, false otherwise.
|
|
|
|
bool areNodeIDsValid() const { return nodeIDsValid; }
|
|
|
|
|
|
|
|
/// \brief Return the numeric ID of the given node.
|
|
|
|
///
|
|
|
|
/// Calls to this method will result in an assertion failure if there have
|
|
|
|
/// been any node additions or removals since the last call to
|
|
|
|
/// assignNodeIDs().
|
|
|
|
unsigned getNodeID(const ConstNodeIterator &nodeItr) const {
|
|
|
|
assert(nodeIDsValid && "Attempt to retrieve invalid ID.");
|
|
|
|
return getNodeEntry(nodeItr).getID();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Returns the iterator associated with the given node ID.
|
|
|
|
NodeIterator getNodeItr(unsigned nodeID) {
|
|
|
|
assert(nodeIDsValid && "Attempt to retrieve iterator with invalid ID.");
|
|
|
|
return idToNodeMap[nodeID];
|
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Returns the iterator associated with the given node ID.
|
|
|
|
ConstNodeIterator getNodeItr(unsigned nodeID) const {
|
|
|
|
assert(nodeIDsValid && "Attempt to retrieve iterator with invalid ID.");
|
|
|
|
return idToNodeMap[nodeID];
|
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Removes the given node (and all attached edges) from the graph.
|
|
|
|
void removeNode(const NodeIterator &nodeItr) {
|
|
|
|
assert(iteratorInRange(nodeItr, nodeList.begin(), nodeList.end()) &&
|
|
|
|
"Iterator does not belong to this graph!");
|
|
|
|
|
|
|
|
invalidateNodeIDs();
|
|
|
|
|
|
|
|
NodeEntry &nodeEntry = getNodeEntry(nodeItr);
|
|
|
|
|
|
|
|
// We need to copy this out because it will be destroyed as the edges are
|
|
|
|
// removed.
|
|
|
|
typedef std::vector<EdgeIterator> AdjEdgeList;
|
|
|
|
typedef typename AdjEdgeList::iterator AdjEdgeListItr;
|
|
|
|
|
|
|
|
AdjEdgeList adjEdges;
|
|
|
|
adjEdges.reserve(nodeEntry.getDegree());
|
|
|
|
std::copy(nodeEntry.adjEdgesBegin(), nodeEntry.adjEdgesEnd(),
|
|
|
|
std::back_inserter(adjEdges));
|
|
|
|
|
|
|
|
// Iterate over the copied out edges and remove them from the graph.
|
|
|
|
for (AdjEdgeListItr itr = adjEdges.begin(), end = adjEdges.end();
|
|
|
|
itr != end; ++itr) {
|
|
|
|
removeEdge(*itr);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Erase the node from the nodelist.
|
|
|
|
nodeList.erase(nodeItr);
|
|
|
|
--nodeListSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
NodeIterator nodesBegin() { return nodeList.begin(); }
|
|
|
|
ConstNodeIterator nodesBegin() const { return nodeList.begin(); }
|
|
|
|
NodeIterator nodesEnd() { return nodeList.end(); }
|
|
|
|
ConstNodeIterator nodesEnd() const { return nodeList.end(); }
|
|
|
|
|
|
|
|
AdjEdgeIterator adjEdgesBegin(const NodeIterator &nodeItr) {
|
|
|
|
return getNodeEntry(nodeItr).adjEdgesBegin();
|
|
|
|
}
|
|
|
|
|
|
|
|
ConstAdjEdgeIterator adjEdgesBegin(const ConstNodeIterator &nodeItr) const {
|
|
|
|
return getNodeEntry(nodeItr).adjEdgesBegin();
|
|
|
|
}
|
|
|
|
|
|
|
|
AdjEdgeIterator adjEdgesEnd(const NodeIterator &nodeItr) {
|
|
|
|
return getNodeEntry(nodeItr).adjEdgesEnd();
|
|
|
|
}
|
|
|
|
|
|
|
|
ConstAdjEdgeIterator adjEdgesEnd(const ConstNodeIterator &nodeItr) const {
|
|
|
|
getNodeEntry(nodeItr).adjEdgesEnd();
|
|
|
|
}
|
|
|
|
|
|
|
|
EdgeIterator findEdge(const NodeIterator &node1Itr,
|
|
|
|
const NodeIterator &node2Itr) {
|
|
|
|
|
|
|
|
for (AdjEdgeIterator adjEdgeItr = adjEdgesBegin(node1Itr),
|
|
|
|
adjEdgeEnd = adjEdgesEnd(node1Itr);
|
|
|
|
adjEdgeItr != adjEdgeEnd; ++adjEdgeItr) {
|
|
|
|
if ((getEdgeNode1Itr(*adjEdgeItr) == node2Itr) ||
|
|
|
|
(getEdgeNode2Itr(*adjEdgeItr) == node2Itr)) {
|
|
|
|
return *adjEdgeItr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return edgeList.end();
|
|
|
|
}
|
|
|
|
|
|
|
|
ConstEdgeIterator findEdge(const ConstNodeIterator &node1Itr,
|
|
|
|
const ConstNodeIterator &node2Itr) const {
|
|
|
|
|
|
|
|
for (ConstAdjEdgeIterator adjEdgeItr = adjEdgesBegin(node1Itr),
|
|
|
|
adjEdgeEnd = adjEdgesEnd(node1Itr);
|
|
|
|
adjEdgeItr != adjEdgesEnd; ++adjEdgeItr) {
|
|
|
|
if ((getEdgeNode1Itr(*adjEdgeItr) == node2Itr) ||
|
|
|
|
(getEdgeNode2Itr(*adjEdgeItr) == node2Itr)) {
|
|
|
|
return *adjEdgeItr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return edgeList.end();
|
|
|
|
}
|
|
|
|
|
|
|
|
Matrix& getEdgeCosts(const EdgeIterator &edgeItr) {
|
|
|
|
return getEdgeEntry(edgeItr).getCosts();
|
|
|
|
}
|
|
|
|
|
|
|
|
const Matrix& getEdgeCosts(const ConstEdgeIterator &edgeItr) const {
|
|
|
|
return getEdgeEntry(edgeItr).getCosts();
|
|
|
|
}
|
|
|
|
|
|
|
|
NodeIterator getEdgeNode1Itr(const EdgeIterator &edgeItr) {
|
|
|
|
return getEdgeEntry(edgeItr).getNode1Itr();
|
|
|
|
}
|
|
|
|
|
|
|
|
ConstNodeIterator getEdgeNode1Itr(const ConstEdgeIterator &edgeItr) const {
|
|
|
|
return getEdgeEntry(edgeItr).getNode1Itr();
|
|
|
|
}
|
|
|
|
|
|
|
|
NodeIterator getEdgeNode2Itr(const EdgeIterator &edgeItr) {
|
|
|
|
return getEdgeEntry(edgeItr).getNode2Itr();
|
|
|
|
}
|
|
|
|
|
|
|
|
ConstNodeIterator getEdgeNode2Itr(const ConstEdgeIterator &edgeItr) const {
|
|
|
|
return getEdgeEntry(edgeItr).getNode2Itr();
|
|
|
|
}
|
|
|
|
|
|
|
|
NodeIterator getEdgeOtherNode(const EdgeIterator &edgeItr,
|
|
|
|
const NodeIterator &nodeItr) {
|
|
|
|
|
|
|
|
EdgeEntry &edgeEntry = getEdgeEntry(edgeItr);
|
|
|
|
if (nodeItr == edgeEntry.getNode1Itr()) {
|
|
|
|
return edgeEntry.getNode2Itr();
|
|
|
|
}
|
|
|
|
//else
|
|
|
|
return edgeEntry.getNode1Itr();
|
|
|
|
}
|
|
|
|
|
|
|
|
ConstNodeIterator getEdgeOtherNode(const ConstEdgeIterator &edgeItr,
|
|
|
|
const ConstNodeIterator &nodeItr) const {
|
|
|
|
|
|
|
|
const EdgeEntry &edgeEntry = getEdgeEntry(edgeItr);
|
|
|
|
if (nodeItr == edgeEntry.getNode1Itr()) {
|
|
|
|
return edgeEntry.getNode2Itr();
|
|
|
|
}
|
|
|
|
//else
|
|
|
|
return edgeEntry.getNode1Itr();
|
|
|
|
}
|
|
|
|
|
|
|
|
void removeEdge(const EdgeIterator &edgeItr) {
|
|
|
|
assert(iteratorInRange(edgeItr, edgeList.begin(), edgeList.end()) &&
|
|
|
|
"Iterator does not belong to this graph!");
|
|
|
|
|
|
|
|
--edgeListSize;
|
|
|
|
|
|
|
|
// Get the edge entry.
|
|
|
|
EdgeEntry &edgeEntry = getEdgeEntry(edgeItr);
|
|
|
|
|
|
|
|
// Get the nodes entry.
|
|
|
|
NodeEntry &node1Entry(getNodeEntry(edgeEntry.getNode1Itr())),
|
|
|
|
&node2Entry(getNodeEntry(edgeEntry.getNode2Itr()));
|
|
|
|
|
|
|
|
// Disconnect the edge from the nodes.
|
|
|
|
node1Entry.removeAdjEdge(edgeEntry.getNode1ThisEdgeItr());
|
|
|
|
node2Entry.removeAdjEdge(edgeEntry.getNode2ThisEdgeItr());
|
|
|
|
|
|
|
|
// Remove the edge from the graph.
|
|
|
|
edgeList.erase(edgeItr);
|
|
|
|
}
|
|
|
|
|
|
|
|
EdgeIterator edgesBegin() { return edgeList.begin(); }
|
|
|
|
ConstEdgeIterator edgesBegin() const { return edgeList.begin(); }
|
|
|
|
EdgeIterator edgesEnd() { return edgeList.end(); }
|
|
|
|
ConstEdgeIterator edgesEnd() const { return edgeList.end(); }
|
|
|
|
|
|
|
|
void clear() {
|
|
|
|
nodeList.clear();
|
|
|
|
nodeListSize = 0;
|
|
|
|
edgeList.clear();
|
|
|
|
edgeListSize = 0;
|
|
|
|
idToNodeMap.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename OStream>
|
|
|
|
void printDot(OStream &os) const {
|
|
|
|
|
|
|
|
assert(areNodeIDsValid() &&
|
|
|
|
"Cannot print a .dot of a graph unless IDs have been assigned.");
|
|
|
|
|
|
|
|
os << "graph {\n";
|
|
|
|
|
|
|
|
for (ConstNodeIterator nodeItr = nodesBegin(), nodeEnd = nodesEnd();
|
|
|
|
nodeItr != nodeEnd; ++nodeItr) {
|
|
|
|
|
|
|
|
os << " node" << getNodeID(nodeItr) << " [ label=\""
|
|
|
|
<< getNodeID(nodeItr) << ": " << getNodeCosts(nodeItr) << "\" ]\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
os << " edge [ len=" << getNumNodes() << " ]\n";
|
|
|
|
|
|
|
|
for (ConstEdgeIterator edgeItr = edgesBegin(), edgeEnd = edgesEnd();
|
|
|
|
edgeItr != edgeEnd; ++edgeItr) {
|
|
|
|
|
|
|
|
os << " node" << getNodeID(getEdgeNode1Itr(edgeItr))
|
|
|
|
<< " -- node" << getNodeID(getEdgeNode2Itr(edgeItr))
|
|
|
|
<< " [ label=\"";
|
|
|
|
|
|
|
|
const Matrix &edgeCosts = getEdgeCosts(edgeItr);
|
|
|
|
|
|
|
|
for (unsigned i = 0; i < edgeCosts.getRows(); ++i) {
|
|
|
|
os << edgeCosts.getRowAsVector(i) << "\\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
os << "\" ]\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
os << "}\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename OStream>
|
|
|
|
void printDot(OStream &os) {
|
|
|
|
if (!areNodeIDsValid()) {
|
|
|
|
assignNodeIDs();
|
|
|
|
}
|
|
|
|
|
|
|
|
const_cast<const ThisGraphT*>(this)->printDot(os);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename OStream>
|
|
|
|
void dumpTo(OStream &os) const {
|
|
|
|
typedef ConstNodeIterator ConstNodeID;
|
|
|
|
|
|
|
|
assert(areNodeIDsValid() &&
|
|
|
|
"Cannot dump a graph unless IDs have been assigned.");
|
|
|
|
|
|
|
|
for (ConstNodeIterator nItr = nodesBegin(), nEnd = nodesEnd();
|
|
|
|
nItr != nEnd; ++nItr) {
|
|
|
|
os << getNodeID(nItr) << "\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned edgeNumber = 1;
|
|
|
|
for (ConstEdgeIterator eItr = edgesBegin(), eEnd = edgesEnd();
|
|
|
|
eItr != eEnd; ++eItr) {
|
|
|
|
|
|
|
|
os << edgeNumber++ << ": { "
|
|
|
|
<< getNodeID(getEdgeNode1Itr(eItr)) << ", "
|
|
|
|
<< getNodeID(getEdgeNode2Itr(eItr)) << " }\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename OStream>
|
|
|
|
void dumpTo(OStream &os) {
|
|
|
|
if (!areNodeIDsValid()) {
|
|
|
|
assignNodeIDs();
|
|
|
|
}
|
|
|
|
|
|
|
|
const_cast<const ThisGraphT*>(this)->dumpTo(os);
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
/// \brief Provides a base from which to derive nodes for GraphBase.
|
|
|
|
template <typename NodeImpl, typename EdgeImpl>
|
|
|
|
class NodeBase {
|
|
|
|
private:
|
|
|
|
|
|
|
|
typedef GraphBase<NodeImpl, EdgeImpl> GraphBaseT;
|
|
|
|
typedef NodeBaseTraits<GraphBaseT> ThisNodeBaseTraits;
|
|
|
|
|
|
|
|
public:
|
|
|
|
typedef typename GraphBaseT::EdgeIterator EdgeIterator;
|
|
|
|
|
|
|
|
private:
|
|
|
|
typedef typename ThisNodeBaseTraits::AdjEdgeList AdjEdgeList;
|
|
|
|
|
|
|
|
unsigned degree, id;
|
|
|
|
Vector costs;
|
|
|
|
AdjEdgeList adjEdges;
|
|
|
|
|
|
|
|
void operator=(const NodeBase& other) {
|
|
|
|
assert(false && "Can't assign NodeEntrys.");
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
typedef typename ThisNodeBaseTraits::AdjEdgeIterator AdjEdgeIterator;
|
|
|
|
typedef typename ThisNodeBaseTraits::ConstAdjEdgeIterator
|
|
|
|
ConstAdjEdgeIterator;
|
|
|
|
|
|
|
|
NodeBase(const Vector &costs) : degree(0), costs(costs) {
|
|
|
|
assert((costs.getLength() > 0) && "Can't have zero-length cost vector.");
|
|
|
|
}
|
|
|
|
|
|
|
|
Vector& getCosts() { return costs; }
|
|
|
|
const Vector& getCosts() const { return costs; }
|
|
|
|
|
|
|
|
unsigned getDegree() const { return degree; }
|
|
|
|
|
|
|
|
void setID(unsigned id) { this->id = id; }
|
|
|
|
unsigned getID() const { return id; }
|
|
|
|
|
|
|
|
AdjEdgeIterator addAdjEdge(const EdgeIterator &edgeItr) {
|
|
|
|
++degree;
|
|
|
|
return adjEdges.insert(adjEdges.end(), edgeItr);
|
|
|
|
}
|
|
|
|
|
|
|
|
void removeAdjEdge(const AdjEdgeIterator &adjEdgeItr) {
|
|
|
|
--degree;
|
|
|
|
adjEdges.erase(adjEdgeItr);
|
|
|
|
}
|
|
|
|
|
|
|
|
AdjEdgeIterator adjEdgesBegin() { return adjEdges.begin(); }
|
|
|
|
ConstAdjEdgeIterator adjEdgesBegin() const { return adjEdges.begin(); }
|
|
|
|
AdjEdgeIterator adjEdgesEnd() { return adjEdges.end(); }
|
|
|
|
ConstAdjEdgeIterator adjEdgesEnd() const { return adjEdges.end(); }
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename NodeImpl, typename EdgeImpl>
|
|
|
|
class EdgeBase {
|
|
|
|
public:
|
|
|
|
typedef typename GraphBase<NodeImpl, EdgeImpl>::NodeIterator NodeIterator;
|
|
|
|
typedef typename GraphBase<NodeImpl, EdgeImpl>::EdgeIterator EdgeIterator;
|
|
|
|
|
|
|
|
typedef typename NodeImpl::AdjEdgeIterator NodeAdjEdgeIterator;
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
NodeIterator node1Itr, node2Itr;
|
|
|
|
NodeAdjEdgeIterator node1ThisEdgeItr, node2ThisEdgeItr;
|
|
|
|
Matrix costs;
|
|
|
|
|
|
|
|
void operator=(const EdgeBase &other) {
|
|
|
|
assert(false && "Can't assign EdgeEntrys.");
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
EdgeBase(const NodeIterator &node1Itr, const NodeIterator &node2Itr,
|
|
|
|
const Matrix &costs) :
|
|
|
|
node1Itr(node1Itr), node2Itr(node2Itr), costs(costs) {
|
|
|
|
|
|
|
|
assert((costs.getRows() > 0) && (costs.getCols() > 0) &&
|
|
|
|
"Can't have zero-dimensioned cost matrices");
|
|
|
|
}
|
|
|
|
|
|
|
|
Matrix& getCosts() { return costs; }
|
|
|
|
const Matrix& getCosts() const { return costs; }
|
|
|
|
|
|
|
|
const NodeIterator& getNode1Itr() const { return node1Itr; }
|
|
|
|
const NodeIterator& getNode2Itr() const { return node2Itr; }
|
|
|
|
|
|
|
|
void setNode1ThisEdgeItr(const NodeAdjEdgeIterator &node1ThisEdgeItr) {
|
|
|
|
this->node1ThisEdgeItr = node1ThisEdgeItr;
|
|
|
|
}
|
|
|
|
|
|
|
|
const NodeAdjEdgeIterator& getNode1ThisEdgeItr() const {
|
|
|
|
return node1ThisEdgeItr;
|
|
|
|
}
|
|
|
|
|
|
|
|
void setNode2ThisEdgeItr(const NodeAdjEdgeIterator &node2ThisEdgeItr) {
|
|
|
|
this->node2ThisEdgeItr = node2ThisEdgeItr;
|
|
|
|
}
|
|
|
|
|
|
|
|
const NodeAdjEdgeIterator& getNode2ThisEdgeItr() const {
|
|
|
|
return node2ThisEdgeItr;
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif // LLVM_CODEGEN_PBQP_GRAPHBASE_HPP
|