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