[Lemon-commits] Peter Kovacs: Port grid graph structure from SVN...

Lemon HG hg at lemon.cs.elte.hu
Wed Oct 22 23:32:26 CEST 2008


details:   http://lemon.cs.elte.hu/hg/lemon/rev/ada5f74d1c9e
changeset: 346:ada5f74d1c9e
user:      Peter Kovacs <kpeter [at] inf.elte.hu>
date:      Tue Sep 02 22:32:04 2008 +0200
description:
	Port grid graph structure from SVN 3503 (ticket #57)

diffstat:

3 files changed, 546 insertions(+), 50 deletions(-)
lemon/Makefile.am  |    1 
lemon/grid_graph.h |  471 ++++++++++++++++++++++++++++++++++++++++++++++++++++
test/graph_test.cc |  124 ++++++++-----

diffs (truncated from 647 to 300 lines):

diff -r c760d691fe3c -r ada5f74d1c9e lemon/Makefile.am
--- a/lemon/Makefile.am	Tue Sep 02 22:27:19 2008 +0200
+++ b/lemon/Makefile.am	Tue Sep 02 22:32:04 2008 +0200
@@ -30,6 +30,7 @@
         lemon/dim2.h \
 	lemon/error.h \
         lemon/graph_to_eps.h \
+        lemon/grid_graph.h \
 	lemon/kruskal.h \
 	lemon/lgf_reader.h \
 	lemon/lgf_writer.h \
diff -r c760d691fe3c -r ada5f74d1c9e lemon/grid_graph.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lemon/grid_graph.h	Tue Sep 02 22:32:04 2008 +0200
@@ -0,0 +1,471 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef GRID_GRAPH_H
+#define GRID_GRAPH_H
+
+#include <iostream>
+#include <lemon/core.h>
+#include <lemon/assert.h>
+
+#include <lemon/bits/base_extender.h>
+#include <lemon/bits/graph_extender.h>
+
+#include <lemon/dim2.h>
+
+///\ingroup graphs
+///\file
+///\brief GridGraph class.
+
+namespace lemon {
+
+  class GridGraphBase {
+
+  public:
+
+    typedef GridGraphBase Graph;
+
+    class Node;
+    class Arc;
+
+  public:
+
+    GridGraphBase() {}
+
+  protected:
+
+    void construct(int w, int h) {
+      _height = h; _width = w;
+      _nodeNum = h * w; _arcNum = 2 * _nodeNum - w - h;
+      _arcLimit = _nodeNum - w;
+    }
+
+    Arc _down(Node n) const {
+      if (n.id < _nodeNum - _width) {
+        return Arc(n.id);
+      } else {
+        return INVALID;
+      }
+    }
+
+    Arc _up(Node n) const {
+      if (n.id >= _width) {
+        return Arc(n.id - _width);
+      } else {
+        return INVALID;
+      }
+    }
+
+    Arc _right(Node n) const {
+      if (n.id % _width < _width - 1) {
+        return _arcLimit + n.id % _width + (n.id / _width) * (_width - 1);
+      } else {
+        return INVALID;
+      }
+    }
+
+    Arc _left(Node n) const {
+      if (n.id % _width > 0) {
+        return _arcLimit + n.id % _width + (n.id / _width) * (_width - 1) - 1;
+      } else {
+        return INVALID;
+      }
+    }
+
+  public:
+
+    Node operator()(int i, int j) const {
+      LEMON_ASSERT(0 <= i && i < width() &&
+                   0 <= j && j < height(), "lemon::GridGraph::IndexError");
+      return Node(i + j * _width);
+    }
+
+    int row(Node n) const {
+      return n.id / _width;
+    }
+
+    int col(Node n) const {
+      return n.id % _width;
+    }
+
+    int width() const {
+      return _width;
+    }
+
+    int height() const {
+      return _height;
+    }
+
+    typedef True NodeNumTag;
+    typedef True ArcNumTag;
+
+    int nodeNum() const { return _nodeNum; }
+    int arcNum() const { return _arcNum; }
+
+    int maxNodeId() const { return nodeNum() - 1; }
+    int maxArcId() const { return arcNum() - 1; }
+
+    Node source(Arc e) const {
+      if (e.id < _arcLimit) {
+        return e.id;
+      } else {
+        return (e.id - _arcLimit) % (_width - 1) +
+          (e.id - _arcLimit) / (_width - 1) * _width;
+      }
+    }
+
+    Node target(Arc e) const {
+      if (e.id < _arcLimit) {
+        return e.id + _width;
+      } else {
+        return (e.id - _arcLimit) % (_width - 1) +
+          (e.id - _arcLimit) / (_width - 1) * _width + 1;
+      }
+    }
+
+    static int id(Node v) { return v.id; }
+    static int id(Arc e) { return e.id; }
+
+    static Node nodeFromId(int id) { return Node(id);}
+
+    static Arc arcFromId(int id) { return Arc(id);}
+
+    typedef True FindArcTag;
+
+    Arc findArc(Node u, Node v, Arc prev = INVALID) const {
+      if (prev != INVALID) return INVALID;
+      if (v.id - u.id == _width) return Arc(u.id);
+      if (v.id - u.id == 1 && u.id % _width < _width - 1) {
+        return Arc(u.id / _width * (_width - 1) +
+                   u.id % _width + _arcLimit);
+      }
+      return INVALID;
+    }
+
+    class Node {
+      friend class GridGraphBase;
+
+    protected:
+      int id;
+      Node(int _id) : id(_id) {}
+    public:
+      Node() {}
+      Node (Invalid) { id = -1; }
+      bool operator==(const Node node) const { return id == node.id; }
+      bool operator!=(const Node node) const { return id != node.id; }
+      bool operator<(const Node node) const { return id < node.id; }
+    };
+
+    class Arc {
+      friend class GridGraphBase;
+
+    protected:
+      int id;
+      Arc(int _id) : id(_id) {}
+    public:
+      Arc() {}
+      Arc (Invalid) { id = -1; }
+      bool operator==(const Arc arc) const { return id == arc.id; }
+      bool operator!=(const Arc arc) const { return id != arc.id; }
+      bool operator<(const Arc arc) const { return id < arc.id; }
+    };
+
+    void first(Node& node) const {
+      node.id = nodeNum() - 1;
+    }
+
+    static void next(Node& node) {
+      --node.id;
+    }
+
+    void first(Arc& arc) const {
+      arc.id = arcNum() - 1;
+    }
+
+    static void next(Arc& arc) {
+      --arc.id;
+    }
+
+    void firstOut(Arc& arc, const Node& node) const {
+      if (node.id < _nodeNum - _width) {
+        arc.id = node.id;
+      } else if (node.id % _width < _width - 1) {
+        arc.id = _arcLimit + node.id % _width +
+          (node.id / _width) * (_width - 1);
+      } else {
+        arc.id = -1;
+      }
+    }
+
+    void nextOut(Arc& arc) const {
+      if (arc.id >= _arcLimit) {
+        arc.id = -1;
+      } else if (arc.id % _width < _width - 1) {
+        arc.id = _arcLimit + arc.id % _width +
+          (arc.id / _width) * (_width - 1);
+      } else {
+        arc.id = -1;
+      }
+    }
+
+    void firstIn(Arc& arc, const Node& node) const {
+      if (node.id >= _width) {
+        arc.id = node.id - _width;
+      } else if (node.id % _width > 0) {
+        arc.id = _arcLimit + node.id % _width +
+          (node.id / _width) * (_width - 1) - 1;
+      } else {
+        arc.id = -1;
+      }
+    }
+
+    void nextIn(Arc& arc) const {
+      if (arc.id >= _arcLimit) {
+        arc.id = -1;
+      } else if (arc.id % _width > 0) {
+        arc.id = _arcLimit + arc.id % _width +
+          (arc.id / _width + 1) * (_width - 1) - 1;
+      } else {
+        arc.id = -1;
+      }
+    }
+
+  private:
+    int _width, _height;
+    int _nodeNum, _arcNum;
+    int _arcLimit;
+  };
+
+  typedef GraphExtender<UndirDigraphExtender<GridGraphBase> >
+    ExtendedGridGraphBase;
+
+  /// \ingroup graphs
+  ///
+  /// \brief Grid graph class
+  ///
+  /// This class implements a special graph type. The nodes of the
+  /// graph can be indiced by two integer \c (i,j) value where \c i
+  /// is in the \c [0,width) range and j is in the [0, height) range.
+  /// Two nodes are connected in the graph if the indices differ only
+  /// on one position and only one is the difference.
+  ///
+  /// \image html grid_graph.png
+  /// \image latex grid_graph.eps "Grid graph" width=\textwidth
+  ///
+  /// The graph can be indiced in the following way:
+  ///\code
+  /// GridGraph gr(w, h);
+  /// GridGraph::NodeMap<int> val(gr);
+  /// for (int i = 0; i < gr.width(); ++i) {
+  ///   for (int j = 0; j < gr.height(); ++j) {
+  ///     val[gr(i, j)] = i + j;
+  ///   }
+  /// }
+  ///\endcode
+  ///
+  /// This graph type is fully conform to the \ref concepts::Graph
+  /// "Undirected Graph" concept, and it also has an important extra
+  /// feature that its maps are real \ref concepts::ReferenceMap
+  /// "reference map"s.
+  class GridGraph : public ExtendedGridGraphBase {



More information about the Lemon-commits mailing list