Added copy sensible construction & assignment to PBQP graphs and fixed a memory access bug in the heuristic solver.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@95633 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Lang Hames
2010-02-09 00:45:48 +00:00
parent 38007ca86a
commit ddea94a819
2 changed files with 85 additions and 18 deletions

View File

@@ -19,6 +19,7 @@
#include <list> #include <list>
#include <vector> #include <vector>
#include <map>
namespace PBQP { namespace PBQP {
@@ -37,7 +38,10 @@ namespace PBQP {
public: public:
typedef NodeList::iterator NodeItr; typedef NodeList::iterator NodeItr;
typedef NodeList::const_iterator ConstNodeItr;
typedef EdgeList::iterator EdgeItr; typedef EdgeList::iterator EdgeItr;
typedef EdgeList::const_iterator ConstEdgeItr;
private: private:
@@ -58,6 +62,7 @@ namespace PBQP {
public: public:
NodeEntry(const Vector &costs) : costs(costs), degree(0) {} NodeEntry(const Vector &costs) : costs(costs), degree(0) {}
Vector& getCosts() { return costs; } Vector& getCosts() { return costs; }
const Vector& getCosts() const { return costs; }
unsigned getDegree() const { return degree; } unsigned getDegree() const { return degree; }
AdjEdgeItr edgesBegin() { return adjEdges.begin(); } AdjEdgeItr edgesBegin() { return adjEdges.begin(); }
AdjEdgeItr edgesEnd() { return adjEdges.end(); } AdjEdgeItr edgesEnd() { return adjEdges.end(); }
@@ -85,6 +90,7 @@ namespace PBQP {
NodeItr getNode1() const { return node1; } NodeItr getNode1() const { return node1; }
NodeItr getNode2() const { return node2; } NodeItr getNode2() const { return node2; }
Matrix& getCosts() { return costs; } Matrix& getCosts() { return costs; }
const Matrix& getCosts() const { return costs; }
void setNode1AEItr(AdjEdgeItr ae) { node1AEItr = ae; } void setNode1AEItr(AdjEdgeItr ae) { node1AEItr = ae; }
AdjEdgeItr getNode1AEItr() { return node1AEItr; } AdjEdgeItr getNode1AEItr() { return node1AEItr; }
void setNode2AEItr(AdjEdgeItr ae) { node2AEItr = ae; } void setNode2AEItr(AdjEdgeItr ae) { node2AEItr = ae; }
@@ -104,9 +110,10 @@ namespace PBQP {
// ----- INTERNAL METHODS ----- // ----- INTERNAL METHODS -----
NodeEntry& getNode(NodeItr nItr) { return *nItr; } NodeEntry& getNode(NodeItr nItr) { return *nItr; }
const NodeEntry& getNode(NodeItr nItr) const { return *nItr; } const NodeEntry& getNode(ConstNodeItr nItr) const { return *nItr; }
EdgeEntry& getEdge(EdgeItr eItr) { return *eItr; } EdgeEntry& getEdge(EdgeItr eItr) { return *eItr; }
const EdgeEntry& getEdge(EdgeItr eItr) const { return *eItr; } const EdgeEntry& getEdge(ConstEdgeItr eItr) const { return *eItr; }
NodeItr addConstructedNode(const NodeEntry &n) { NodeItr addConstructedNode(const NodeEntry &n) {
++numNodes; ++numNodes;
@@ -130,10 +137,32 @@ namespace PBQP {
return edgeItr; return edgeItr;
} }
inline void copyFrom(const Graph &other);
public: public:
/// \brief Construct an empty PBQP graph.
Graph() : numNodes(0), numEdges(0) {} Graph() : numNodes(0), numEdges(0) {}
/// \brief Copy construct this graph from "other". Note: Does not copy node
/// and edge data, only graph structure and costs.
/// @param other Source graph to copy from.
Graph(const Graph &other) : numNodes(0), numEdges(0) {
copyFrom(other);
}
/// \brief Make this graph a copy of "other". Note: Does not copy node and
/// edge data, only graph structure and costs.
/// @param other The graph to copy from.
/// @return A reference to this graph.
///
/// This will clear the current graph, erasing any nodes and edges added,
/// before copying from other.
Graph& operator=(const Graph &other) {
clear();
copyFrom(other);
return *this;
}
/// \brief Add a node with the given costs. /// \brief Add a node with the given costs.
/// @param costs Cost vector for the new node. /// @param costs Cost vector for the new node.
/// @return Node iterator for the added node. /// @return Node iterator for the added node.
@@ -166,6 +195,13 @@ namespace PBQP {
/// @return Node cost vector. /// @return Node cost vector.
Vector& getNodeCosts(NodeItr nItr) { return getNode(nItr).getCosts(); } Vector& getNodeCosts(NodeItr nItr) { return getNode(nItr).getCosts(); }
/// \brief Get a node's cost vector (const version).
/// @param nItr Node iterator.
/// @return Node cost vector.
const Vector& getNodeCosts(ConstNodeItr nItr) const {
return getNode(nItr).getCosts();
}
/// \brief Set a node's data pointer. /// \brief Set a node's data pointer.
/// @param nItr Node iterator. /// @param nItr Node iterator.
/// @param data Pointer to node data. /// @param data Pointer to node data.
@@ -183,6 +219,13 @@ namespace PBQP {
/// @return Edge cost matrix. /// @return Edge cost matrix.
Matrix& getEdgeCosts(EdgeItr eItr) { return getEdge(eItr).getCosts(); } Matrix& getEdgeCosts(EdgeItr eItr) { return getEdge(eItr).getCosts(); }
/// \brief Get an edge's cost matrix (const version).
/// @param eItr Edge iterator.
/// @return Edge cost matrix.
const Matrix& getEdgeCosts(ConstEdgeItr eItr) const {
return getEdge(eItr).getCosts();
}
/// \brief Set an edge's data pointer. /// \brief Set an edge's data pointer.
/// @param eItr Edge iterator. /// @param eItr Edge iterator.
/// @param data Pointer to edge data. /// @param data Pointer to edge data.
@@ -205,9 +248,15 @@ namespace PBQP {
/// \brief Begin iterator for node set. /// \brief Begin iterator for node set.
NodeItr nodesBegin() { return nodes.begin(); } NodeItr nodesBegin() { return nodes.begin(); }
/// \brief Begin const iterator for node set.
ConstNodeItr nodesBegin() const { return nodes.begin(); }
/// \brief End iterator for node set. /// \brief End iterator for node set.
NodeItr nodesEnd() { return nodes.end(); } NodeItr nodesEnd() { return nodes.end(); }
/// \brief End const iterator for node set.
ConstNodeItr nodesEnd() const { return nodes.end(); }
/// \brief Begin iterator for edge set. /// \brief Begin iterator for edge set.
EdgeItr edgesBegin() { return edges.begin(); } EdgeItr edgesBegin() { return edges.begin(); }
@@ -342,6 +391,10 @@ namespace PBQP {
bool operator()(Graph::NodeItr n1, Graph::NodeItr n2) const { bool operator()(Graph::NodeItr n1, Graph::NodeItr n2) const {
return &*n1 < &*n2; return &*n1 < &*n2;
} }
bool operator()(Graph::ConstNodeItr n1, Graph::ConstNodeItr n2) const {
return &*n1 < &*n2;
}
}; };
class EdgeItrCompartor { class EdgeItrCompartor {
@@ -349,8 +402,23 @@ namespace PBQP {
bool operator()(Graph::EdgeItr e1, Graph::EdgeItr e2) const { bool operator()(Graph::EdgeItr e1, Graph::EdgeItr e2) const {
return &*e1 < &*e2; return &*e1 < &*e2;
} }
bool operator()(Graph::ConstEdgeItr e1, Graph::ConstEdgeItr e2) const {
return &*e1 < &*e2;
}
}; };
void Graph::copyFrom(const Graph &other) {
std::map<Graph::ConstNodeItr, Graph::NodeItr,
NodeItrComparator> nodeMap;
for (Graph::ConstNodeItr nItr = other.nodesBegin(),
nEnd = other.nodesEnd();
nItr != nEnd; ++nItr) {
nodeMap[nItr] = addNode(other.getNodeCosts(nItr));
}
}
} }

View File

@@ -107,8 +107,11 @@ namespace PBQP {
Solution s; Solution s;
std::vector<Graph::NodeItr> stack; std::vector<Graph::NodeItr> stack;
std::vector<NodeData> nodeData; typedef std::list<NodeData> NodeDataList;
std::vector<EdgeData> edgeData; NodeDataList nodeDataList;
typedef std::list<EdgeData> EdgeDataList;
EdgeDataList edgeDataList;
public: public:
@@ -364,8 +367,8 @@ namespace PBQP {
} else if (addedEdge) { } else if (addedEdge) {
// If the edge was added, and non-null, finish setting it up, add it to // If the edge was added, and non-null, finish setting it up, add it to
// the solver & notify heuristic. // the solver & notify heuristic.
edgeData.push_back(EdgeData()); edgeDataList.push_back(EdgeData());
g.setEdgeData(yzeItr, &edgeData.back()); g.setEdgeData(yzeItr, &edgeDataList.back());
addSolverEdge(yzeItr); addSolverEdge(yzeItr);
h.handleAddEdge(yzeItr); h.handleAddEdge(yzeItr);
} }
@@ -402,22 +405,18 @@ namespace PBQP {
simplify(); simplify();
} }
// Reserve space for the node and edge data.
nodeData.resize(g.getNumNodes());
edgeData.resize(g.getNumEdges());
// Create node data objects. // Create node data objects.
unsigned ndIndex = 0;
for (Graph::NodeItr nItr = g.nodesBegin(), nEnd = g.nodesEnd(); for (Graph::NodeItr nItr = g.nodesBegin(), nEnd = g.nodesEnd();
nItr != nEnd; ++nItr, ++ndIndex) { nItr != nEnd; ++nItr) {
g.setNodeData(nItr, &nodeData[ndIndex]); nodeDataList.push_back(NodeData());
g.setNodeData(nItr, &nodeDataList.back());
} }
// Create edge data objects. // Create edge data objects.
unsigned edIndex = 0;
for (Graph::EdgeItr eItr = g.edgesBegin(), eEnd = g.edgesEnd(); for (Graph::EdgeItr eItr = g.edgesBegin(), eEnd = g.edgesEnd();
eItr != eEnd; ++eItr, ++edIndex) { eItr != eEnd; ++eItr) {
g.setEdgeData(eItr, &edgeData[edIndex]); edgeDataList.push_back(EdgeData());
g.setEdgeData(eItr, &edgeDataList.back());
addSolverEdge(eItr); addSolverEdge(eItr);
} }
} }
@@ -563,8 +562,8 @@ namespace PBQP {
void cleanup() { void cleanup() {
h.cleanup(); h.cleanup();
nodeData.clear(); nodeDataList.clear();
edgeData.clear(); edgeDataList.clear();
} }
}; };