lemon/grid_ugraph.h
author ladanyi
Tue, 01 Aug 2006 10:26:15 +0000
changeset 2166 c67e8b928a95
parent 2116 b6a68c15a6a3
child 2207 75a29ac69c19
permissions -rw-r--r--
More "doxygenish" syntax.
deba@1979
     1
/* -*- C++ -*-
deba@1979
     2
 *
deba@1979
     3
 * This file is a part of LEMON, a generic C++ optimization library
deba@1979
     4
 *
deba@1979
     5
 * Copyright (C) 2003-2006
deba@1979
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
deba@1979
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
deba@1979
     8
 *
deba@1979
     9
 * Permission to use, modify and distribute this software is granted
deba@1979
    10
 * provided that this copyright notice appears in all copies. For
deba@1979
    11
 * precise terms see the accompanying LICENSE file.
deba@1979
    12
 *
deba@1979
    13
 * This software is provided "AS IS" with no warranty of any kind,
deba@1979
    14
 * express or implied, and with no claim as to its suitability for any
deba@1979
    15
 * purpose.
deba@1979
    16
 *
deba@1979
    17
 */
deba@1979
    18
deba@1979
    19
#ifndef GRID_UGRAPH_H
deba@1979
    20
#define GRID_UGRAPH_H
deba@1979
    21
deba@1979
    22
#include <iostream>
deba@1993
    23
#include <lemon/bits/invalid.h>
deba@1993
    24
#include <lemon/bits/utility.h>
deba@1979
    25
deba@1999
    26
#include <lemon/bits/base_extender.h>
deba@2116
    27
#include <lemon/bits/graph_extender.h>
deba@1979
    28
deba@1979
    29
#include <lemon/xy.h>
deba@1979
    30
deba@1979
    31
///\ingroup graphs
deba@1979
    32
///\file
deba@1979
    33
///\brief GridUGraph class.
deba@1979
    34
deba@1979
    35
