vmap.h: Enables one to create maps with a virtual base class.
3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2006
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
9 * Permission to use, modify and distribute this software is granted
10 * provided that this copyright notice appears in all copies. For
11 * precise terms see the accompanying LICENSE file.
13 * This software is provided "AS IS" with no warranty of any kind,
14 * express or implied, and with no claim as to its suitability for any
23 #include <lemon/invalid.h>
24 #include <lemon/utility.h>
26 #include <lemon/bits/iterable_graph_extender.h>
27 #include <lemon/bits/alteration_notifier.h>
28 #include <lemon/bits/static_map.h>
29 #include <lemon/bits/graph_extender.h>
35 ///\brief GridGraph class.
39 /// \brief Base graph for GridGraph.
41 /// Base graph for grid graph. It describes some member functions
42 /// which can be used in the GridGraph.
44 /// \warning Always use the GridGraph instead of this.
50 typedef GridGraphBase Graph;
61 /// \brief Creates a grid graph with the given size.
63 /// Creates a grid graph with the given size.
64 void construct(int width, int height) {
65 _height = height; _width = width;
66 _nodeNum = height * width; _edgeNum = 2 * _nodeNum - width - height;
67 _edgeLimit = _nodeNum - width;
70 /// \brief Gives back the edge goes down from the node.
72 /// Gives back the edge goes down from the node. If there is not
73 /// outgoing edge then it gives back INVALID.
74 Edge _down(Node n) const {
75 if (n.id < _nodeNum - _width) {
82 /// \brief Gives back the edge comes from up into the node.
84 /// Gives back the edge comes from up into the node. If there is not
85 /// incoming edge then it gives back INVALID.
86 Edge _up(Node n) const {
88 return Edge(n.id - _width);
94 /// \brief Gives back the edge goes right from the node.
96 /// Gives back the edge goes right from the node. If there is not
97 /// outgoing edge then it gives back INVALID.
98 Edge _right(Node n) const {
99 if (n.id % _width < _width - 1) {
100 return _edgeLimit + n.id % _width + (n.id / _width) * (_width - 1);
106 /// \brief Gives back the edge comes from left into the node.
108 /// Gives back the edge comes left up into the node. If there is not
109 /// incoming edge then it gives back INVALID.
110 Edge _left(Node n) const {
111 if (n.id % _width > 0) {
112 return _edgeLimit + n.id % _width + (n.id / _width) * (_width - 1) - 1;
121 /// \brief The node on the given position.
123 /// Gives back the node on the given position.
124 Node operator()(int i, int j) const {
125 return Node(i + j * _width);
128 /// \brief Gives back the row index of the node.
130 /// Gives back the row index of the node.
131 int row(Node n) const {
132 return n.id / _width;
135 /// \brief Gives back the coloumn index of the node.
137 /// Gives back the coloumn index of the node.
138 int col(Node n) const {
139 return n.id % _width;
142 /// \brief Gives back the width of the graph.
144 /// Gives back the width of the graph.
149 /// \brief Gives back the height of the graph.
151 /// Gives back the height of the graph.
156 typedef True NodeNumTag;
157 typedef True EdgeNumTag;
160 int nodeNum() const { return _nodeNum; }
162 int edgeNum() const { return _edgeNum; }
168 int maxNodeId() const { return nodeNum() - 1; }
173 int maxEdgeId() const { return edgeNum() - 1; }
175 /// \brief Gives back the source node of an edge.
177 /// Gives back the source node of an edge.
178 Node source(Edge e) const {
179 if (e.id < _edgeLimit) {
182 return (e.id - _edgeLimit) % (_width - 1) +
183 (e.id - _edgeLimit) / (_width - 1) * _width;
187 /// \brief Gives back the target node of an edge.
189 /// Gives back the target node of an edge.
190 Node target(Edge e) const {
191 if (e.id < _edgeLimit) {
192 return e.id + _width;
194 return (e.id - _edgeLimit) % (_width - 1) +
195 (e.id - _edgeLimit) / (_width - 1) * _width + 1;
201 /// The ID of a valid Node is a nonnegative integer not greater than
202 /// \ref maxNodeId(). The range of the ID's is not surely continuous
203 /// and the greatest node ID can be actually less then \ref maxNodeId().
205 /// The ID of the \ref INVALID node is -1.
206 ///\return The ID of the node \c v.
208 static int id(Node v) { return v.id; }
211 /// The ID of a valid Edge is a nonnegative integer not greater than
212 /// \ref maxEdgeId(). The range of the ID's is not surely continuous
213 /// and the greatest edge ID can be actually less then \ref maxEdgeId().
215 /// The ID of the \ref INVALID edge is -1.
216 ///\return The ID of the edge \c e.
217 static int id(Edge e) { return e.id; }
219 static Node nodeFromId(int id) { return Node(id);}
221 static Edge edgeFromId(int id) { return Edge(id);}
223 typedef True FindEdgeTag;
225 /// Finds an edge between two nodes.
227 /// Finds an edge from node \c u to node \c v.
229 /// If \c prev is \ref INVALID (this is the default value), then
230 /// It finds the first edge from \c u to \c v. Otherwise it looks for
231 /// the next edge from \c u to \c v after \c prev.
232 /// \return The found edge or INVALID if there is no such an edge.
233 Edge findEdge(Node u, Node v, Edge prev = INVALID) const {
234 if (prev != INVALID) return INVALID;
235 if (v.id - u.id == _width) return Edge(u.id);
236 if (v.id - u.id == 1 && u.id % _width < _width - 1) {
237 return Edge(u.id / _width * (_width - 1) +
238 u.id % _width + _edgeLimit);
245 friend class GridGraphBase;
249 Node(int _id) { id = _id;}
252 Node (Invalid) { id = -1; }
253 bool operator==(const Node node) const {return id == node.id;}
254 bool operator!=(const Node node) const {return id != node.id;}
255 bool operator<(const Node node) const {return id < node.id;}
261 friend class GridGraphBase;
266 Edge(int _id) : id(_id) {}
270 Edge (Invalid) { id = -1; }
271 bool operator==(const Edge edge) const {return id == edge.id;}
272 bool operator!=(const Edge edge) const {return id != edge.id;}
273 bool operator<(const Edge edge) const {return id < edge.id;}
276 void first(Node& node) const {
277 node.id = nodeNum() - 1;
280 static void next(Node& node) {
284 void first(Edge& edge) const {
285 edge.id = edgeNum() - 1;
288 static void next(Edge& edge) {
292 void firstOut(Edge& edge, const Node& node) const {
293 if (node.id < _nodeNum - _width) {
295 } else if (node.id % _width < _width - 1) {
296 edge.id = _edgeLimit + node.id % _width +
297 (node.id / _width) * (_width - 1);
303 void nextOut(Edge& edge) const {
304 if (edge.id >= _edgeLimit) {
306 } else if (edge.id % _width < _width - 1) {
307 edge.id = _edgeLimit + edge.id % _width +
308 (edge.id / _width) * (_width - 1);
314 void firstIn(Edge& edge, const Node& node) const {
315 if (node.id >= _width) {
316 edge.id = node.id - _width;
317 } else if (node.id % _width > 0) {
318 edge.id = _edgeLimit + node.id % _width +
319 (node.id / _width) * (_width - 1) - 1;
325 void nextIn(Edge& edge) const {
326 if (edge.id >= _edgeLimit) {
328 } else if (edge.id % _width > 0) {
329 edge.id = _edgeLimit + edge.id % _width +
330 (edge.id / _width + 1) * (_width - 1) - 1;
338 int _nodeNum, _edgeNum;
343 typedef StaticMappableUGraphExtender<
344 IterableUGraphExtender<
345 AlterableUGraphExtender<
346 UGraphExtender<GridGraphBase> > > > ExtendedGridGraphBase;
350 /// \brief Grid graph class
352 /// This class implements a special graph type. The nodes of the
353 /// graph can be indiced by two integer \c (i,j) value where \c i
354 /// is in the \c [0,width) range and j is in the [0, height) range.
355 /// Two nodes are connected in the graph if the indices differ only
356 /// on one position and only one is the difference.
358 /// The graph can be indiced in the following way:
360 /// GridGraph graph(w, h);
361 /// GridGraph::NodeMap<int> val(graph);
362 /// for (int i = 0; i < graph.width(); ++i) {
363 /// for (int j = 0; j < graph.height(); ++j) {
364 /// val[graph(i, j)] = i + j;
369 /// The graph type is fully conform to the \ref concept::UGraph
370 /// "Undirected Graph" concept.
372 /// \author Balazs Dezso
373 /// \see GridGraphBase
374 class GridGraph : public ExtendedGridGraphBase {
377 /// \brief Map to get the indices of the nodes as xy<int>.
379 /// Map to get the indices of the nodes as xy<int>.
382 typedef True NeedCopy;
383 /// \brief The key type of the map
384 typedef GridGraph::Node Key;
385 /// \brief The value type of the map
386 typedef xy<int> Value;
388 /// \brief Constructor
391 IndexMap(const GridGraph& _graph) : graph(_graph) {}
393 /// \brief The subscript operator
395 /// The subscript operator.
396 Value operator[](Key key) const {
397 return xy<int>(graph.row(key), graph.col(key));
401 const GridGraph& graph;
404 /// \brief Map to get the row of the nodes.
406 /// Map to get the row of the nodes.
409 typedef True NeedCopy;
410 /// \brief The key type of the map
411 typedef GridGraph::Node Key;
412 /// \brief The value type of the map
415 /// \brief Constructor
418 RowMap(const GridGraph& _graph) : graph(_graph) {}
420 /// \brief The subscript operator
422 /// The subscript operator.
423 Value operator[](Key key) const {
424 return graph.row(key);
428 const GridGraph& graph;
431 /// \brief Map to get the column of the nodes.
433 /// Map to get the column of the nodes.
436 typedef True NeedCopy;
437 /// \brief The key type of the map
438 typedef GridGraph::Node Key;
439 /// \brief The value type of the map
442 /// \brief Constructor
445 ColMap(const GridGraph& _graph) : graph(_graph) {}
447 /// \brief The subscript operator
449 /// The subscript operator.
450 Value operator[](Key key) const {
451 return graph.col(key);
455 const GridGraph& graph;
458 /// \brief Constructor
461 GridGraph(int n, int m) { construct(n, m); }
463 /// \brief Gives back the edge goes down from the node.
465 /// Gives back the edge goes down from the node. If there is not
466 /// outgoing edge then it gives back INVALID.
467 Edge down(Node n) const {
469 return ue != INVALID ? direct(ue, true) : INVALID;
472 /// \brief Gives back the edge goes up from the node.
474 /// Gives back the edge goes up from the node. If there is not
475 /// outgoing edge then it gives back INVALID.
476 Edge up(Node n) const {
478 return ue != INVALID ? direct(ue, false) : INVALID;
481 /// \brief Gives back the edge goes right from the node.
483 /// Gives back the edge goes right from the node. If there is not
484 /// outgoing edge then it gives back INVALID.
485 Edge right(Node n) const {
486 UEdge ue = _right(n);
487 return ue != INVALID ? direct(ue, true) : INVALID;
490 /// \brief Gives back the edge goes left from the node.
492 /// Gives back the edge goes left from the node. If there is not
493 /// outgoing edge then it gives back INVALID.
494 Edge left(Node n) const {
496 return ue != INVALID ? direct(ue, false) : INVALID;
501 /// \brief Index map of the grid graph
503 /// Just returns an IndexMap for the grid graph.
504 GridGraph::IndexMap indexMap(const GridGraph& graph) {
505 return GridGraph::IndexMap(graph);
508 /// \brief Row map of the grid graph
510 /// Just returns a RowMap for the grid graph.
511 GridGraph::RowMap rowMap(const GridGraph& graph) {
512 return GridGraph::RowMap(graph);
515 /// \brief Column map of the grid graph
517 /// Just returns a ColMap for the grid graph.
518 GridGraph::ColMap colMap(const GridGraph& graph) {
519 return GridGraph::ColMap(graph);