COIN-OR::LEMON - Graph Library

Ticket #57: grid_ada5f74d1c9e.patch

File grid_ada5f74d1c9e.patch, 17.9 KB (added by Peter Kovacs, 16 years ago)
  • lemon/Makefile.am

    # HG changeset patch
    # User Peter Kovacs <kpeter@inf.elte.hu>
    # Date 1220387524 -7200
    # Node ID ada5f74d1c9e874b24256426f1c5c0e141fcbc2d
    # Parent  c760d691fe3c47f3f57ee31f18f5aa5ae6fcf965
    Port grid graph structure from SVN 3503 (ticket #57)
    
    diff -r c760d691fe3c -r ada5f74d1c9e lemon/Makefile.am
    a b  
    3030        lemon/dim2.h \
    3131        lemon/error.h \
    3232        lemon/graph_to_eps.h \
     33        lemon/grid_graph.h \
    3334        lemon/kruskal.h \
    3435        lemon/lgf_reader.h \
    3536        lemon/lgf_writer.h \
  • new file lemon/grid_graph.h

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

    diff -r c760d691fe3c -r ada5f74d1c9e test/graph_test.cc
    a b  
    2020#include <lemon/list_graph.h>
    2121#include <lemon/smart_graph.h>
    2222// #include <lemon/full_graph.h>
    23 // #include <lemon/grid_graph.h>
     23#include <lemon/grid_graph.h>
    2424
    2525#include "test_tools.h"
    2626#include "graph_test.h"
     
    126126  }
    127127//  { // Checking FullGraph
    128128//    checkConcept<Graph, FullGraph>();
    129 //    checkGraphIterators<FullGraph>();
    130129//  }
    131 //  { // Checking GridGraph
    132 //    checkConcept<Graph, GridGraph>();
    133 //    checkGraphIterators<GridGraph>();
    134 //  }
     130  { // Checking GridGraph
     131    checkConcept<Graph, GridGraph>();
     132  }
    135133}
    136134
    137135template <typename Graph>
     
    188186  check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
    189187}
    190188
    191 // void checkGridGraph(const GridGraph& g, int w, int h) {
    192 //   check(g.width() == w, "Wrong width");
    193 //   check(g.height() == h, "Wrong height");
     189void checkGridGraph(const GridGraph& g, int w, int h) {
     190  check(g.width() == w, "Wrong width");
     191  check(g.height() == h, "Wrong height");
    194192
    195 //   for (int i = 0; i < w; ++i) {
    196 //     for (int j = 0; j < h; ++j) {
    197 //       check(g.col(g(i, j)) == i, "Wrong col");
    198 //       check(g.row(g(i, j)) == j, "Wrong row");
    199 //     }
    200 //   }
     193  for (int i = 0; i < w; ++i) {
     194    for (int j = 0; j < h; ++j) {
     195      check(g.col(g(i, j)) == i, "Wrong col");
     196      check(g.row(g(i, j)) == j, "Wrong row");
     197    }
     198  }
    201199
    202 //   for (int i = 0; i < w; ++i) {
    203 //     for (int j = 0; j < h - 1; ++j) {
    204 //       check(g.source(g.down(g(i, j))) == g(i, j), "Wrong down");
    205 //       check(g.target(g.down(g(i, j))) == g(i, j + 1), "Wrong down");
    206 //     }
    207 //     check(g.down(g(i, h - 1)) == INVALID, "Wrong down");
    208 //   }
     200  for (int i = 0; i < w; ++i) {
     201    for (int j = 0; j < h - 1; ++j) {
     202      check(g.source(g.down(g(i, j))) == g(i, j), "Wrong down");
     203      check(g.target(g.down(g(i, j))) == g(i, j + 1), "Wrong down");
     204    }
     205    check(g.down(g(i, h - 1)) == INVALID, "Wrong down");
     206  }
    209207
    210 //   for (int i = 0; i < w; ++i) {
    211 //     for (int j = 1; j < h; ++j) {
    212 //       check(g.source(g.up(g(i, j))) == g(i, j), "Wrong up");
    213 //       check(g.target(g.up(g(i, j))) == g(i, j - 1), "Wrong up");
    214 //     }
    215 //     check(g.up(g(i, 0)) == INVALID, "Wrong up");
    216 //   }
     208  for (int i = 0; i < w; ++i) {
     209    for (int j = 1; j < h; ++j) {
     210      check(g.source(g.up(g(i, j))) == g(i, j), "Wrong up");
     211      check(g.target(g.up(g(i, j))) == g(i, j - 1), "Wrong up");
     212    }
     213    check(g.up(g(i, 0)) == INVALID, "Wrong up");
     214  }
    217215
    218 //   for (int j = 0; j < h; ++j) {
    219 //     for (int i = 0; i < w - 1; ++i) {
    220 //       check(g.source(g.right(g(i, j))) == g(i, j), "Wrong right");
    221 //       check(g.target(g.right(g(i, j))) == g(i + 1, j), "Wrong right");
    222 //     }
    223 //     check(g.right(g(w - 1, j)) == INVALID, "Wrong right");
    224 //   }
     216  for (int j = 0; j < h; ++j) {
     217    for (int i = 0; i < w - 1; ++i) {
     218      check(g.source(g.right(g(i, j))) == g(i, j), "Wrong right");
     219      check(g.target(g.right(g(i, j))) == g(i + 1, j), "Wrong right");
     220    }
     221    check(g.right(g(w - 1, j)) == INVALID, "Wrong right");
     222  }
    225223
    226 //   for (int j = 0; j < h; ++j) {
    227 //     for (int i = 1; i < w; ++i) {
    228 //       check(g.source(g.left(g(i, j))) == g(i, j), "Wrong left");
    229 //       check(g.target(g.left(g(i, j))) == g(i - 1, j), "Wrong left");
    230 //     }
    231 //     check(g.left(g(0, j)) == INVALID, "Wrong left");
    232 //   }
    233 // }
     224  for (int j = 0; j < h; ++j) {
     225    for (int i = 1; i < w; ++i) {
     226      check(g.source(g.left(g(i, j))) == g(i, j), "Wrong left");
     227      check(g.target(g.left(g(i, j))) == g(i - 1, j), "Wrong left");
     228    }
     229    check(g.left(g(0, j)) == INVALID, "Wrong left");
     230  }
     231
     232  checkGraphNodeList(g, w*h);
     233  checkGraphArcList(g, 2*(2*w*h-w-h));
     234  checkGraphEdgeList(g, 2*w*h-w-h);
     235
     236  checkGraphOutArcList(g, g(0,0), 2);
     237  checkGraphOutArcList(g, g(0,1), 3);
     238  checkGraphOutArcList(g, g(w-2,h-2), 4);
     239
     240  checkGraphInArcList(g, g(0,0), 2);
     241  checkGraphInArcList(g, g(0,1), 3);
     242  checkGraphInArcList(g, g(w-2,h-2), 4);
     243
     244  checkGraphIncEdgeList(g, g(0,0), 2);
     245  checkGraphIncEdgeList(g, g(0,1), 3);
     246  checkGraphIncEdgeList(g, g(w-2,h-2), 4);
     247
     248  checkGraphConArcList(g, 2*(2*w*h-w-h));
     249  checkGraphConEdgeList(g, 2*w*h-w-h);
     250
     251  checkArcDirections(g);
     252
     253  checkNodeIds(g);
     254  checkArcIds(g);
     255  checkEdgeIds(g);
     256  checkGraphNodeMap(g);
     257  checkGraphArcMap(g);
     258  checkGraphEdgeMap(g);
     259}
    234260
    235261void checkGraphs() {
    236262  { // Checking ListGraph
     
    246272//     checkGraphNodeList(g, 5);
    247273//     checkGraphEdgeList(g, 10);
    248274//   }
    249 //   { // Checking GridGraph
    250 //     GridGraph g(5, 6);
    251 //     checkGraphNodeList(g, 30);
    252 //     checkGraphEdgeList(g, 49);
    253 //     checkGridGraph(g, 5, 6);
    254 //   }
     275  { // Checking GridGraph
     276    GridGraph g(5, 6);
     277    checkGridGraph(g, 5, 6);
     278  }
    255279}
    256280
    257281int main() {