COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/grid_ugraph.h @ 2159:dd3181a462d0

Last change on this file since 2159:dd3181a462d0 was 2151:38ec4a930c05, checked in by Alpar Juttner, 18 years ago

exceptionName() has been thrown away

File size: 14.1 KB
Line 
1/* -*- C++ -*-
2 *
3 * This file is a part of LEMON, a generic C++ optimization library
4 *
5 * Copyright (C) 2003-2006
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 *
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.
12 *
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
15 * purpose.
16 *
17 */
18
19#ifndef GRID_UGRAPH_H
20#define GRID_UGRAPH_H
21
22#include <iostream>
23#include <lemon/bits/invalid.h>
24#include <lemon/bits/utility.h>
25
26#include <lemon/bits/base_extender.h>
27#include <lemon/bits/graph_extender.h>
28
29#include <lemon/xy.h>
30
31///\ingroup graphs
32///\file
33///\brief GridUGraph class.
34
35namespace lemon {
36
37  /// \brief Base graph for GridUGraph.
38  ///
39  /// Base graph for grid graph. It describes some member functions
40  /// which can be used in the GridUGraph.
41  ///
42  /// \warning Always use the GridUGraph instead of this.
43  /// \see GridUGraph
44  class GridUGraphBase {
45
46  public:
47
48    typedef GridUGraphBase UGraph;
49
50    class Node;
51    class Edge;
52
53  public:
54
55    GridUGraphBase() {}
56
57  protected:
58
59    /// \brief Creates a grid graph with the given size.
60    ///
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;
66    }
67
68    /// \brief Gives back the edge goes down from the node.
69    ///
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) {
74        return Edge(n.id);
75      } else {
76        return INVALID;
77      }
78    }
79
80    /// \brief Gives back the edge comes from up into the node.
81    ///
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 {
85      if (n.id >= _width) {
86        return Edge(n.id - _width);
87      } else {
88        return INVALID;
89      }
90    }
91
92    /// \brief Gives back the edge goes right from the node.
93    ///
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);
99      } else {
100        return INVALID;
101      }
102    }
103
104    /// \brief Gives back the edge comes from left into the node.
105    ///
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;
111      } else {
112        return INVALID;
113      }
114    }
115
116  public:
117
118    class IndexError : public RuntimeError {
119    public:
120      virtual const char* what() const throw() {
121        return "lemon::GridUGraph::IndexError";
122      } 
123    };
124
125   
126    /// \brief The node on the given position.
127    ///
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);
133    }
134
135    /// \brief Gives back the row index of the node.
136    ///
137    /// Gives back the row index of the node.
138    int row(Node n) const {
139      return n.id / _width;
140    }
141   
142    /// \brief Gives back the coloumn index of the node.
143    ///
144    /// Gives back the coloumn index of the node.
145    int col(Node n) const {
146      return n.id % _width;   
147    }
148
149    /// \brief Gives back the width of the graph.
150    ///
151    /// Gives back the width of the graph.
152    int width() const {
153      return _width;
154    }
155
156    /// \brief Gives back the height of the graph.
157    ///
158    /// Gives back the height of the graph.
159    int height() const {
160      return _height;
161    }
162
163    typedef True NodeNumTag;
164    typedef True EdgeNumTag;
165
166    ///Number of nodes.
167    int nodeNum() const { return _nodeNum; }
168    ///Number of edges.
169    int edgeNum() const { return _edgeNum; }
170
171    /// Maximum node ID.
172   
173    /// Maximum node ID.
174    ///\sa id(Node)
175    int maxNodeId() const { return nodeNum() - 1; }
176    /// Maximum edge ID.
177   
178    /// Maximum edge ID.
179    ///\sa id(Edge)
180    int maxEdgeId() const { return edgeNum() - 1; }
181
182    /// \brief Gives back the source node of an edge.
183    ///   
184    /// Gives back the source node of an edge.
185    Node source(Edge e) const {
186      if (e.id < _edgeLimit) {
187        return e.id;
188      } else {
189        return (e.id - _edgeLimit) % (_width - 1) +
190          (e.id - _edgeLimit) / (_width - 1) * _width;
191      }
192    }
193
194    /// \brief Gives back the target node of an edge.
195    ///   
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;
200      } else {
201        return (e.id - _edgeLimit) % (_width - 1) +
202          (e.id - _edgeLimit) / (_width - 1) * _width + 1;
203      }
204    }
205
206    /// Node ID.
207   
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().
211    ///
212    /// The ID of the \ref INVALID node is -1.
213    ///\return The ID of the node \c v.
214
215    static int id(Node v) { return v.id; }
216    /// Edge ID.
217   
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().
221    ///
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; }
225
226    static Node nodeFromId(int id) { return Node(id);}
227   
228    static Edge edgeFromId(int id) { return Edge(id);}
229
230    typedef True FindEdgeTag;
231
232    /// Finds an edge between two nodes.
233   
234    /// Finds an edge from node \c u to node \c v.
235    ///
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);
246      }
247      return INVALID;
248    }
249   
250     
251    class Node {
252      friend class GridUGraphBase;
253
254    protected:
255      int id;
256      Node(int _id) { id = _id;}
257    public:
258      Node() {}
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;}
263    };
264   
265
266
267    class Edge {
268      friend class GridUGraphBase;
269     
270    protected:
271      int id;
272
273      Edge(int _id) : id(_id) {}
274
275    public:
276      Edge() { }
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;}
281    };
282
283    void first(Node& node) const {
284      node.id = nodeNum() - 1;
285    }
286
287    static void next(Node& node) {
288      --node.id;
289    }
290
291    void first(Edge& edge) const {
292      edge.id = edgeNum() - 1;
293    }
294
295    static void next(Edge& edge) {
296      --edge.id;
297    }
298
299    void firstOut(Edge& edge, const Node& node) const {
300      if (node.id < _nodeNum - _width) {
301        edge.id = node.id;
302      } else if (node.id % _width < _width - 1) {
303        edge.id = _edgeLimit + node.id % _width +
304          (node.id / _width) * (_width - 1);
305      } else {
306        edge.id = -1;
307      }
308    }
309
310    void nextOut(Edge& edge) const {
311      if (edge.id >= _edgeLimit) {
312        edge.id = -1;
313      } else if (edge.id % _width < _width - 1) {
314        edge.id = _edgeLimit + edge.id % _width +
315          (edge.id / _width) * (_width - 1);
316      } else {
317        edge.id = -1;
318      }
319    }
320
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;
327      } else {
328        edge.id = -1;
329      }
330    }
331   
332    void nextIn(Edge& edge) const {
333      if (edge.id >= _edgeLimit) {
334        edge.id = -1;
335      } else if (edge.id % _width > 0) {
336        edge.id = _edgeLimit + edge.id % _width +
337          (edge.id / _width + 1) * (_width - 1) - 1;
338      } else {
339        edge.id = -1;
340      }
341    }
342
343  private:
344    int _width, _height;
345    int _nodeNum, _edgeNum;
346    int _edgeLimit;
347  };
348
349
350  typedef UGraphExtender<UndirGraphExtender<GridUGraphBase> >
351  ExtendedGridUGraphBase;
352
353  /// \ingroup graphs
354  ///
355  /// \brief Grid graph class
356  ///
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.
362  ///
363  /// The graph can be indiced in the following way:
364  ///\code
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;
370  ///   }
371  /// }
372  ///\endcode
373  ///
374  /// The graph type is fully conform to the \ref concept::UGraph
375  /// "Undirected Graph" concept.
376  ///
377  /// \author Balazs Dezso
378  /// \see GridUGraphBase
379  class GridUGraph : public ExtendedGridUGraphBase {
380  public:
381
382    typedef ExtendedGridUGraphBase Parent;
383
384    /// \brief Map to get the indices of the nodes as xy<int>.
385    ///
386    /// Map to get the indices of the nodes as xy<int>.
387    class IndexMap {
388    public:
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;
393
394      /// \brief Constructor
395      ///
396      /// Constructor
397      IndexMap(const GridUGraph& _graph) : graph(_graph) {}
398
399      /// \brief The subscript operator
400      ///
401      /// The subscript operator.
402      Value operator[](Key key) const {
403        return xy<int>(graph.row(key), graph.col(key));
404      }
405
406    private:
407      const GridUGraph& graph;
408    };
409
410    /// \brief Map to get the row of the nodes.
411    ///
412    /// Map to get the row of the nodes.
413    class RowMap {
414    public:
415      /// \brief The key type of the map
416      typedef GridUGraph::Node Key;
417      /// \brief The value type of the map
418      typedef int Value;
419
420      /// \brief Constructor
421      ///
422      /// Constructor
423      RowMap(const GridUGraph& _graph) : graph(_graph) {}
424
425      /// \brief The subscript operator
426      ///
427      /// The subscript operator.
428      Value operator[](Key key) const {
429        return graph.row(key);
430      }
431
432    private:
433      const GridUGraph& graph;
434    };
435
436    /// \brief Map to get the column of the nodes.
437    ///
438    /// Map to get the column of the nodes.
439    class ColMap {
440    public:
441      /// \brief The key type of the map
442      typedef GridUGraph::Node Key;
443      /// \brief The value type of the map
444      typedef int Value;
445
446      /// \brief Constructor
447      ///
448      /// Constructor
449      ColMap(const GridUGraph& _graph) : graph(_graph) {}
450
451      /// \brief The subscript operator
452      ///
453      /// The subscript operator.
454      Value operator[](Key key) const {
455        return graph.col(key);
456      }
457
458    private:
459      const GridUGraph& graph;
460    };
461
462    /// \brief Constructor
463    ///
464    ///
465    GridUGraph(int n, int m) { construct(n, m); }
466
467    /// \brief Resize the graph
468    ///
469    void resize(int n, int m) {
470      Parent::getNotifier(Edge()).clear();
471      Parent::getNotifier(UEdge()).clear();
472      Parent::getNotifier(Node()).clear();
473      construct(n, m);
474      Parent::getNotifier(Node()).build();
475      Parent::getNotifier(UEdge()).build();
476      Parent::getNotifier(Edge()).build();
477    }
478   
479    /// \brief Gives back the edge goes down from the node.
480    ///
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 {
484      UEdge ue = _down(n);
485      return ue != INVALID ? direct(ue, true) : INVALID;
486    }
487   
488    /// \brief Gives back the edge goes up from the node.
489    ///
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 {
493      UEdge ue = _up(n);
494      return ue != INVALID ? direct(ue, false) : INVALID;
495    }
496
497    /// \brief Gives back the edge goes right from the node.
498    ///
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;
504    }
505
506    /// \brief Gives back the edge goes left from the node.
507    ///
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 {
511      UEdge ue = _left(n);
512      return ue != INVALID ? direct(ue, false) : INVALID;
513    }
514   
515  };
516
517  /// \brief Index map of the grid graph
518  ///
519  /// Just returns an IndexMap for the grid graph.
520  GridUGraph::IndexMap indexMap(const GridUGraph& graph) {
521    return GridUGraph::IndexMap(graph);
522  }
523
524  /// \brief Row map of the grid graph
525  ///
526  /// Just returns a RowMap for the grid graph.
527  GridUGraph::RowMap rowMap(const GridUGraph& graph) {
528    return GridUGraph::RowMap(graph);
529  }
530
531  /// \brief Column map of the grid graph
532  ///
533  /// Just returns a ColMap for the grid graph.
534  GridUGraph::ColMap colMap(const GridUGraph& graph) {
535    return GridUGraph::ColMap(graph);
536  }
537}
538#endif
Note: See TracBrowser for help on using the repository browser.