[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