0
2
1
| 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 |
|
|
| 35 |
namespace 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 |
| ... | ... |
@@ -21,24 +21,25 @@ |
| 21 | 21 |
lemon/assert.h \ |
| 22 | 22 |
lemon/bfs.h \ |
| 23 | 23 |
lemon/bin_heap.h \ |
| 24 | 24 |
lemon/color.h \ |
| 25 | 25 |
lemon/concept_check.h \ |
| 26 | 26 |
lemon/counter.h \ |
| 27 | 27 |
lemon/core.h \ |
| 28 | 28 |
lemon/dfs.h \ |
| 29 | 29 |
lemon/dijkstra.h \ |
| 30 | 30 |
lemon/dim2.h \ |
| 31 | 31 |
lemon/error.h \ |
| 32 | 32 |
lemon/graph_to_eps.h \ |
| 33 |
lemon/grid_graph.h \ |
|
| 33 | 34 |
lemon/kruskal.h \ |
| 34 | 35 |
lemon/lgf_reader.h \ |
| 35 | 36 |
lemon/lgf_writer.h \ |
| 36 | 37 |
lemon/list_graph.h \ |
| 37 | 38 |
lemon/maps.h \ |
| 38 | 39 |
lemon/math.h \ |
| 39 | 40 |
lemon/path.h \ |
| 40 | 41 |
lemon/random.h \ |
| 41 | 42 |
lemon/smart_graph.h \ |
| 42 | 43 |
lemon/time_measure.h \ |
| 43 | 44 |
lemon/tolerance.h \ |
| 44 | 45 |
lemon/unionfind.h |
| ... | ... |
@@ -11,25 +11,25 @@ |
| 11 | 11 |
* precise terms see the accompanying LICENSE file. |
| 12 | 12 |
* |
| 13 | 13 |
* This software is provided "AS IS" with no warranty of any kind, |
| 14 | 14 |
* express or implied, and with no claim as to its suitability for any |
| 15 | 15 |
* purpose. |
| 16 | 16 |
* |
| 17 | 17 |
*/ |
| 18 | 18 |
|
| 19 | 19 |
#include <lemon/concepts/graph.h> |
| 20 | 20 |
#include <lemon/list_graph.h> |
| 21 | 21 |
#include <lemon/smart_graph.h> |
| 22 | 22 |
// #include <lemon/full_graph.h> |
| 23 |
|
|
| 23 |
#include <lemon/grid_graph.h> |
|
| 24 | 24 |
|
| 25 | 25 |
#include "test_tools.h" |
| 26 | 26 |
#include "graph_test.h" |
| 27 | 27 |
|
| 28 | 28 |
using namespace lemon; |
| 29 | 29 |
using namespace lemon::concepts; |
| 30 | 30 |
|
| 31 | 31 |
template <class Graph> |
| 32 | 32 |
void checkGraph() {
|
| 33 | 33 |
TEMPLATE_GRAPH_TYPEDEFS(Graph); |
| 34 | 34 |
|
| 35 | 35 |
Graph G; |
| ... | ... |
@@ -117,30 +117,28 @@ |
| 117 | 117 |
checkConcept<ExtendableGraphComponent<>, ListGraph>(); |
| 118 | 118 |
checkConcept<ClearableGraphComponent<>, ListGraph>(); |
| 119 | 119 |
checkConcept<ErasableGraphComponent<>, ListGraph>(); |
| 120 | 120 |
} |
| 121 | 121 |
{ // Checking SmartGraph
|
| 122 | 122 |
checkConcept<Graph, SmartGraph>(); |
| 123 | 123 |
checkConcept<AlterableGraphComponent<>, SmartGraph>(); |
| 124 | 124 |
checkConcept<ExtendableGraphComponent<>, SmartGraph>(); |
| 125 | 125 |
checkConcept<ClearableGraphComponent<>, SmartGraph>(); |
| 126 | 126 |
} |
| 127 | 127 |
// { // Checking FullGraph
|
| 128 | 128 |
// checkConcept<Graph, FullGraph>(); |
| 129 |
// checkGraphIterators<FullGraph>(); |
|
| 130 | 129 |
// } |
| 131 |
// { // Checking GridGraph
|
|
| 132 |
// checkConcept<Graph, GridGraph>(); |
|
| 133 |
// checkGraphIterators<GridGraph>(); |
|
| 134 |
// } |
|
| 130 |
{ // Checking GridGraph
|
|
| 131 |
checkConcept<Graph, GridGraph>(); |
|
| 132 |
} |
|
| 135 | 133 |
} |
| 136 | 134 |
|
| 137 | 135 |
template <typename Graph> |
| 138 | 136 |
void checkGraphValidity() {
|
| 139 | 137 |
TEMPLATE_GRAPH_TYPEDEFS(Graph); |
| 140 | 138 |
Graph g; |
| 141 | 139 |
|
| 142 | 140 |
Node |
| 143 | 141 |
n1 = g.addNode(), |
| 144 | 142 |
n2 = g.addNode(), |
| 145 | 143 |
n3 = g.addNode(); |
| 146 | 144 |
|
| ... | ... |
@@ -179,83 +177,109 @@ |
| 179 | 177 |
|
| 180 | 178 |
check(!g.valid(n1), "Wrong validity check"); |
| 181 | 179 |
check(g.valid(n2), "Wrong validity check"); |
| 182 | 180 |
check(g.valid(n3), "Wrong validity check"); |
| 183 | 181 |
check(!g.valid(e1), "Wrong validity check"); |
| 184 | 182 |
check(g.valid(e2), "Wrong validity check"); |
| 185 | 183 |
|
| 186 | 184 |
check(!g.valid(g.nodeFromId(-1)), "Wrong validity check"); |
| 187 | 185 |
check(!g.valid(g.edgeFromId(-1)), "Wrong validity check"); |
| 188 | 186 |
check(!g.valid(g.arcFromId(-1)), "Wrong validity check"); |
| 189 | 187 |
} |
| 190 | 188 |
|
| 191 |
// void checkGridGraph(const GridGraph& g, int w, int h) {
|
|
| 192 |
// check(g.width() == w, "Wrong width"); |
|
| 193 |
|
|
| 189 |
void checkGridGraph(const GridGraph& g, int w, int h) {
|
|
| 190 |
check(g.width() == w, "Wrong width"); |
|
| 191 |
check(g.height() == h, "Wrong height"); |
|
| 194 | 192 |
|
| 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 |
} |
|
| 201 | 199 |
|
| 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 |
} |
|
| 209 | 207 |
|
| 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 |
} |
|
| 217 | 215 |
|
| 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 |
} |
|
| 225 | 223 |
|
| 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 |
} |
|
| 234 | 260 |
|
| 235 | 261 |
void checkGraphs() {
|
| 236 | 262 |
{ // Checking ListGraph
|
| 237 | 263 |
checkGraph<ListGraph>(); |
| 238 | 264 |
checkGraphValidityErase<ListGraph>(); |
| 239 | 265 |
} |
| 240 | 266 |
{ // Checking SmartGraph
|
| 241 | 267 |
checkGraph<SmartGraph>(); |
| 242 | 268 |
checkGraphValidity<SmartGraph>(); |
| 243 | 269 |
} |
| 244 | 270 |
// { // Checking FullGraph
|
| 245 | 271 |
// FullGraph g(5); |
| 246 | 272 |
// checkGraphNodeList(g, 5); |
| 247 | 273 |
// checkGraphEdgeList(g, 10); |
| 248 | 274 |
// } |
| 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 |
} |
|
| 255 | 279 |
} |
| 256 | 280 |
|
| 257 | 281 |
int main() {
|
| 258 | 282 |
checkConcepts(); |
| 259 | 283 |
checkGraphs(); |
| 260 | 284 |
return 0; |
| 261 | 285 |
} |
0 comments (0 inline)