Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

466 lines
15 KiB

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