# HG changeset patch # User deba # Date 1126516792 0 # Node ID 4f8b9cee576b82fe00913d8ba64c6e2b081ca06e # Parent e825655c24a4bf05d265514743a5ae5da49ee1ec Fixing and improving GridGraph diff -r e825655c24a4 -r 4f8b9cee576b demo/Makefile.am --- a/demo/Makefile.am Mon Sep 12 09:15:59 2005 +0000 +++ b/demo/Makefile.am Mon Sep 12 09:19:52 2005 +0000 @@ -14,7 +14,8 @@ hello_lemon \ sub_graph_adaptor_demo \ descriptor_map_demo \ - coloring + coloring \ + grid_graph_demo if HAVE_GLPK noinst_PROGRAMS += lp_demo lp_maxflow_demo @@ -37,6 +38,8 @@ graph_to_eps_demo_SOURCES = graph_to_eps_demo.cc +grid_graph_demo_SOURCES = grid_graph_demo.cc + graph_orientation_SOURCES = graph_orientation.cc min_route_SOURCES = min_route.cc diff -r e825655c24a4 -r 4f8b9cee576b demo/grid_graph_demo.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/demo/grid_graph_demo.cc Mon Sep 12 09:19:52 2005 +0000 @@ -0,0 +1,29 @@ +#include +#include +#include +#include + +#include +#include + +using namespace lemon; +using namespace std; + +int main() { + GridGraph graph(5, 7); + GridGraph::NodeMap > coord(graph); + for (int i = 0; i < graph.width(); ++i) { + for (int j = 0; j < graph.height(); ++j) { + coord[graph(i, j)] = xy(i * 10.0, j * 10.0); + } + } + graphToEps(graph, "grid_graph.eps").scaleToA4(). + title("Grid graph"). + copyright("(C) 2005 LEMON Project"). + coords(coord). + enableParallel(). + nodeScale(.45). + drawArrows(). + run(); + return 0; +} diff -r e825655c24a4 -r 4f8b9cee576b lemon/grid_graph.h --- a/lemon/grid_graph.h Mon Sep 12 09:15:59 2005 +0000 +++ b/lemon/grid_graph.h Mon Sep 12 09:19:52 2005 +0000 @@ -47,19 +47,68 @@ /// \brief Creates a grid graph with the given size. /// /// Creates a grid graph with the given size. - void construct(int height, int width) { + void construct(int width, int height) { _height = height; _width = width; _nodeNum = height * width; _edgeNum = 2 * _nodeNum - width - height; _edgeLimit = _nodeNum - width; } + /// \brief Gives back the edge goes down from the node. + /// + /// Gives back the edge goes down from the node. If there is not + /// outgoing edge then it gives back INVALID. + Edge _down(Node n) const { + if (n.id < _nodeNum - _width) { + return Edge(n.id); + } else { + return INVALID; + } + } + + /// \brief Gives back the edge comes from up into the node. + /// + /// Gives back the edge comes from up into the node. If there is not + /// incoming edge then it gives back INVALID. + Edge _up(Node n) const { + if (n.id >= _width) { + return Edge(n.id - _width); + } else { + return INVALID; + } + } + + /// \brief Gives back the edge goes right from the node. + /// + /// Gives back the edge goes right from the node. If there is not + /// outgoing edge then it gives back INVALID. + Edge _right(Node n) const { + if (n.id % _width < _width - 1) { + return _edgeLimit + n.id % _width + (n.id / _width) * (_width - 1); + } else { + return INVALID; + } + } + + /// \brief Gives back the edge comes from left into the node. + /// + /// Gives back the edge comes left up into the node. If there is not + /// incoming edge then it gives back INVALID. + Edge _left(Node n) const { + if (n.id % _width > 0) { + return _edgeLimit + n.id % _width + (n.id / _width) * (_width - 1) - 1; + } else { + return INVALID; + } + } + + public: /// \brief The node on the given position. /// /// Gives back the node on the given position. Node operator()(int i, int j) const { - return Node(i * _width + j); + return Node(i + j * _width); } /// \brief Gives back the row index of the node. @@ -72,7 +121,7 @@ /// \brief Gives back the coloumn index of the node. /// /// Gives back the coloumn index of the node. - int col(Node node) const { + int col(Node n) const { return n.id % _width; } @@ -277,14 +326,10 @@ }; - typedef UndirGraphExtender - UndirGridGraphBase; - typedef AlterableUndirGraphExtender - AlterableGridGraphBase; - typedef IterableUndirGraphExtender - IterableGridGraphBase; - typedef MappableUndirGraphExtender - MappableGridGraphBase; + typedef MappableUndirGraphExtender< + IterableUndirGraphExtender< + AlterableUndirGraphExtender< + UndirGraphExtender > > > ExtendedGridGraphBase; /// \ingroup graphs /// @@ -311,10 +356,47 @@ /// "Undirected Graph" concept. /// /// \author Balazs Dezso - class GridGraph : public MappableGridGraphBase { + class GridGraph : public ExtendedGridGraphBase { public: - GridGraph(int m, int n) { construct(m, n); } + GridGraph(int n, int m) { construct(n, m); } + + /// \brief Gives back the edge goes down from the node. + /// + /// Gives back the edge goes down from the node. If there is not + /// outgoing edge then it gives back INVALID. + Edge down(Node n) const { + UndirEdge ue = _down(n); + return ue != INVALID ? direct(ue, true) : INVALID; + } + + /// \brief Gives back the edge goes up from the node. + /// + /// Gives back the edge goes up from the node. If there is not + /// outgoing edge then it gives back INVALID. + Edge up(Node n) const { + UndirEdge ue = _up(n); + return ue != INVALID ? direct(ue, false) : INVALID; + } + + /// \brief Gives back the edge goes right from the node. + /// + /// Gives back the edge goes right from the node. If there is not + /// outgoing edge then it gives back INVALID. + Edge right(Node n) const { + UndirEdge ue = _right(n); + return ue != INVALID ? direct(ue, true) : INVALID; + } + + /// \brief Gives back the edge goes left from the node. + /// + /// Gives back the edge goes left from the node. If there is not + /// outgoing edge then it gives back INVALID. + Edge left(Node n) const { + UndirEdge ue = _left(n); + return ue != INVALID ? direct(ue, false) : INVALID; + } + }; } #endif diff -r e825655c24a4 -r 4f8b9cee576b test/undir_graph_test.cc --- a/test/undir_graph_test.cc Mon Sep 12 09:15:59 2005 +0000 +++ b/test/undir_graph_test.cc Mon Sep 12 09:19:52 2005 +0000 @@ -5,6 +5,7 @@ #include #include #include +#include #include @@ -43,12 +44,35 @@ checkConcept(); checkConcept(); + + checkConcept(); } template void check_item_counts(Graph &g, int n, int e) { - check(countNodes(g)==n, "Wrong node number."); - check(countEdges(g)==2*e, "Wrong edge number."); + int nn = 0; + for (typename Graph::NodeIt it(g); it != INVALID; ++it) { + ++nn; + } + + check(nn == n, "Wrong node number."); + check(countNodes(g) == n, "Wrong node number."); + + int ee = 0; + for (typename Graph::EdgeIt it(g); it != INVALID; ++it) { + ++ee; + } + + check(ee == 2*e, "Wrong edge number."); + check(countEdges(g) == 2*e, "Wrong edge number."); + + int uee = 0; + for (typename Graph::UndirEdgeIt it(g); it != INVALID; ++it) { + ++uee; + } + + check(uee == e, "Wrong undir edge number."); + check(countUndirEdges(g) == e, "Wrong undir edge number."); } template @@ -108,8 +132,50 @@ // print_items(g); check_item_counts(g,3,2); +} +void checkGridGraph(const GridGraph& g, int w, int h) { + check(g.width() == w, "Wrong width"); + check(g.height() == h, "Wrong height"); + for (int i = 0; i < w; ++i) { + for (int j = 0; j < h; ++j) { + check(g.col(g(i, j)) == i, "Wrong col"); + check(g.row(g(i, j)) == j, "Wrong row"); + } + } + + for (int i = 0; i < w; ++i) { + for (int j = 0; j < h - 1; ++j) { + check(g.source(g.down(g(i, j))) == g(i, j), "Wrong down"); + check(g.target(g.down(g(i, j))) == g(i, j + 1), "Wrong down"); + } + check(g.down(g(i, h - 1)) == INVALID, "Wrong down"); + } + + for (int i = 0; i < w; ++i) { + for (int j = 1; j < h; ++j) { + check(g.source(g.up(g(i, j))) == g(i, j), "Wrong up"); + check(g.target(g.up(g(i, j))) == g(i, j - 1), "Wrong up"); + } + check(g.up(g(i, 0)) == INVALID, "Wrong up"); + } + + for (int j = 0; j < h; ++j) { + for (int i = 0; i < w - 1; ++i) { + check(g.source(g.right(g(i, j))) == g(i, j), "Wrong right"); + check(g.target(g.right(g(i, j))) == g(i + 1, j), "Wrong right"); + } + check(g.right(g(w - 1, j)) == INVALID, "Wrong right"); + } + + for (int j = 0; j < h; ++j) { + for (int i = 1; i < w; ++i) { + check(g.source(g.left(g(i, j))) == g(i, j), "Wrong left"); + check(g.target(g.left(g(i, j))) == g(i - 1, j), "Wrong left"); + } + check(g.left(g(0, j)) == INVALID, "Wrong left"); + } } int main() { @@ -123,5 +189,13 @@ check_item_counts(g, 5, 10); } + { + GridGraph g(5, 6); + check_item_counts(g, 30, 49); + checkGridGraph(g, 5, 6); + } + + std::cout << __FILE__ ": All tests passed.\n"; + return 0; }