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/bits/invalid.h>
24 #include <lemon/bits/utility.h>
26 #include <lemon/bits/base_extender.h>
27 #include <lemon/bits/graph_extender.h>
33 ///\brief GridUGraph class.
37 /// \brief Base graph for GridUGraph.
39 /// Base graph for grid graph. It describes some member functions
40 /// which can be used in the GridUGraph.
42 /// \warning Always use the GridUGraph instead of this.
44 class GridUGraphBase {
48 typedef GridUGraphBase UGraph;
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;
118 class IndexError : public RuntimeError {
120 virtual const char* exceptionName() const {
121 return "lemon::GridUGraph::IndexError";
126 /// \brief The node on the given position.
128 /// Gives back the node on the given position.
129 Node operator()(int i, int j) const {
130 LEMON_ASSERT(0 <= i && i < width() && 0 <= j &&
131 j < height(), IndexError());
132 return Node(i + j * _width);
135 /// \brief Gives back the row index of the node.
137 /// Gives back the row index of the node.
138 int row(Node n) const {
139 return n.id / _width;
142 /// \brief Gives back the coloumn index of the node.
144 /// Gives back the coloumn index of the node.
145 int col(Node n) const {
146 return n.id % _width;
149 /// \brief Gives back the width of the graph.
151 /// Gives back the width of the graph.
156 /// \brief Gives back the height of the graph.
158 /// Gives back the height of the graph.
163 typedef True NodeNumTag;
164 typedef True EdgeNumTag;
167 int nodeNum() const { return _nodeNum; }
169 int edgeNum() const { return _edgeNum; }
175 int maxNodeId() const { return nodeNum() - 1; }
180 int maxEdgeId() const { return edgeNum() - 1; }
182 /// \brief Gives back the source node of an edge.
184 /// Gives back the source node of an edge.
185 Node source(Edge e) const {
186 if (e.id < _edgeLimit) {
189 return (e.id - _edgeLimit) % (_width - 1) +
190 (e.id - _edgeLimit) / (_width - 1) * _width;
194 /// \brief Gives back the target node of an edge.
196 /// Gives back the target node of an edge.
197 Node target(Edge e) const {
198 if (e.id < _edgeLimit) {
199 return e.id + _width;
201 return (e.id - _edgeLimit) % (_width - 1) +
202 (e.id - _edgeLimit) / (_width - 1) * _width + 1;
208 /// The ID of a valid Node is a nonnegative integer not greater than
209 /// \ref maxNodeId(). The range of the ID's is not surely continuous
210 /// and the greatest node ID can be actually less then \ref maxNodeId().
212 /// The ID of the \ref INVALID node is -1.
213 ///\return The ID of the node \c v.
215 static int id(Node v) { return v.id; }
218 /// The ID of a valid Edge is a nonnegative integer not greater than
219 /// \ref maxEdgeId(). The range of the ID's is not surely continuous
220 /// and the greatest edge ID can be actually less then \ref maxEdgeId().
222 /// The ID of the \ref INVALID edge is -1.
223 ///\return The ID of the edge \c e.
224 static int id(Edge e) { return e.id; }
226 static Node nodeFromId(int id) { return Node(id);}
228 static Edge edgeFromId(int id) { return Edge(id);}
230 typedef True FindEdgeTag;
232 /// Finds an edge between two nodes.
234 /// Finds an edge from node \c u to node \c v.
236 /// If \c prev is \ref INVALID (this is the default value), then
237 /// It finds the first edge from \c u to \c v. Otherwise it looks for
238 /// the next edge from \c u to \c v after \c prev.
239 /// \return The found edge or INVALID if there is no such an edge.
240 Edge findEdge(Node u, Node v, Edge prev = INVALID) const {
241 if (prev != INVALID) return INVALID;
242 if (v.id - u.id == _width) return Edge(u.id);
243 if (v.id - u.id == 1 && u.id % _width < _width - 1) {
244 return Edge(u.id / _width * (_width - 1) +
245 u.id % _width + _edgeLimit);
252 friend class GridUGraphBase;
256 Node(int _id) { id = _id;}
259 Node (Invalid) { id = -1; }
260 bool operator==(const Node node) const {return id == node.id;}
261 bool operator!=(const Node node) const {return id != node.id;}
262 bool operator<(const Node node) const {return id < node.id;}
268 friend class GridUGraphBase;
273 Edge(int _id) : id(_id) {}
277 Edge (Invalid) { id = -1; }
278 bool operator==(const Edge edge) const {return id == edge.id;}
279 bool operator!=(const Edge edge) const {return id != edge.id;}
280 bool operator<(const Edge edge) const {return id < edge.id;}
283 void first(Node& node) const {
284 node.id = nodeNum() - 1;
287 static void next(Node& node) {
291 void first(Edge& edge) const {
292 edge.id = edgeNum() - 1;
295 static void next(Edge& edge) {
299 void firstOut(Edge& edge, const Node& node) const {
300 if (node.id < _nodeNum - _width) {
302 } else if (node.id % _width < _width - 1) {
303 edge.id = _edgeLimit + node.id % _width +
304 (node.id / _width) * (_width - 1);
310 void nextOut(Edge& edge) const {
311 if (edge.id >= _edgeLimit) {
313 } else if (edge.id % _width < _width - 1) {
314 edge.id = _edgeLimit + edge.id % _width +
315 (edge.id / _width) * (_width - 1);
321 void firstIn(Edge& edge, const Node& node) const {
322 if (node.id >= _width) {
323 edge.id = node.id - _width;
324 } else if (node.id % _width > 0) {
325 edge.id = _edgeLimit + node.id % _width +
326 (node.id / _width) * (_width - 1) - 1;
332 void nextIn(Edge& edge) const {
333 if (edge.id >= _edgeLimit) {
335 } else if (edge.id % _width > 0) {
336 edge.id = _edgeLimit + edge.id % _width +
337 (edge.id / _width + 1) * (_width - 1) - 1;
345 int _nodeNum, _edgeNum;
350 typedef UGraphExtender<UGraphBaseExtender<
351 GridUGraphBase> > ExtendedGridUGraphBase;
355 /// \brief Grid graph class
357 /// This class implements a special graph type. The nodes of the
358 /// graph can be indiced by two integer \c (i,j) value where \c i
359 /// is in the \c [0,width) range and j is in the [0, height) range.
360 /// Two nodes are connected in the graph if the indices differ only
361 /// on one position and only one is the difference.
363 /// The graph can be indiced in the following way:
365 /// GridUGraph graph(w, h);
366 /// GridUGraph::NodeMap<int> val(graph);
367 /// for (int i = 0; i < graph.width(); ++i) {
368 /// for (int j = 0; j < graph.height(); ++j) {
369 /// val[graph(i, j)] = i + j;
374 /// The graph type is fully conform to the \ref concept::UUGraph
375 /// "Undirected UGraph" concept.
377 /// \author Balazs Dezso
378 /// \see GridUGraphBase
379 class GridUGraph : public ExtendedGridUGraphBase {
382 typedef ExtendedGridUGraphBase Parent;
384 /// \brief Map to get the indices of the nodes as xy<int>.
386 /// Map to get the indices of the nodes as xy<int>.
389 /// \brief The key type of the map
390 typedef GridUGraph::Node Key;
391 /// \brief The value type of the map
392 typedef xy<int> Value;
394 /// \brief Constructor
397 IndexMap(const GridUGraph& _graph) : graph(_graph) {}
399 /// \brief The subscript operator
401 /// The subscript operator.
402 Value operator[](Key key) const {
403 return xy<int>(graph.row(key), graph.col(key));
407 const GridUGraph& graph;
410 /// \brief Map to get the row of the nodes.
412 /// Map to get the row of the nodes.
415 /// \brief The key type of the map
416 typedef GridUGraph::Node Key;
417 /// \brief The value type of the map
420 /// \brief Constructor
423 RowMap(const GridUGraph& _graph) : graph(_graph) {}
425 /// \brief The subscript operator
427 /// The subscript operator.
428 Value operator[](Key key) const {
429 return graph.row(key);
433 const GridUGraph& graph;
436 /// \brief Map to get the column of the nodes.
438 /// Map to get the column of the nodes.
441 /// \brief The key type of the map
442 typedef GridUGraph::Node Key;
443 /// \brief The value type of the map
446 /// \brief Constructor
449 ColMap(const GridUGraph& _graph) : graph(_graph) {}
451 /// \brief The subscript operator
453 /// The subscript operator.
454 Value operator[](Key key) const {
455 return graph.col(key);
459 const GridUGraph& graph;
462 /// \brief Constructor
465 GridUGraph(int n, int m) { construct(n, m); }
467 /// \brief Resize the graph
469 void resize(int n, int m) {
470 Parent::getNotifier(Edge()).clear();
471 Parent::getNotifier(UEdge()).clear();
472 Parent::getNotifier(Node()).clear();
474 Parent::getNotifier(Node()).build();
475 Parent::getNotifier(UEdge()).build();
476 Parent::getNotifier(Edge()).build();
479 /// \brief Gives back the edge goes down from the node.
481 /// Gives back the edge goes down from the node. If there is not
482 /// outgoing edge then it gives back INVALID.
483 Edge down(Node n) const {
485 return ue != INVALID ? direct(ue, true) : INVALID;
488 /// \brief Gives back the edge goes up from the node.
490 /// Gives back the edge goes up from the node. If there is not
491 /// outgoing edge then it gives back INVALID.
492 Edge up(Node n) const {
494 return ue != INVALID ? direct(ue, false) : INVALID;
497 /// \brief Gives back the edge goes right from the node.
499 /// Gives back the edge goes right from the node. If there is not
500 /// outgoing edge then it gives back INVALID.
501 Edge right(Node n) const {
502 UEdge ue = _right(n);
503 return ue != INVALID ? direct(ue, true) : INVALID;
506 /// \brief Gives back the edge goes left from the node.
508 /// Gives back the edge goes left from the node. If there is not
509 /// outgoing edge then it gives back INVALID.
510 Edge left(Node n) const {
512 return ue != INVALID ? direct(ue, false) : INVALID;
517 /// \brief Index map of the grid graph
519 /// Just returns an IndexMap for the grid graph.
520 GridUGraph::IndexMap indexMap(const GridUGraph& graph) {
521 return GridUGraph::IndexMap(graph);
524 /// \brief Row map of the grid graph
526 /// Just returns a RowMap for the grid graph.
527 GridUGraph::RowMap rowMap(const GridUGraph& graph) {
528 return GridUGraph::RowMap(graph);
531 /// \brief Column map of the grid graph
533 /// Just returns a ColMap for the grid graph.
534 GridUGraph::ColMap colMap(const GridUGraph& graph) {
535 return GridUGraph::ColMap(graph);