2 * lemon/grid_graph.h - Part of LEMON, a generic C++ optimization library
4 * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
5 * (Egervary Research Group on Combinatorial Optimization, EGRES).
7 * Permission to use, modify and distribute this software is granted
8 * provided that this copyright notice appears in all copies. For
9 * precise terms see the accompanying LICENSE file.
11 * This software is provided "AS IS" with no warranty of any kind,
12 * express or implied, and with no claim as to its suitability for any
21 #include <lemon/invalid.h>
22 #include <lemon/utility.h>
24 #include <lemon/bits/iterable_graph_extender.h>
25 #include <lemon/bits/alteration_notifier.h>
26 #include <lemon/bits/static_map.h>
28 #include <lemon/bits/undir_graph_extender.h>
34 ///\brief GridGraph class.
38 /// \brief Base graph for GridGraph.
40 /// Base graph for grid graph. It describes some member functions
41 /// which can be used in the GridGraph.
43 /// \warning Always use the GridGraph instead of this.
49 typedef GridGraphBase Graph;
60 /// \brief Creates a grid graph with the given size.
62 /// Creates a grid graph with the given size.
63 void construct(int width, int height) {
64 _height = height; _width = width;
65 _nodeNum = height * width; _edgeNum = 2 * _nodeNum - width - height;
66 _edgeLimit = _nodeNum - width;
69 /// \brief Gives back the edge goes down from the node.
71 /// Gives back the edge goes down from the node. If there is not
72 /// outgoing edge then it gives back INVALID.
73 Edge _down(Node n) const {
74 if (n.id < _nodeNum - _width) {
81 /// \brief Gives back the edge comes from up into the node.
83 /// Gives back the edge comes from up into the node. If there is not
84 /// incoming edge then it gives back INVALID.
85 Edge _up(Node n) const {
87 return Edge(n.id - _width);
93 /// \brief Gives back the edge goes right from the node.
95 /// Gives back the edge goes right from the node. If there is not
96 /// outgoing edge then it gives back INVALID.
97 Edge _right(Node n) const {
98 if (n.id % _width < _width - 1) {
99 return _edgeLimit + n.id % _width + (n.id / _width) * (_width - 1);
105 /// \brief Gives back the edge comes from left into the node.
107 /// Gives back the edge comes left up into the node. If there is not
108 /// incoming edge then it gives back INVALID.
109 Edge _left(Node n) const {
110 if (n.id % _width > 0) {
111 return _edgeLimit + n.id % _width + (n.id / _width) * (_width - 1) - 1;
120 /// \brief The node on the given position.
122 /// Gives back the node on the given position.
123 Node operator()(int i, int j) const {
124 return Node(i + j * _width);
127 /// \brief Gives back the row index of the node.
129 /// Gives back the row index of the node.
130 int row(Node n) const {
131 return n.id / _width;
134 /// \brief Gives back the coloumn index of the node.
136 /// Gives back the coloumn index of the node.
137 int col(Node n) const {
138 return n.id % _width;
141 /// \brief Gives back the width of the graph.
143 /// Gives back the width of the graph.
148 /// \brief Gives back the height of the graph.
150 /// Gives back the height of the graph.
155 typedef True NodeNumTag;
156 typedef True EdgeNumTag;
159 int nodeNum() const { return _nodeNum; }
161 int edgeNum() const { return _edgeNum; }
167 int maxId(Node = INVALID) const { return nodeNum() - 1; }
172 int maxId(Edge = INVALID) const { return edgeNum() - 1; }
174 /// \brief Gives back the source node of an edge.
176 /// Gives back the source node of an edge.
177 Node source(Edge e) const {
178 if (e.id < _edgeLimit) {
181 return (e.id - _edgeLimit) % (_width - 1) +
182 (e.id - _edgeLimit) / (_width - 1) * _width;
186 /// \brief Gives back the target node of an edge.
188 /// Gives back the target node of an edge.
189 Node target(Edge e) const {
190 if (e.id < _edgeLimit) {
191 return e.id + _width;
193 return (e.id - _edgeLimit) % (_width - 1) +
194 (e.id - _edgeLimit) / (_width - 1) * _width + 1;
200 /// The ID of a valid Node is a nonnegative integer not greater than
201 /// \ref maxNodeId(). The range of the ID's is not surely continuous
202 /// and the greatest node ID can be actually less then \ref maxNodeId().
204 /// The ID of the \ref INVALID node is -1.
205 ///\return The ID of the node \c v.
207 static int id(Node v) { return v.id; }
210 /// The ID of a valid Edge is a nonnegative integer not greater than
211 /// \ref maxEdgeId(). The range of the ID's is not surely continuous
212 /// and the greatest edge ID can be actually less then \ref maxEdgeId().
214 /// The ID of the \ref INVALID edge is -1.
215 ///\return The ID of the edge \c e.
216 static int id(Edge e) { return e.id; }
218 static Node fromId(int id, Node) { return Node(id);}
220 static Edge fromId(int id, Edge) { return Edge(id);}
222 typedef True FindEdgeTag;
224 /// Finds an edge between two nodes.
226 /// Finds an edge from node \c u to node \c v.
228 /// If \c prev is \ref INVALID (this is the default value), then
229 /// It finds the first edge from \c u to \c v. Otherwise it looks for
230 /// the next edge from \c u to \c v after \c prev.
231 /// \return The found edge or INVALID if there is no such an edge.
232 Edge findEdge(Node u, Node v, Edge prev = INVALID) {
233 if (prev != INVALID) return INVALID;
234 if (v.id - u.id == _width) return Edge(u.id);
235 if (v.id - u.id == 1 && u.id % _width < _width - 1) {
236 return Edge(u.id / _width * (_width - 1) +
237 u.id % _width + _edgeLimit);
244 friend class GridGraphBase;
248 Node(int _id) { id = _id;}
251 Node (Invalid) { id = -1; }
252 bool operator==(const Node node) const {return id == node.id;}
253 bool operator!=(const Node node) const {return id != node.id;}
254 bool operator<(const Node node) const {return id < node.id;}
260 friend class GridGraphBase;
265 Edge(int _id) : id(_id) {}
269 Edge (Invalid) { id = -1; }
270 bool operator==(const Edge edge) const {return id == edge.id;}
271 bool operator!=(const Edge edge) const {return id != edge.id;}
272 bool operator<(const Edge edge) const {return id < edge.id;}
275 void first(Node& node) const {
276 node.id = nodeNum() - 1;
279 static void next(Node& node) {
283 void first(Edge& edge) const {
284 edge.id = edgeNum() - 1;
287 static void next(Edge& edge) {
291 void firstOut(Edge& edge, const Node& node) const {
292 if (node.id < _nodeNum - _width) {
294 } else if (node.id % _width < _width - 1) {
295 edge.id = _edgeLimit + node.id % _width +
296 (node.id / _width) * (_width - 1);
302 void nextOut(Edge& edge) const {
303 if (edge.id >= _edgeLimit) {
305 } else if (edge.id % _width < _width - 1) {
306 edge.id = _edgeLimit + edge.id % _width +
307 (edge.id / _width) * (_width - 1);
313 void firstIn(Edge& edge, const Node& node) const {
314 if (node.id >= _width) {
315 edge.id = node.id - _width;
316 } else if (node.id % _width > 0) {
317 edge.id = _edgeLimit + node.id % _width +
318 (node.id / _width) * (_width - 1) - 1;
324 void nextIn(Edge& edge) const {
325 if (edge.id >= _edgeLimit) {
327 } else if (edge.id % _width > 0) {
328 edge.id = _edgeLimit + edge.id % _width +
329 (edge.id / _width + 1) * (_width - 1) - 1;
337 int _nodeNum, _edgeNum;
342 typedef StaticMappableUndirGraphExtender<
343 IterableUndirGraphExtender<
344 AlterableUndirGraphExtender<
345 UndirGraphExtender<GridGraphBase> > > > ExtendedGridGraphBase;
349 /// \brief Grid graph class
351 /// This class implements a special graph type. The nodes of the
352 /// graph can be indiced by two integer \c (i,j) value where \c i
353 /// is in the \c [0,height) range and j is in the [0, width) range.
354 /// Two nodes are connected in the graph if the indices differ only
355 /// on one position and only one is the difference.
357 /// The graph can be indiced in the following way:
359 /// GridGraph graph(h, w);
360 /// GridGraph::NodeMap<int> val(graph);
361 /// for (int i = 0; i < graph.height(); ++i) {
362 /// for (int j = 0; j < graph.width(); ++j) {
363 /// val[graph(i, j)] = i + j;
368 /// The graph type is fully conform to the \ref concept::UndirGraph
369 /// "Undirected Graph" concept.
371 /// \author Balazs Dezso
372 /// \see GridGraphBase
373 class GridGraph : public ExtendedGridGraphBase {
376 /// \brief Map to get the indices of the nodes as xy<int>.
378 /// Map to get the indices of the nodes as xy<int>.
381 typedef True NeedCopy;
382 /// \brief The key type of the map
383 typedef GridGraph::Node Key;
384 /// \brief The value type of the map
385 typedef xy<int> Value;
387 /// \brief Constructor
390 IndexMap(const GridGraph& _graph) : graph(_graph) {}
392 /// \brief The subscript operator
394 /// The subscript operator.
395 Value operator[](Key key) const {
396 return xy<int>(graph.row(key), graph.col(key));
400 const GridGraph& graph;
403 /// \brief Map to get the row of the nodes.
405 /// Map to get the row of the nodes.
408 typedef True NeedCopy;
409 /// \brief The key type of the map
410 typedef GridGraph::Node Key;
411 /// \brief The value type of the map
414 /// \brief Constructor
417 RowMap(const GridGraph& _graph) : graph(_graph) {}
419 /// \brief The subscript operator
421 /// The subscript operator.
422 Value operator[](Key key) const {
423 return graph.row(key);
427 const GridGraph& graph;
430 /// \brief Map to get the column of the nodes.
432 /// Map to get the column of the nodes.
435 typedef True NeedCopy;
436 /// \brief The key type of the map
437 typedef GridGraph::Node Key;
438 /// \brief The value type of the map
441 /// \brief Constructor
444 ColMap(const GridGraph& _graph) : graph(_graph) {}
446 /// \brief The subscript operator
448 /// The subscript operator.
449 Value operator[](Key key) const {
450 return graph.col(key);
454 const GridGraph& graph;
457 GridGraph(int n, int m) { construct(n, m); }
459 /// \brief Gives back the edge goes down from the node.
461 /// Gives back the edge goes down from the node. If there is not
462 /// outgoing edge then it gives back INVALID.
463 Edge down(Node n) const {
464 UndirEdge ue = _down(n);
465 return ue != INVALID ? direct(ue, true) : INVALID;
468 /// \brief Gives back the edge goes up from the node.
470 /// Gives back the edge goes up from the node. If there is not
471 /// outgoing edge then it gives back INVALID.
472 Edge up(Node n) const {
473 UndirEdge ue = _up(n);
474 return ue != INVALID ? direct(ue, false) : INVALID;
477 /// \brief Gives back the edge goes right from the node.
479 /// Gives back the edge goes right from the node. If there is not
480 /// outgoing edge then it gives back INVALID.
481 Edge right(Node n) const {
482 UndirEdge ue = _right(n);
483 return ue != INVALID ? direct(ue, true) : INVALID;
486 /// \brief Gives back the edge goes left from the node.
488 /// Gives back the edge goes left from the node. If there is not
489 /// outgoing edge then it gives back INVALID.
490 Edge left(Node n) const {
491 UndirEdge ue = _left(n);
492 return ue != INVALID ? direct(ue, false) : INVALID;
497 /// \brief Index map of the grid graph
499 /// Just returns an IndexMap for the grid graph.
500 GridGraph::IndexMap indexMap(const GridGraph& graph) {
501 return GridGraph::IndexMap(graph);
504 /// \brief Row map of the grid graph
506 /// Just returns an RowMap for the grid graph.
507 GridGraph::RowMap rowMap(const GridGraph& graph) {
508 return GridGraph::RowMap(graph);
511 /// \brief Coloumn map of the grid graph
513 /// Just returns an ColMap for the grid graph.
514 GridGraph::ColMap colMap(const GridGraph& graph) {
515 return GridGraph::ColMap(graph);