Bugfix: DFS crashed if the source did not have an outgoing edge.
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/default_map.h>
28 #include <lemon/bits/undir_graph_extender.h>
36 typedef GridGraphBase Graph;
47 /// \brief Creates a grid graph with the given size.
49 /// Creates a grid graph with the given size.
50 void construct(int height, int width) {
51 _height = height; _width = width;
52 _nodeNum = height * width; _edgeNum = 2 * _nodeNum - width - height;
53 _edgeLimit = _nodeNum - width;
58 /// \brief The node on the given position.
60 /// Gives back the node on the given position.
61 Node operator()(int i, int j) const {
62 return Node(i * _width + j);
65 /// \brief Gives back the row index of the node.
67 /// Gives back the row index of the node.
68 int row(Node n) const {
72 /// \brief Gives back the coloumn index of the node.
74 /// Gives back the coloumn index of the node.
75 int col(Node node) const {
79 /// \brief Gives back the width of the graph.
81 /// Gives back the width of the graph.
86 /// \brief Gives back the height of the graph.
88 /// Gives back the height of the graph.
93 typedef True NodeNumTag;
94 typedef True EdgeNumTag;
97 int nodeNum() const { return _nodeNum; }
99 int edgeNum() const { return _edgeNum; }
105 int maxId(Node = INVALID) const { return nodeNum() - 1; }
110 int maxId(Edge = INVALID) const { return edgeNum() - 1; }
112 /// \brief Gives back the source node of an edge.
114 /// Gives back the source node of an edge.
115 Node source(Edge e) const {
116 if (e.id < _edgeLimit) {
119 return (e.id - _edgeLimit) % (_width - 1) +
120 (e.id - _edgeLimit) / (_width - 1) * _width;
124 /// \brief Gives back the target node of an edge.
126 /// Gives back the target node of an edge.
127 Node target(Edge e) const {
128 if (e.id < _edgeLimit) {
129 return e.id + _width;
131 return (e.id - _edgeLimit) % (_width - 1) +
132 (e.id - _edgeLimit) / (_width - 1) * _width + 1;
138 /// The ID of a valid Node is a nonnegative integer not greater than
139 /// \ref maxNodeId(). The range of the ID's is not surely continuous
140 /// and the greatest node ID can be actually less then \ref maxNodeId().
142 /// The ID of the \ref INVALID node is -1.
143 ///\return The ID of the node \c v.
145 static int id(Node v) { return v.id; }
148 /// The ID of a valid Edge is a nonnegative integer not greater than
149 /// \ref maxEdgeId(). The range of the ID's is not surely continuous
150 /// and the greatest edge ID can be actually less then \ref maxEdgeId().
152 /// The ID of the \ref INVALID edge is -1.
153 ///\return The ID of the edge \c e.
154 static int id(Edge e) { return e.id; }
156 static Node fromId(int id, Node) { return Node(id);}
158 static Edge fromId(int id, Edge) { return Edge(id);}
160 typedef True FindEdgeTag;
162 /// Finds an edge between two nodes.
164 /// Finds an edge from node \c u to node \c v.
166 /// If \c prev is \ref INVALID (this is the default value), then
167 /// It finds the first edge from \c u to \c v. Otherwise it looks for
168 /// the next edge from \c u to \c v after \c prev.
169 /// \return The found edge or INVALID if there is no such an edge.
170 Edge findEdge(Node u, Node v, Edge prev = INVALID) {
171 if (prev != INVALID) return INVALID;
172 if (v.id - u.id == _width) return Edge(u.id);
173 if (v.id - u.id == 1 && u.id % _width < _width - 1) {
174 return Edge(u.id / _width * (_width - 1) +
175 u.id % _width + _edgeLimit);
182 friend class GridGraphBase;
186 Node(int _id) { id = _id;}
189 Node (Invalid) { id = -1; }
190 bool operator==(const Node node) const {return id == node.id;}
191 bool operator!=(const Node node) const {return id != node.id;}
192 bool operator<(const Node node) const {return id < node.id;}
198 friend class GridGraphBase;
203 Edge(int _id) : id(_id) {}
207 Edge (Invalid) { id = -1; }
208 bool operator==(const Edge edge) const {return id == edge.id;}
209 bool operator!=(const Edge edge) const {return id != edge.id;}
210 bool operator<(const Edge edge) const {return id < edge.id;}
213 void first(Node& node) const {
214 node.id = nodeNum() - 1;
217 static void next(Node& node) {
221 void first(Edge& edge) const {
222 edge.id = edgeNum() - 1;
225 static void next(Edge& edge) {
229 void firstOut(Edge& edge, const Node& node) const {
230 if (node.id < _nodeNum - _width) {
232 } else if (node.id % _width < _width - 1) {
233 edge.id = _edgeLimit + node.id % _width +
234 (node.id / _width) * (_width - 1);
240 void nextOut(Edge& edge) const {
241 if (edge.id >= _edgeLimit) {
243 } else if (edge.id % _width < _width - 1) {
244 edge.id = _edgeLimit + edge.id % _width +
245 (edge.id / _width) * (_width - 1);
251 void firstIn(Edge& edge, const Node& node) const {
252 if (node.id >= _width) {
253 edge.id = node.id - _width;
254 } else if (node.id % _width > 0) {
255 edge.id = _edgeLimit + node.id % _width +
256 (node.id / _width) * (_width - 1) - 1;
262 void nextIn(Edge& edge) const {
263 if (edge.id >= _edgeLimit) {
265 } else if (edge.id % _width > 0) {
266 edge.id = _edgeLimit + edge.id % _width +
267 (edge.id / _width + 1) * (_width - 1) - 1;
275 int _nodeNum, _edgeNum;
280 typedef UndirGraphExtender<GridGraphBase>
282 typedef AlterableUndirGraphExtender<UndirGridGraphBase>
283 AlterableGridGraphBase;
284 typedef IterableUndirGraphExtender<AlterableGridGraphBase>
285 IterableGridGraphBase;
286 typedef MappableUndirGraphExtender<IterableGridGraphBase>
287 MappableGridGraphBase;
291 /// \brief Grid graph class
293 /// This class implements a special graph type. The nodes of the
294 /// graph can be indiced by two integer \c (i,j) value where \c i
295 /// is in the \c [0,height) range and j is in the [0, width) range.
296 /// Two nodes are connected in the graph if the indices differ only
297 /// on one position and only one is the difference.
299 /// The graph can be indiced in the following way:
301 /// GridGraph graph(h, w);
302 /// GridGraph::NodeMap<int> val(graph);
303 /// for (int i = 0; i < graph.height(); ++i) {
304 /// for (int j = 0; j < graph.width(); ++j) {
305 /// val[graph(i, j)] = i + j;
310 /// The graph type is fully conform to the \ref concept::UndirGraph
311 /// "Undirected Graph" concept.
313 /// \author Balazs Dezso
314 class GridGraph : public MappableGridGraphBase {
317 GridGraph(int m, int n) { construct(m, n); }