COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/grid_graph.h @ 1725:22752dd6c693

Last change on this file since 1725:22752dd6c693 was 1703:eb90e3d6bddc, checked in by Balazs Dezso, 18 years ago

Proper sized map type

File size: 13.6 KB
Line 
1/* -*- C++ -*-
2 * lemon/grid_graph.h - Part of LEMON, a generic C++ optimization library
3 *
4 * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
5 * (Egervary Research Group on Combinatorial Optimization, EGRES).
6 *
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.
10 *
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
13 * purpose.
14 *
15 */
16
17#ifndef GRID_GRAPH_H
18#define GRID_GRAPH_H
19
20#include <iostream>
21#include <lemon/invalid.h>
22#include <lemon/utility.h>
23
24#include <lemon/bits/iterable_graph_extender.h>
25#include <lemon/bits/alteration_notifier.h>
26#include <lemon/bits/static_map.h>
27
28#include <lemon/bits/undir_graph_extender.h>
29
30#include <lemon/xy.h>
31
32///\ingroup graphs
33///\file
34///\brief GridGraph class.
35
36namespace lemon {
37
38  /// \brief Base graph for GridGraph.
39  ///
40  /// Base graph for grid graph. It describes some member functions
41  /// which can be used in the GridGraph.
42  ///
43  /// \warning Always use the GridGraph instead of this.
44  /// \see GridGraph
45  class GridGraphBase {
46
47  public:
48
49    typedef GridGraphBase Graph;
50
51    class Node;
52    class Edge;
53
54  public:
55
56    GridGraphBase() {}
57
58  protected:
59
60    /// \brief Creates a grid graph with the given size.
61    ///
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;
67    }
68
69    /// \brief Gives back the edge goes down from the node.
70    ///
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) {
75        return Edge(n.id);
76      } else {
77        return INVALID;
78      }
79    }
80
81    /// \brief Gives back the edge comes from up into the node.
82    ///
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 {
86      if (n.id >= _width) {
87        return Edge(n.id - _width);
88      } else {
89        return INVALID;
90      }
91    }
92
93    /// \brief Gives back the edge goes right from the node.
94    ///
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);
100      } else {
101        return INVALID;
102      }
103    }
104
105    /// \brief Gives back the edge comes from left into the node.
106    ///
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;
112      } else {
113        return INVALID;
114      }
115    }
116
117
118  public:
119   
120    /// \brief The node on the given position.
121    ///
122    /// Gives back the node on the given position.
123    Node operator()(int i, int j) const {
124      return Node(i + j * _width);
125    }
126
127    /// \brief Gives back the row index of the node.
128    ///
129    /// Gives back the row index of the node.
130    int row(Node n) const {
131      return n.id / _width;
132    }
133   
134    /// \brief Gives back the coloumn index of the node.
135    ///
136    /// Gives back the coloumn index of the node.
137    int col(Node n) const {
138      return n.id % _width;   
139    }
140
141    /// \brief Gives back the width of the graph.
142    ///
143    /// Gives back the width of the graph.
144    int width() const {
145      return _width;
146    }
147
148    /// \brief Gives back the height of the graph.
149    ///
150    /// Gives back the height of the graph.
151    int height() const {
152      return _height;
153    }
154
155    typedef True NodeNumTag;
156    typedef True EdgeNumTag;
157
158    ///Number of nodes.
159    int nodeNum() const { return _nodeNum; }
160    ///Number of edges.
161    int edgeNum() const { return _edgeNum; }
162
163    /// Maximum node ID.
164   
165    /// Maximum node ID.
166    ///\sa id(Node)
167    int maxId(Node = INVALID) const { return nodeNum() - 1; }
168    /// Maximum edge ID.
169   
170    /// Maximum edge ID.
171    ///\sa id(Edge)
172    int maxId(Edge = INVALID) const { return edgeNum() - 1; }
173
174    /// \brief Gives back the source node of an edge.
175    ///   
176    /// Gives back the source node of an edge.
177    Node source(Edge e) const {
178      if (e.id < _edgeLimit) {
179        return e.id;
180      } else {
181        return (e.id - _edgeLimit) % (_width - 1) +
182          (e.id - _edgeLimit) / (_width - 1) * _width;
183      }
184    }
185
186    /// \brief Gives back the target node of an edge.
187    ///   
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;
192      } else {
193        return (e.id - _edgeLimit) % (_width - 1) +
194          (e.id - _edgeLimit) / (_width - 1) * _width + 1;
195      }
196    }
197
198    /// Node ID.
199   
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().
203    ///
204    /// The ID of the \ref INVALID node is -1.
205    ///\return The ID of the node \c v.
206
207    static int id(Node v) { return v.id; }
208    /// Edge ID.
209   
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().
213    ///
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; }
217
218    static Node fromId(int id, Node) { return Node(id);}
219   
220    static Edge fromId(int id, Edge) { return Edge(id);}
221
222    typedef True FindEdgeTag;
223
224    /// Finds an edge between two nodes.
225   
226    /// Finds an edge from node \c u to node \c v.
227    ///
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);
238      }
239      return INVALID;
240    }
241   
242     
243    class Node {
244      friend class GridGraphBase;
245
246    protected:
247      int id;
248      Node(int _id) { id = _id;}
249    public:
250      Node() {}
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;}
255    };
256   
257
258
259    class Edge {
260      friend class GridGraphBase;
261     
262    protected:
263      int id;
264
265      Edge(int _id) : id(_id) {}
266
267    public:
268      Edge() { }
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;}
273    };
274
275    void first(Node& node) const {
276      node.id = nodeNum() - 1;
277    }
278
279    static void next(Node& node) {
280      --node.id;
281    }
282
283    void first(Edge& edge) const {
284      edge.id = edgeNum() - 1;
285    }
286
287    static void next(Edge& edge) {
288      --edge.id;
289    }
290
291    void firstOut(Edge& edge, const Node& node) const {
292      if (node.id < _nodeNum - _width) {
293        edge.id = node.id;
294      } else if (node.id % _width < _width - 1) {
295        edge.id = _edgeLimit + node.id % _width +
296          (node.id / _width) * (_width - 1);
297      } else {
298        edge.id = -1;
299      }
300    }
301
302    void nextOut(Edge& edge) const {
303      if (edge.id >= _edgeLimit) {
304        edge.id = -1;
305      } else if (edge.id % _width < _width - 1) {
306        edge.id = _edgeLimit + edge.id % _width +
307          (edge.id / _width) * (_width - 1);
308      } else {
309        edge.id = -1;
310      }
311    }
312
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;
319      } else {
320        edge.id = -1;
321      }
322    }
323   
324    void nextIn(Edge& edge) const {
325      if (edge.id >= _edgeLimit) {
326        edge.id = -1;
327      } else if (edge.id % _width > 0) {
328        edge.id = _edgeLimit + edge.id % _width +
329          (edge.id / _width + 1) * (_width - 1) - 1;
330      } else {
331        edge.id = -1;
332      }
333    }
334
335  private:
336    int _width, _height;
337    int _nodeNum, _edgeNum;
338    int _edgeLimit;
339  };
340
341
342  typedef StaticMappableUndirGraphExtender<
343    IterableUndirGraphExtender<
344    AlterableUndirGraphExtender<
345    UndirGraphExtender<GridGraphBase> > > > ExtendedGridGraphBase;
346
347  /// \ingroup graphs
348  ///
349  /// \brief Grid graph class
350  ///
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.
356  ///
357  /// The graph can be indiced in the following way:
358  /// \code
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;
364  ///   }
365  /// }
366  /// \endcode
367  ///
368  /// The graph type is fully conform to the \ref concept::UndirGraph
369  /// "Undirected Graph" concept.
370  ///
371  /// \author Balazs Dezso
372  /// \see GridGraphBase
373  class GridGraph : public ExtendedGridGraphBase {
374  public:
375
376    /// \brief Map to get the indices of the nodes as xy<int>.
377    ///
378    /// Map to get the indices of the nodes as xy<int>.
379    class IndexMap {
380    public:
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;
386
387      /// \brief Constructor
388      ///
389      /// Constructor
390      IndexMap(const GridGraph& _graph) : graph(_graph) {}
391
392      /// \brief The subscript operator
393      ///
394      /// The subscript operator.
395      Value operator[](Key key) const {
396        return xy<int>(graph.row(key), graph.col(key));
397      }
398
399    private:
400      const GridGraph& graph;
401    };
402
403    /// \brief Map to get the row of the nodes.
404    ///
405    /// Map to get the row of the nodes.
406    class RowMap {
407    public:
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
412      typedef int Value;
413
414      /// \brief Constructor
415      ///
416      /// Constructor
417      RowMap(const GridGraph& _graph) : graph(_graph) {}
418
419      /// \brief The subscript operator
420      ///
421      /// The subscript operator.
422      Value operator[](Key key) const {
423        return graph.row(key);
424      }
425
426    private:
427      const GridGraph& graph;
428    };
429
430    /// \brief Map to get the column of the nodes.
431    ///
432    /// Map to get the column of the nodes.
433    class ColMap {
434    public:
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
439      typedef int Value;
440
441      /// \brief Constructor
442      ///
443      /// Constructor
444      ColMap(const GridGraph& _graph) : graph(_graph) {}
445
446      /// \brief The subscript operator
447      ///
448      /// The subscript operator.
449      Value operator[](Key key) const {
450        return graph.col(key);
451      }
452
453    private:
454      const GridGraph& graph;
455    };
456
457    GridGraph(int n, int m) { construct(n, m); }
458   
459    /// \brief Gives back the edge goes down from the node.
460    ///
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;
466    }
467   
468    /// \brief Gives back the edge goes up from the node.
469    ///
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;
475    }
476
477    /// \brief Gives back the edge goes right from the node.
478    ///
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;
484    }
485
486    /// \brief Gives back the edge goes left from the node.
487    ///
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;
493    }
494   
495  };
496
497  /// \brief Index map of the grid graph
498  ///
499  /// Just returns an IndexMap for the grid graph.
500  GridGraph::IndexMap indexMap(const GridGraph& graph) {
501    return GridGraph::IndexMap(graph);
502  }
503
504  /// \brief Row map of the grid graph
505  ///
506  /// Just returns an RowMap for the grid graph.
507  GridGraph::RowMap rowMap(const GridGraph& graph) {
508    return GridGraph::RowMap(graph);
509  }
510
511  /// \brief Coloumn map of the grid graph
512  ///
513  /// Just returns an ColMap for the grid graph.
514  GridGraph::ColMap colMap(const GridGraph& graph) {
515    return GridGraph::ColMap(graph);
516  }
517}
518#endif
Note: See TracBrowser for help on using the repository browser.