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>
27 #include <lemon/bits/graph_extender.h>
33 ///\brief GridGraph class.
37 /// \brief Base graph for GridGraph.
39 /// Base graph for grid graph. It describes some member functions
40 /// which can be used in the GridGraph.
42 /// \warning Always use the GridGraph instead of this.
48 typedef GridGraphBase Graph;
59 /// \brief Creates a grid graph with the given size.
61 /// Creates a grid graph with the given size.
62 void construct(int width, int height) {
63 _height = height; _width = width;
64 _nodeNum = height * width; _edgeNum = 2 * _nodeNum - width - height;
65 _edgeLimit = _nodeNum - width;
68 /// \brief Gives back the edge goes down from the node.
70 /// Gives back the edge goes down from the node. If there is not
71 /// outgoing edge then it gives back INVALID.
72 Edge _down(Node n) const {
73 if (n.id < _nodeNum - _width) {
80 /// \brief Gives back the edge comes from up into the node.
82 /// Gives back the edge comes from up into the node. If there is not
83 /// incoming edge then it gives back INVALID.
84 Edge _up(Node n) const {
86 return Edge(n.id - _width);
92 /// \brief Gives back the edge goes right from the node.
94 /// Gives back the edge goes right from the node. If there is not
95 /// outgoing edge then it gives back INVALID.
96 Edge _right(Node n) const {
97 if (n.id % _width < _width - 1) {
98 return _edgeLimit + n.id % _width + (n.id / _width) * (_width - 1);
104 /// \brief Gives back the edge comes from left into the node.
106 /// Gives back the edge comes left up into the node. If there is not
107 /// incoming edge then it gives back INVALID.
108 Edge _left(Node n) const {
109 if (n.id % _width > 0) {
110 return _edgeLimit + n.id % _width + (n.id / _width) * (_width - 1) - 1;
119 /// \brief The node on the given position.
121 /// Gives back the node on the given position.
122 Node operator()(int i, int j) const {
123 return Node(i + j * _width);
126 /// \brief Gives back the row index of the node.
128 /// Gives back the row index of the node.
129 int row(Node n) const {
130 return n.id / _width;
133 /// \brief Gives back the coloumn index of the node.
135 /// Gives back the coloumn index of the node.
136 int col(Node n) const {
137 return n.id % _width;
140 /// \brief Gives back the width of the graph.
142 /// Gives back the width of the graph.
147 /// \brief Gives back the height of the graph.
149 /// Gives back the height of the graph.
154 typedef True NodeNumTag;
155 typedef True EdgeNumTag;
158 int nodeNum() const { return _nodeNum; }
160 int edgeNum() const { return _edgeNum; }
166 int maxNodeId() const { return nodeNum() - 1; }
171 int maxEdgeId() const { return edgeNum() - 1; }
173 /// \brief Gives back the source node of an edge.
175 /// Gives back the source node of an edge.
176 Node source(Edge e) const {
177 if (e.id < _edgeLimit) {
180 return (e.id - _edgeLimit) % (_width - 1) +
181 (e.id - _edgeLimit) / (_width - 1) * _width;
185 /// \brief Gives back the target node of an edge.
187 /// Gives back the target node of an edge.
188 Node target(Edge e) const {
189 if (e.id < _edgeLimit) {
190 return e.id + _width;
192 return (e.id - _edgeLimit) % (_width - 1) +
193 (e.id - _edgeLimit) / (_width - 1) * _width + 1;
199 /// The ID of a valid Node is a nonnegative integer not greater than
200 /// \ref maxNodeId(). The range of the ID's is not surely continuous
201 /// and the greatest node ID can be actually less then \ref maxNodeId().
203 /// The ID of the \ref INVALID node is -1.
204 ///\return The ID of the node \c v.
206 static int id(Node v) { return v.id; }
209 /// The ID of a valid Edge is a nonnegative integer not greater than
210 /// \ref maxEdgeId(). The range of the ID's is not surely continuous
211 /// and the greatest edge ID can be actually less then \ref maxEdgeId().
213 /// The ID of the \ref INVALID edge is -1.
214 ///\return The ID of the edge \c e.
215 static int id(Edge e) { return e.id; }
217 static Node nodeFromId(int id) { return Node(id);}
219 static Edge edgeFromId(int id) { return Edge(id);}
221 typedef True FindEdgeTag;
223 /// Finds an edge between two nodes.
225 /// Finds an edge from node \c u to node \c v.
227 /// If \c prev is \ref INVALID (this is the default value), then
228 /// It finds the first edge from \c u to \c v. Otherwise it looks for
229 /// the next edge from \c u to \c v after \c prev.
230 /// \return The found edge or INVALID if there is no such an edge.
231 Edge findEdge(Node u, Node v, Edge prev = INVALID) {
232 if (prev != INVALID) return INVALID;
233 if (v.id - u.id == _width) return Edge(u.id);
234 if (v.id - u.id == 1 && u.id % _width < _width - 1) {
235 return Edge(u.id / _width * (_width - 1) +
236 u.id % _width + _edgeLimit);
243 friend class GridGraphBase;
247 Node(int _id) { id = _id;}
250 Node (Invalid) { id = -1; }
251 bool operator==(const Node node) const {return id == node.id;}
252 bool operator!=(const Node node) const {return id != node.id;}
253 bool operator<(const Node node) const {return id < node.id;}
259 friend class GridGraphBase;
264 Edge(int _id) : id(_id) {}
268 Edge (Invalid) { id = -1; }
269 bool operator==(const Edge edge) const {return id == edge.id;}
270 bool operator!=(const Edge edge) const {return id != edge.id;}
271 bool operator<(const Edge edge) const {return id < edge.id;}
274 void first(Node& node) const {
275 node.id = nodeNum() - 1;
278 static void next(Node& node) {
282 void first(Edge& edge) const {
283 edge.id = edgeNum() - 1;
286 static void next(Edge& edge) {
290 void firstOut(Edge& edge, const Node& node) const {
291 if (node.id < _nodeNum - _width) {
293 } else if (node.id % _width < _width - 1) {
294 edge.id = _edgeLimit + node.id % _width +
295 (node.id / _width) * (_width - 1);
301 void nextOut(Edge& edge) const {
302 if (edge.id >= _edgeLimit) {
304 } else if (edge.id % _width < _width - 1) {
305 edge.id = _edgeLimit + edge.id % _width +
306 (edge.id / _width) * (_width - 1);
312 void firstIn(Edge& edge, const Node& node) const {
313 if (node.id >= _width) {
314 edge.id = node.id - _width;
315 } else if (node.id % _width > 0) {
316 edge.id = _edgeLimit + node.id % _width +
317 (node.id / _width) * (_width - 1) - 1;
323 void nextIn(Edge& edge) const {
324 if (edge.id >= _edgeLimit) {
326 } else if (edge.id % _width > 0) {
327 edge.id = _edgeLimit + edge.id % _width +
328 (edge.id / _width + 1) * (_width - 1) - 1;
336 int _nodeNum, _edgeNum;
341 typedef StaticMappableUndirGraphExtender<
342 IterableUndirGraphExtender<
343 AlterableUndirGraphExtender<
344 UndirGraphExtender<GridGraphBase> > > > ExtendedGridGraphBase;
348 /// \brief Grid graph class
350 /// This class implements a special graph type. The nodes of the
351 /// graph can be indiced by two integer \c (i,j) value where \c i
352 /// is in the \c [0,height) range and j is in the [0, width) range.
353 /// Two nodes are connected in the graph if the indices differ only
354 /// on one position and only one is the difference.
356 /// The graph can be indiced in the following way:
358 /// GridGraph graph(h, w);
359 /// GridGraph::NodeMap<int> val(graph);
360 /// for (int i = 0; i < graph.width(); ++i) {
361 /// for (int j = 0; j < graph.height(); ++j) {
362 /// val[graph(i, j)] = i + j;
367 /// The graph type is fully conform to the \ref concept::UndirGraph
368 /// "Undirected Graph" concept.
370 /// \author Balazs Dezso
371 /// \see GridGraphBase
372 class GridGraph : public ExtendedGridGraphBase {
375 /// \brief Map to get the indices of the nodes as xy<int>.
377 /// Map to get the indices of the nodes as xy<int>.
380 typedef True NeedCopy;
381 /// \brief The key type of the map
382 typedef GridGraph::Node Key;
383 /// \brief The value type of the map
384 typedef xy<int> Value;
386 /// \brief Constructor
389 IndexMap(const GridGraph& _graph) : graph(_graph) {}
391 /// \brief The subscript operator
393 /// The subscript operator.
394 Value operator[](Key key) const {
395 return xy<int>(graph.row(key), graph.col(key));
399 const GridGraph& graph;
402 /// \brief Map to get the row of the nodes.
404 /// Map to get the row of the nodes.
407 typedef True NeedCopy;
408 /// \brief The key type of the map
409 typedef GridGraph::Node Key;
410 /// \brief The value type of the map
413 /// \brief Constructor
416 RowMap(const GridGraph& _graph) : graph(_graph) {}
418 /// \brief The subscript operator
420 /// The subscript operator.
421 Value operator[](Key key) const {
422 return graph.row(key);
426 const GridGraph& graph;
429 /// \brief Map to get the column of the nodes.
431 /// Map to get the column of the nodes.
434 typedef True NeedCopy;
435 /// \brief The key type of the map
436 typedef GridGraph::Node Key;
437 /// \brief The value type of the map
440 /// \brief Constructor
443 ColMap(const GridGraph& _graph) : graph(_graph) {}
445 /// \brief The subscript operator
447 /// The subscript operator.
448 Value operator[](Key key) const {
449 return graph.col(key);
453 const GridGraph& graph;
456 GridGraph(int n, int m) { construct(n, m); }
458 /// \brief Gives back the edge goes down from the node.
460 /// Gives back the edge goes down from the node. If there is not
461 /// outgoing edge then it gives back INVALID.
462 Edge down(Node n) const {
463 UndirEdge ue = _down(n);
464 return ue != INVALID ? direct(ue, true) : INVALID;
467 /// \brief Gives back the edge goes up from the node.
469 /// Gives back the edge goes up from the node. If there is not
470 /// outgoing edge then it gives back INVALID.
471 Edge up(Node n) const {
472 UndirEdge ue = _up(n);
473 return ue != INVALID ? direct(ue, false) : INVALID;
476 /// \brief Gives back the edge goes right from the node.
478 /// Gives back the edge goes right from the node. If there is not
479 /// outgoing edge then it gives back INVALID.
480 Edge right(Node n) const {
481 UndirEdge ue = _right(n);
482 return ue != INVALID ? direct(ue, true) : INVALID;
485 /// \brief Gives back the edge goes left from the node.
487 /// Gives back the edge goes left from the node. If there is not
488 /// outgoing edge then it gives back INVALID.
489 Edge left(Node n) const {
490 UndirEdge ue = _left(n);
491 return ue != INVALID ? direct(ue, false) : INVALID;
496 /// \brief Index map of the grid graph
498 /// Just returns an IndexMap for the grid graph.
499 GridGraph::IndexMap indexMap(const GridGraph& graph) {
500 return GridGraph::IndexMap(graph);
503 /// \brief Row map of the grid graph
505 /// Just returns a RowMap for the grid graph.
506 GridGraph::RowMap rowMap(const GridGraph& graph) {
507 return GridGraph::RowMap(graph);
510 /// \brief Column map of the grid graph
512 /// Just returns a ColMap for the grid graph.
513 GridGraph::ColMap colMap(const GridGraph& graph) {
514 return GridGraph::ColMap(graph);