blob: 40fc9197a923fdabed175ea08d72fa4df7ad169b [file] [log] [blame]
Lang Hames030c4bf2010-01-26 04:49:58 +00001//===-------------------- Graph.h - PBQP Graph ------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// PBQP Graph class.
11//
12//===----------------------------------------------------------------------===//
13
14
15#ifndef LLVM_CODEGEN_PBQP_GRAPH_H
16#define LLVM_CODEGEN_PBQP_GRAPH_H
17
18#include "Math.h"
19
20#include <list>
21#include <vector>
22
23namespace PBQP {
24
25 /// PBQP Graph class.
26 /// Instances of this class describe PBQP problems.
27 class Graph {
28 private:
29
30 // ----- TYPEDEFS -----
31 class NodeEntry;
32 class EdgeEntry;
33
34 typedef std::list<NodeEntry> NodeList;
35 typedef std::list<EdgeEntry> EdgeList;
36
37 public:
38
39 typedef NodeList::iterator NodeItr;
40 typedef EdgeList::iterator EdgeItr;
41
42 private:
43
44 typedef std::list<EdgeItr> AdjEdgeList;
45
46 public:
47
48 typedef AdjEdgeList::iterator AdjEdgeItr;
49
50 private:
51
52 class NodeEntry {
53 private:
54 Vector costs;
55 AdjEdgeList adjEdges;
56 unsigned degree;
57 void *data;
58 public:
59 NodeEntry(const Vector &costs) : costs(costs), degree(0) {}
60 Vector& getCosts() { return costs; }
61 unsigned getDegree() const { return degree; }
62 AdjEdgeItr edgesBegin() { return adjEdges.begin(); }
63 AdjEdgeItr edgesEnd() { return adjEdges.end(); }
64 AdjEdgeItr addEdge(EdgeItr e) {
65 ++degree;
66 return adjEdges.insert(adjEdges.end(), e);
67 }
68 void removeEdge(AdjEdgeItr ae) {
69 --degree;
70 adjEdges.erase(ae);
71 }
72 void setData(void *data) { this->data = data; }
73 void* getData() { return data; }
74 };
75
76 class EdgeEntry {
77 private:
78 NodeItr node1, node2;
79 Matrix costs;
80 AdjEdgeItr node1AEItr, node2AEItr;
81 void *data;
82 public:
83 EdgeEntry(NodeItr node1, NodeItr node2, const Matrix &costs)
84 : node1(node1), node2(node2), costs(costs) {}
85 NodeItr getNode1() const { return node1; }
86 NodeItr getNode2() const { return node2; }
87 Matrix& getCosts() { return costs; }
88 void setNode1AEItr(AdjEdgeItr ae) { node1AEItr = ae; }
89 AdjEdgeItr getNode1AEItr() { return node1AEItr; }
90 void setNode2AEItr(AdjEdgeItr ae) { node2AEItr = ae; }
91 AdjEdgeItr getNode2AEItr() { return node2AEItr; }
92 void setData(void *data) { this->data = data; }
93 void *getData() { return data; }
94 };
95
96 // ----- MEMBERS -----
97
98 NodeList nodes;
99 unsigned numNodes;
100
101 EdgeList edges;
102 unsigned numEdges;
103
104 // ----- INTERNAL METHODS -----
105
106 NodeEntry& getNode(NodeItr nItr) { return *nItr; }
107 const NodeEntry& getNode(NodeItr nItr) const { return *nItr; }
108 EdgeEntry& getEdge(EdgeItr eItr) { return *eItr; }
109 const EdgeEntry& getEdge(EdgeItr eItr) const { return *eItr; }
110
111 NodeItr addConstructedNode(const NodeEntry &n) {
112 ++numNodes;
113 return nodes.insert(nodes.end(), n);
114 }
115
116 EdgeItr addConstructedEdge(const EdgeEntry &e) {
117 assert(findEdge(e.getNode1(), e.getNode2()) == edges.end() &&
118 "Attempt to add duplicate edge.");
119 ++numEdges;
120 EdgeItr edgeItr = edges.insert(edges.end(), e);
121 EdgeEntry &ne = getEdge(edgeItr);
122 NodeEntry &n1 = getNode(ne.getNode1());
123 NodeEntry &n2 = getNode(ne.getNode2());
124 // Sanity check on matrix dimensions:
125 assert((n1.getCosts().getLength() == ne.getCosts().getRows()) &&
126 (n2.getCosts().getLength() == ne.getCosts().getCols()) &&
127 "Edge cost dimensions do not match node costs dimensions.");
128 ne.setNode1AEItr(n1.addEdge(edgeItr));
129 ne.setNode2AEItr(n2.addEdge(edgeItr));
130 return edgeItr;
131 }
132
133 public:
134
135 Graph() : numNodes(0), numEdges(0) {}
136
137 /// \brief Add a node with the given costs.
138 /// @param costs Cost vector for the new node.
139 /// @return Node iterator for the added node.
140 NodeItr addNode(const Vector &costs) {
141 return addConstructedNode(NodeEntry(costs));
142 }
143
144 /// \brief Add an edge between the given nodes with the given costs.
145 /// @param n1Itr First node.
146 /// @param n2Itr Second node.
147 /// @return Edge iterator for the added edge.
148 EdgeItr addEdge(Graph::NodeItr n1Itr, Graph::NodeItr n2Itr,
149 const Matrix &costs) {
150 assert(getNodeCosts(n1Itr).getLength() == costs.getRows() &&
151 getNodeCosts(n2Itr).getLength() == costs.getCols() &&
152 "Matrix dimensions mismatch.");
153 return addConstructedEdge(EdgeEntry(n1Itr, n2Itr, costs));
154 }
155
156 /// \brief Get the number of nodes in the graph.
157 /// @return Number of nodes in the graph.
158 unsigned getNumNodes() const { return numNodes; }
159
160 /// \brief Get the number of edges in the graph.
161 /// @return Number of edges in the graph.
162 unsigned getNumEdges() const { return numEdges; }
163
164 /// \brief Get a node's cost vector.
165 /// @param nItr Node iterator.
166 /// @return Node cost vector.
167 Vector& getNodeCosts(NodeItr nItr) { return getNode(nItr).getCosts(); }
168
169 /// \brief Set a node's data pointer.
170 /// @param nItr Node iterator.
171 /// @param data Pointer to node data.
172 ///
173 /// Typically used by a PBQP solver to attach data to aid in solution.
174 void setNodeData(NodeItr nItr, void *data) { getNode(nItr).setData(data); }
175
176 /// \brief Get the node's data pointer.
177 /// @param nItr Node iterator.
178 /// @return Pointer to node data.
179 void* getNodeData(NodeItr nItr) { return getNode(nItr).getData(); }
180
181 /// \brief Get an edge's cost matrix.
182 /// @param eItr Edge iterator.
183 /// @return Edge cost matrix.
184 Matrix& getEdgeCosts(EdgeItr eItr) { return getEdge(eItr).getCosts(); }
185
186 /// \brief Set an edge's data pointer.
187 /// @param eItr Edge iterator.
188 /// @param data Pointer to edge data.
189 ///
190 /// Typically used by a PBQP solver to attach data to aid in solution.
191 void setEdgeData(EdgeItr eItr, void *data) { getEdge(eItr).setData(data); }
192
193 /// \brief Get an edge's data pointer.
194 /// @param eItr Edge iterator.
195 /// @return Pointer to edge data.
196 void* getEdgeData(EdgeItr eItr) { return getEdge(eItr).getData(); }
197
198 /// \brief Get a node's degree.
199 /// @param nItr Node iterator.
200 /// @return The degree of the node.
201 unsigned getNodeDegree(NodeItr nItr) const {
202 return getNode(nItr).getDegree();
203 }
204
205 /// \brief Begin iterator for node set.
206 NodeItr nodesBegin() { return nodes.begin(); }
207
208 /// \brief End iterator for node set.
209 NodeItr nodesEnd() { return nodes.end(); }
210
211 /// \brief Begin iterator for edge set.
212 EdgeItr edgesBegin() { return edges.begin(); }
213
214 /// \brief End iterator for edge set.
215 EdgeItr edgesEnd() { return edges.end(); }
216
217 /// \brief Get begin iterator for adjacent edge set.
218 /// @param nItr Node iterator.
219 /// @return Begin iterator for the set of edges connected to the given node.
220 AdjEdgeItr adjEdgesBegin(NodeItr nItr) {
221 return getNode(nItr).edgesBegin();
222 }
223
224 /// \brief Get end iterator for adjacent edge set.
225 /// @param nItr Node iterator.
226 /// @return End iterator for the set of edges connected to the given node.
227 AdjEdgeItr adjEdgesEnd(NodeItr nItr) {
228 return getNode(nItr).edgesEnd();
229 }
230
231 /// \brief Get the first node connected to this edge.
232 /// @param eItr Edge iterator.
233 /// @return The first node connected to the given edge.
234 NodeItr getEdgeNode1(EdgeItr eItr) {
235 return getEdge(eItr).getNode1();
236 }
237
238 /// \brief Get the second node connected to this edge.
239 /// @param eItr Edge iterator.
240 /// @return The second node connected to the given edge.
241 NodeItr getEdgeNode2(EdgeItr eItr) {
242 return getEdge(eItr).getNode2();
243 }
244
245 /// \brief Get the "other" node connected to this edge.
246 /// @param eItr Edge iterator.
247 /// @param nItr Node iterator for the "given" node.
248 /// @return The iterator for the "other" node connected to this edge.
249 NodeItr getEdgeOtherNode(EdgeItr eItr, NodeItr nItr) {
250 EdgeEntry &e = getEdge(eItr);
251 if (e.getNode1() == nItr) {
252 return e.getNode2();
253 } // else
254 return e.getNode1();
255 }
256
257 /// \brief Get the edge connecting two nodes.
258 /// @param n1Itr First node iterator.
259 /// @param n2Itr Second node iterator.
260 /// @return An iterator for edge (n1Itr, n2Itr) if such an edge exists,
261 /// otherwise returns edgesEnd().
262 EdgeItr findEdge(NodeItr n1Itr, NodeItr n2Itr) {
263 for (AdjEdgeItr aeItr = adjEdgesBegin(n1Itr), aeEnd = adjEdgesEnd(n1Itr);
264 aeItr != aeEnd; ++aeItr) {
265 if ((getEdgeNode1(*aeItr) == n2Itr) ||
266 (getEdgeNode2(*aeItr) == n2Itr)) {
267 return *aeItr;
268 }
269 }
270 return edges.end();
271 }
272
273 /// \brief Remove a node from the graph.
274 /// @param nItr Node iterator.
275 void removeNode(NodeItr nItr) {
276 NodeEntry &n = getNode(nItr);
277 for (AdjEdgeItr itr = n.edgesBegin(), end = n.edgesEnd(); itr != end;) {
278 EdgeItr eItr = *itr;
279 ++itr;
280 removeEdge(eItr);
281 }
282 nodes.erase(nItr);
283 --numNodes;
284 }
285
286 /// \brief Remove an edge from the graph.
287 /// @param eItr Edge iterator.
288 void removeEdge(EdgeItr eItr) {
289 EdgeEntry &e = getEdge(eItr);
290 NodeEntry &n1 = getNode(e.getNode1());
291 NodeEntry &n2 = getNode(e.getNode2());
292 n1.removeEdge(e.getNode1AEItr());
293 n2.removeEdge(e.getNode2AEItr());
294 edges.erase(eItr);
295 --numEdges;
296 }
297
298 /// \brief Remove all nodes and edges from the graph.
299 void clear() {
300 nodes.clear();
301 edges.clear();
302 numNodes = numEdges = 0;
303 }
304
305 /// \brief Print a representation of this graph in DOT format.
306 /// @param os Output stream to print on.
307 template <typename OStream>
308 void printDot(OStream &os) {
309
310 os << "graph {\n";
311
312 for (NodeItr nodeItr = nodesBegin(), nodeEnd = nodesEnd();
313 nodeItr != nodeEnd; ++nodeItr) {
314
315 os << " node" << nodeItr << " [ label=\""
316 << nodeItr << ": " << getNodeCosts(nodeItr) << "\" ]\n";
317 }
318
319 os << " edge [ len=" << getNumNodes() << " ]\n";
320
321 for (EdgeItr edgeItr = edgesBegin(), edgeEnd = edgesEnd();
322 edgeItr != edgeEnd; ++edgeItr) {
323
324 os << " node" << getEdgeNode1(edgeItr)
325 << " -- node" << getEdgeNode2(edgeItr)
326 << " [ label=\"";
327
328 const Matrix &edgeCosts = getEdgeCosts(edgeItr);
329
330 for (unsigned i = 0; i < edgeCosts.getRows(); ++i) {
331 os << edgeCosts.getRowAsVector(i) << "\\n";
332 }
333 os << "\" ]\n";
334 }
335 os << "}\n";
336 }
337
338 };
339
340 class NodeItrComparator {
341 public:
342 bool operator()(Graph::NodeItr n1, Graph::NodeItr n2) const {
343 return &*n1 < &*n2;
344 }
345 };
346
347 class EdgeItrCompartor {
348 public:
349 bool operator()(Graph::EdgeItr e1, Graph::EdgeItr e2) const {
350 return &*e1 < &*e2;
351 }
352 };
353
354
355}
356
357#endif // LLVM_CODEGEN_PBQP_GRAPH_HPP