namespace lemon {
deba@1979
    36
deba@1979
    37
  /// \brief Base graph for GridUGraph.
deba@1979
    38
  ///
deba@1979
    39
  /// Base graph for grid graph. It describes some member functions
deba@1979
    40
  /// which can be used in the GridUGraph.
deba@1979
    41
  ///
deba@1979
    42
  /// \warning Always use the GridUGraph instead of this.
deba@1979
    43
  /// \see GridUGraph
deba@1979
    44
  class GridUGraphBase {
deba@1979
    45
deba@1979
    46
  public:
deba@1979
    47
deba@1979
    48
    typedef GridUGraphBase UGraph;
deba@1979
    49
deba@1979
    50
    class Node;
deba@1979
    51
    class Edge;
deba@1979
    52
deba@1979
    53
  public:
deba@1979
    54
deba@1979
    55
    GridUGraphBase() {}
deba@1979
    56
deba@1979
    57
  protected:
deba@1979
    58
deba@1979
    59
    /// \brief Creates a grid graph with the given size.
deba@1979
    60
    ///
deba@1979
    61
    /// Creates a grid graph with the given size.
deba@1979
    62
    void construct(int width, int height) {
deba@1979
    63
      _height = height; _width = width;
deba@1979
    64
      _nodeNum = height * width; _edgeNum = 2 * _nodeNum - width - height;
deba@1979
    65
      _edgeLimit = _nodeNum - width;
deba@1979
    66
    }
deba@1979
    67
deba@1979
    68
    /// \brief Gives back the edge goes down from the node.
deba@1979
    69
    ///
deba@1979
    70
    /// Gives back the edge goes down from the node. If there is not
deba@1979
    71
    /// outgoing edge then it gives back INVALID.
deba@1979
    72
    Edge _down(Node n) const {
deba@1979
    73
      if (n.id < _nodeNum - _width) {
deba@1979
    74
	return Edge(n.id);
deba@1979
    75
      } else {
deba@1979
    76
	return INVALID;
deba@1979
    77
      }
deba@1979
    78
    }
deba@1979
    79
deba@1979
    80
    /// \brief Gives back the edge comes from up into the node.
deba@1979
    81
    ///
deba@1979
    82
    /// Gives back the edge comes from up into the node. If there is not
deba@1979
    83
    /// incoming edge then it gives back INVALID.
deba@1979
    84
    Edge _up(Node n) const {
deba@1979
    85
      if (n.id >= _width) {
deba@1979
    86
	return Edge(n.id - _width);
deba@1979
    87
      } else {
deba@1979
    88
	return INVALID;
deba@1979
    89
      }
deba@1979
    90
    }
deba@1979
    91
deba@1979
    92
    /// \brief Gives back the edge goes right from the node.
deba@1979
    93
    ///
deba@1979
    94
    /// Gives back the edge goes right from the node. If there is not
deba@1979
    95
    /// outgoing edge then it gives back INVALID.
deba@1979
    96
    Edge _right(Node n) const {
deba@1979
    97
      if (n.id % _width < _width - 1) {
deba@1979
    98
	return _edgeLimit + n.id % _width + (n.id / _width) * (_width - 1);
deba@1979
    99
      } else {
deba@1979
   100
	return INVALID;
deba@1979
   101
      }
deba@1979
   102
    }
deba@1979
   103
deba@1979
   104
    /// \brief Gives back the edge comes from left into the node.
deba@1979
   105
    ///
deba@1979
   106
    /// Gives back the edge comes left up into the node. If there is not
deba@1979
   107
    /// incoming edge then it gives back INVALID.
deba@1979
   108
    Edge _left(Node n) const {
deba@1979
   109
      if (n.id % _width > 0) {
deba@1979
   110
	return _edgeLimit + n.id % _width + (n.id / _width) * (_width - 1) - 1;
deba@1979
   111
      } else {
deba@1979
   112
	return INVALID;
deba@1979
   113
      }
deba@1979
   114
    }
deba@1979
   115
deba@1979
   116
  public:
deba@1979
   117
deba@1979
   118
    class IndexError : public RuntimeError {
deba@1979
   119
    public:
alpar@2151
   120
      virtual const char* what() const throw() {
deba@1979
   121
        return "lemon::GridUGraph::IndexError";
deba@1979
   122
      }  
deba@1979
   123
    };
deba@1979
   124
deba@1979
   125
    
deba@1979
   126
    /// \brief The node on the given position.
deba@1979
   127
    /// 
deba@1979
   128
    /// Gives back the node on the given position.
deba@1979
   129
    Node operator()(int i, int j) const {
deba@1986
   130
      LEMON_ASSERT(0 <= i && i < width() && 0 <= j  && 
deba@1986
   131
                   j < height(), IndexError());
deba@1979
   132
      return Node(i + j * _width);
deba@1979
   133
    }
deba@1979
   134
deba@1979
   135
    /// \brief Gives back the row index of the node.
deba@1979
   136
    ///
deba@1979
   137
    /// Gives back the row index of the node.
deba@1979
   138
    int row(Node n) const {
deba@1979
   139
      return n.id / _width;
deba@1979
   140
    }
deba@1979
   141
    
deba@1979
   142
    /// \brief Gives back the coloumn index of the node.
deba@1979
   143
    ///
deba@1979
   144
    /// Gives back the coloumn index of the node.
deba@1979
   145
    int col(Node n) const {
deba@1979
   146
      return n.id % _width;    
deba@1979
   147
    }
deba@1979
   148
deba@1979
   149
    /// \brief Gives back the width of the graph.
deba@1979
   150
    ///
deba@1979
   151
    /// Gives back the width of the graph.
deba@1979
   152
    int width() const {
deba@1979
   153
      return _width;
deba@1979
   154
    }
deba@1979
   155
deba@1979
   156
    /// \brief Gives back the height of the graph.
deba@1979
   157
    ///
deba@1979
   158
    /// Gives back the height of the graph.
deba@1979
   159
    int height() const {
deba@1979
   160
      return _height;
deba@1979
   161
    }
deba@1979
   162
deba@1979
   163
    typedef True NodeNumTag;
deba@1979
   164
    typedef True EdgeNumTag;
deba@1979
   165
deba@1979
   166
    ///Number of nodes.
deba@1979
   167
    int nodeNum() const { return _nodeNum; }
deba@1979
   168
    ///Number of edges.
deba@1979
   169
    int edgeNum() const { return _edgeNum; }
deba@1979
   170
deba@1979
   171
    /// Maximum node ID.
deba@1979
   172
    
deba@1979
   173
    /// Maximum node ID.
deba@1979
   174
    ///\sa id(Node)
deba@1979
   175
    int maxNodeId() const { return nodeNum() - 1; }
deba@1979
   176
    /// Maximum edge ID.
deba@1979
   177
    
deba@1979
   178
    /// Maximum edge ID.
deba@1979
   179
    ///\sa id(Edge)
deba@1979
   180
    int maxEdgeId() const { return edgeNum() - 1; }
deba@1979
   181
deba@1979
   182
    /// \brief Gives back the source node of an edge.
deba@1979
   183
    ///    
deba@1979
   184
    /// Gives back the source node of an edge.
deba@1979
   185
    Node source(Edge e) const {
deba@1979
   186
      if (e.id < _edgeLimit) {
deba@1979
   187
	return e.id;
deba@1979
   188
      } else {
deba@1979
   189
	return (e.id - _edgeLimit) % (_width - 1) +
deba@1979
   190
	  (e.id - _edgeLimit) / (_width - 1) * _width;
deba@1979
   191
      }
deba@1979
   192
    }
deba@1979
   193
deba@1979
   194
    /// \brief Gives back the target node of an edge.
deba@1979
   195
    ///    
deba@1979
   196
    /// Gives back the target node of an edge.
deba@1979
   197
    Node target(Edge e) const {
deba@1979
   198
      if (e.id < _edgeLimit) {
deba@1979
   199
	return e.id + _width;
deba@1979
   200
      } else {
deba@1979
   201
	return (e.id - _edgeLimit) % (_width - 1) +
deba@1979
   202
	  (e.id - _edgeLimit) / (_width - 1) * _width + 1;
deba@1979
   203
      }
deba@1979
   204
    }
deba@1979
   205
deba@1979
   206
    /// Node ID.
deba@1979
   207
    
deba@1979
   208
    /// The ID of a valid Node is a nonnegative integer not greater than
deba@1979
   209
    /// \ref maxNodeId(). The range of the ID's is not surely continuous
deba@1979
   210
    /// and the greatest node ID can be actually less then \ref maxNodeId().
deba@1979
   211
    ///
deba@1979
   212
    /// The ID of the \ref INVALID node is -1.
deba@1979
   213
    ///\return The ID of the node \c v. 
deba@1979
   214
deba@1979
   215
    static int id(Node v) { return v.id; }
deba@1979
   216
    /// Edge ID.
deba@1979
   217
    
deba@1979
   218
    /// The ID of a valid Edge is a nonnegative integer not greater than
deba@1979
   219
    /// \ref maxEdgeId(). The range of the ID's is not surely continuous
deba@1979
   220
    /// and the greatest edge ID can be actually less then \ref maxEdgeId().
deba@1979
   221
    ///
deba@1979
   222
    /// The ID of the \ref INVALID edge is -1.
deba@1979
   223
    ///\return The ID of the edge \c e. 
deba@1979
   224
    static int id(Edge e) { return e.id; }
deba@1979
   225
deba@1979
   226
    static Node nodeFromId(int id) { return Node(id);}
deba@1979
   227
    
deba@1979
   228
    static Edge edgeFromId(int id) { return Edge(id);}
deba@1979
   229
deba@1979
   230
    typedef True FindEdgeTag;
deba@1979
   231
deba@1979
   232
    /// Finds an edge between two nodes.
deba@1979
   233
    
deba@1979
   234
    /// Finds an edge from node \c u to node \c v.
deba@1979
   235
    ///
deba@1979
   236
    /// If \c prev is \ref INVALID (this is the default value), then
deba@1979
   237
    /// It finds the first edge from \c u to \c v. Otherwise it looks for
deba@1979
   238
    /// the next edge from \c u to \c v after \c prev.
deba@1979
   239
    /// \return The found edge or INVALID if there is no such an edge.
deba@1979
   240
    Edge findEdge(Node u, Node v, Edge prev = INVALID) const {
deba@1979
   241
      if (prev != INVALID) return INVALID;
deba@1979
   242
      if (v.id - u.id == _width) return Edge(u.id);
deba@1979
   243
      if (v.id - u.id == 1 && u.id % _width < _width - 1) {
deba@1979
   244
	return Edge(u.id / _width * (_width - 1) +
deba@1979
   245
		    u.id % _width + _edgeLimit);
deba@1979
   246
      }
deba@1979
   247
      return INVALID;
deba@1979
   248
    }
deba@1979
   249
    
deba@1979
   250
      
deba@1979
   251
    class Node {
deba@1979
   252
      friend class GridUGraphBase;
deba@1979
   253
deba@1979
   254
    protected:
deba@1979
   255
      int id;
deba@1979
   256
      Node(int _id) { id = _id;}
deba@1979
   257
    public:
deba@1979
   258
      Node() {}
deba@1979
   259
      Node (Invalid) { id = -1; }
deba@1979
   260
      bool operator==(const Node node) const {return id == node.id;}
deba@1979
   261
      bool operator!=(const Node node) const {return id != node.id;}
deba@1979
   262
      bool operator<(const Node node) const {return id < node.id;}
deba@1979
   263
    };
deba@1979
   264
    
deba@1979
   265
deba@1979
   266
deba@1979
   267
    class Edge {
deba@1979
   268
      friend class GridUGraphBase;
deba@1979
   269
      
deba@1979
   270
    protected:
deba@1979
   271
      int id; 
deba@1979
   272
deba@1979
   273
      Edge(int _id) : id(_id) {}
deba@1979
   274
deba@1979
   275
    public:
deba@1979
   276
      Edge() { }
deba@1979
   277
      Edge (Invalid) { id = -1; }
deba@1979
   278
      bool operator==(const Edge edge) const {return id == edge.id;}
deba@1979
   279
      bool operator!=(const Edge edge) const {return id != edge.id;}
deba@1979
   280
      bool operator<(const Edge edge) const {return id < edge.id;}
deba@1979
   281
    };
deba@1979
   282
deba@1979
   283
    void first(Node& node) const {
deba@1979
   284
      node.id = nodeNum() - 1;
deba@1979
   285
    }
deba@1979
   286
deba@1979
   287
    static void next(Node& node) {
deba@1979
   288
      --node.id;
deba@1979
   289
    }
deba@1979
   290
deba@1979
   291
    void first(Edge& edge) const {
deba@1979
   292
      edge.id = edgeNum() - 1;
deba@1979
   293
    }
deba@1979
   294
deba@1979
   295
    static void next(Edge& edge) {
deba@1979
   296
      --edge.id;
deba@1979
   297
    }
deba@1979
   298
deba@1979
   299
    void firstOut(Edge& edge, const Node& node) const {
deba@1979
   300
      if (node.id < _nodeNum - _width) {
deba@1979
   301
	edge.id = node.id;
deba@1979
   302
      } else if (node.id % _width < _width - 1) {
deba@1979
   303
	edge.id = _edgeLimit + node.id % _width +
deba@1979
   304
	  (node.id / _width) * (_width - 1);
deba@1979
   305
      } else {
deba@1979
   306
	edge.id = -1;
deba@1979
   307
      }
deba@1979
   308
    }
deba@1979
   309
deba@1979
   310
    void nextOut(Edge& edge) const {
deba@1979
   311
      if (edge.id >= _edgeLimit) {
deba@1979
   312
	edge.id = -1;
deba@1979
   313
      } else if (edge.id % _width < _width - 1) {
deba@1979
   314
	edge.id = _edgeLimit + edge.id % _width +
deba@1979
   315
	  (edge.id / _width) * (_width - 1);
deba@1979
   316
      } else {
deba@1979
   317
	edge.id = -1;
deba@1979
   318
      }
deba@1979
   319
    }
deba@1979
   320
deba@1979
   321
    void firstIn(Edge& edge, const Node& node) const {
deba@1979
   322
      if (node.id >= _width) {
deba@1979
   323
	edge.id = node.id - _width;
deba@1979
   324
      } else if (node.id % _width > 0) {
deba@1979
   325
	edge.id = _edgeLimit + node.id % _width +
deba@1979
   326
	  (node.id / _width) * (_width - 1) - 1;
deba@1979
   327
      } else {
deba@1979
   328
	edge.id = -1;
deba@1979
   329
      }
deba@1979
   330
    }
deba@1979
   331
    
deba@1979
   332
    void nextIn(Edge& edge) const {
deba@1979
   333
      if (edge.id >= _edgeLimit) {
deba@1979
   334
	edge.id = -1;
deba@1979
   335
      } else if (edge.id % _width > 0) {
deba@1979
   336
	edge.id = _edgeLimit + edge.id % _width +
deba@1979
   337
	  (edge.id / _width + 1) * (_width - 1) - 1;
deba@1979
   338
      } else {
deba@1979
   339
	edge.id = -1;
deba@1979
   340
      }
deba@1979
   341
    }
deba@1979
   342
deba@1979
   343
  private:
deba@1979
   344
    int _width, _height;
deba@1979
   345
    int _nodeNum, _edgeNum;
deba@1979
   346
    int _edgeLimit;
deba@1979
   347
  };
deba@1979
   348
deba@1979
   349
deba@2076
   350
  typedef UGraphExtender<UndirGraphExtender<GridUGraphBase> > 
deba@2076
   351
  ExtendedGridUGraphBase;
deba@1979
   352
deba@1979
   353
  /// \ingroup graphs
deba@1979
   354
  ///
deba@1979
   355
  /// \brief Grid graph class
deba@1979
   356
  ///
deba@1979
   357
  /// This class implements a special graph type. The nodes of the
deba@1979
   358
  /// graph can be indiced by two integer \c (i,j) value where \c i
deba@1979
   359
  /// is in the \c [0,width) range and j is in the [0, height) range.
deba@1979
   360
  /// Two nodes are connected in the graph if the indices differ only
deba@1979
   361
  /// on one position and only one is the difference. 
deba@1979
   362
  ///
deba@1979
   363
  /// The graph can be indiced in the following way:
deba@1979
   364
  ///\code
deba@1979
   365
  /// GridUGraph graph(w, h);
deba@1979
   366
  /// GridUGraph::NodeMap<int> val(graph); 
deba@1979
   367
  /// for (int i = 0; i < graph.width(); ++i) {
deba@1979
   368
  ///   for (int j = 0; j < graph.height(); ++j) {
deba@1979
   369
  ///     val[graph(i, j)] = i + j;
deba@1979
   370
  ///   }
deba@1979
   371
  /// }
deba@1979
   372
  ///\endcode
deba@1979
   373
  ///
deba@2037
   374
  /// The graph type is fully conform to the \ref concept::UGraph
deba@2037
   375
  /// "Undirected Graph" concept.
deba@1979
   376
  ///
deba@1979
   377
  /// \author Balazs Dezso
deba@1979
   378
  /// \see GridUGraphBase
deba@1979
   379
  class GridUGraph : public ExtendedGridUGraphBase {
deba@1979
   380
  public:
deba@1979
   381
deba@1979
   382
    typedef ExtendedGridUGraphBase Parent;
deba@1979
   383
deba@1979
   384
    /// \brief Map to get the indices of the nodes as xy<int>.
deba@1979
   385
    ///
deba@1979
   386
    /// Map to get the indices of the nodes as xy<int>.
deba@1979
   387
    class IndexMap {
deba@1979
   388
    public:
deba@1979
   389
      /// \brief The key type of the map
deba@1979
   390
      typedef GridUGraph::Node Key;
deba@1979
   391
      /// \brief The value type of the map
deba@1979
   392
      typedef xy<int> Value;
deba@1979
   393
deba@1979
   394
      /// \brief Constructor
deba@1979
   395
      ///
deba@1979
   396
      /// Constructor
deba@1979
   397
      IndexMap(const GridUGraph& _graph) : graph(_graph) {}
deba@1979
   398
deba@1979
   399
      /// \brief The subscript operator
deba@1979
   400
      ///
deba@1979
   401
      /// The subscript operator.
deba@1979
   402
      Value operator[](Key key) const {
deba@1979
   403
	return xy<int>(graph.row(key), graph.col(key));
deba@1979
   404
      }
deba@1979
   405
deba@1979
   406
    private:
deba@1979
   407
      const GridUGraph& graph;
deba@1979
   408
    };
deba@1979
   409
deba@1979
   410
    /// \brief Map to get the row of the nodes.
deba@1979
   411
    ///
deba@1979
   412
    /// Map to get the row of the nodes.
deba@1979
   413
    class RowMap {
deba@1979
   414
    public:
deba@1979
   415
      /// \brief The key type of the map
deba@1979
   416
      typedef GridUGraph::Node Key;
deba@1979
   417
      /// \brief The value type of the map
deba@1979
   418
      typedef int Value;
deba@1979
   419
deba@1979
   420
      /// \brief Constructor
deba@1979
   421
      ///
deba@1979
   422
      /// Constructor
deba@1979
   423
      RowMap(const GridUGraph& _graph) : graph(_graph) {}
deba@1979
   424
deba@1979
   425
      /// \brief The subscript operator
deba@1979
   426
      ///
deba@1979
   427
      /// The subscript operator.
deba@1979
   428
      Value operator[](Key key) const {
deba@1979
   429
	return graph.row(key);
deba@1979
   430
      }
deba@1979
   431
deba@1979
   432
    private:
deba@1979
   433
      const GridUGraph& graph;
deba@1979
   434
    };
deba@1979
   435
deba@1979
   436
    /// \brief Map to get the column of the nodes.
deba@1979
   437
    ///
deba@1979
   438
    /// Map to get the column of the nodes.
deba@1979
   439
    class ColMap {
deba@1979
   440
    public:
deba@1979
   441
      /// \brief The key type of the map
deba@1979
   442
      typedef GridUGraph::Node Key;
deba@1979
   443
      /// \brief The value type of the map
deba@1979
   444
      typedef int Value;
deba@1979
   445
deba@1979
   446
      /// \brief Constructor
deba@1979
   447
      ///
deba@1979
   448
      /// Constructor
deba@1979
   449
      ColMap(const GridUGraph& _graph) : graph(_graph) {}
deba@1979
   450
deba@1979
   451
      /// \brief The subscript operator
deba@1979
   452
      ///
deba@1979
   453
      /// The subscript operator.
deba@1979
   454
      Value operator[](Key key) const {
deba@1979
   455
	return graph.col(key);
deba@1979
   456
      }
deba@1979
   457
deba@1979
   458
    private:
deba@1979
   459
      const GridUGraph& graph;
deba@1979
   460
    };
deba@1979
   461
deba@1979
   462
    /// \brief Constructor
deba@1979
   463
    ///
deba@1979
   464
    /// 
deba@1979
   465
    GridUGraph(int n, int m) { construct(n, m); }
deba@1979
   466
deba@1979
   467
    /// \brief Resize the graph
deba@1979
   468
    ///
deba@1979
   469
    void resize(int n, int m) {
deba@1979
   470
      Parent::getNotifier(Edge()).clear();
deba@1979
   471
      Parent::getNotifier(UEdge()).clear();
deba@1979
   472
      Parent::getNotifier(Node()).clear();
deba@1979
   473
      construct(n, m);
deba@1979
   474
      Parent::getNotifier(Node()).build();
deba@1979
   475
      Parent::getNotifier(UEdge()).build();
deba@1979
   476
      Parent::getNotifier(Edge()).build();
deba@1979
   477
    }
deba@1979
   478
    
deba@1979
   479
    /// \brief Gives back the edge goes down from the node.
deba@1979
   480
    ///
deba@1979
   481
    /// Gives back the edge goes down from the node. If there is not
deba@1979
   482
    /// outgoing edge then it gives back INVALID.
deba@1979
   483
    Edge down(Node n) const {
deba@1979
   484
      UEdge ue = _down(n);
deba@1979
   485
      return ue != INVALID ? direct(ue, true) : INVALID;
deba@1979
   486
    }
deba@1979
   487
    
deba@1979
   488
    /// \brief Gives back the edge goes up from the node.
deba@1979
   489
    ///
deba@1979
   490
    /// Gives back the edge goes up from the node. If there is not
deba@1979
   491
    /// outgoing edge then it gives back INVALID.
deba@1979
   492
    Edge up(Node n) const {
deba@1979
   493
      UEdge ue = _up(n);
deba@1979
   494
      return ue != INVALID ? direct(ue, false) : INVALID;
deba@1979
   495
    }
deba@1979
   496
deba@1979
   497
    /// \brief Gives back the edge goes right from the node.
deba@1979
   498
    ///
deba@1979
   499
    /// Gives back the edge goes right from the node. If there is not
deba@1979
   500
    /// outgoing edge then it gives back INVALID.
deba@1979
   501
    Edge right(Node n) const {
deba@1979
   502
      UEdge ue = _right(n);
deba@1979
   503
      return ue != INVALID ? direct(ue, true) : INVALID;
deba@1979
   504
    }
deba@1979
   505
deba@1979
   506
    /// \brief Gives back the edge goes left from the node.
deba@1979
   507
    ///
deba@1979
   508
    /// Gives back the edge goes left from the node. If there is not
deba@1979
   509
    /// outgoing edge then it gives back INVALID.
deba@1979
   510
    Edge left(Node n) const {
deba@1979
   511
      UEdge ue = _left(n);
deba@1979
   512
      return ue != INVALID ? direct(ue, false) : INVALID;
deba@1979
   513
    }
deba@1979
   514
    
deba@1979
   515
  };
deba@1979
   516
deba@1979
   517
  /// \brief Index map of the grid graph
deba@1979
   518
  ///
deba@1979
   519
  /// Just returns an IndexMap for the grid graph.
deba@1979
   520
  GridUGraph::IndexMap indexMap(const GridUGraph& graph) {
deba@1979
   521
    return GridUGraph::IndexMap(graph);
deba@1979
   522
  }
deba@1979
   523
deba@1979
   524
  /// \brief Row map of the grid graph
deba@1979
   525
  ///
deba@1979
   526
  /// Just returns a RowMap for the grid graph.
deba@1979
   527
  GridUGraph::RowMap rowMap(const GridUGraph& graph) {
deba@1979
   528
    return GridUGraph::RowMap(graph);
deba@1979
   529
  }
deba@1979
   530
deba@1979
   531
  /// \brief Column map of the grid graph
deba@1979
   532
  ///
deba@1979
   533
  /// Just returns a ColMap for the grid graph.
deba@1979
   534
  GridUGraph::ColMap colMap(const GridUGraph& graph) {
deba@1979
   535
    return GridUGraph::ColMap(graph);
deba@1979
   536
  }
deba@1979
   537
}
deba@1979
   538
#endif