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