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