lemongraph 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.yardopts +8 -0
- data/LICENSE +674 -0
- data/README.md +6 -0
- data/ext/lemon-1.3.1/AUTHORS +26 -0
- data/ext/lemon-1.3.1/CMakeLists.txt +371 -0
- data/ext/lemon-1.3.1/INSTALL +167 -0
- data/ext/lemon-1.3.1/LICENSE +32 -0
- data/ext/lemon-1.3.1/NEWS +337 -0
- data/ext/lemon-1.3.1/README +50 -0
- data/ext/lemon-1.3.1/cmake/FindCOIN.cmake +110 -0
- data/ext/lemon-1.3.1/cmake/FindGLPK.cmake +55 -0
- data/ext/lemon-1.3.1/cmake/FindGhostscript.cmake +10 -0
- data/ext/lemon-1.3.1/cmake/FindILOG.cmake +102 -0
- data/ext/lemon-1.3.1/cmake/FindSOPLEX.cmake +23 -0
- data/ext/lemon-1.3.1/cmake/LEMONConfig.cmake.in +13 -0
- data/ext/lemon-1.3.1/cmake/nsis/lemon.ico +0 -0
- data/ext/lemon-1.3.1/cmake/nsis/uninstall.ico +0 -0
- data/ext/lemon-1.3.1/cmake/version.cmake +1 -0
- data/ext/lemon-1.3.1/cmake/version.cmake.in +1 -0
- data/ext/lemon-1.3.1/contrib/CMakeLists.txt +19 -0
- data/ext/lemon-1.3.1/lemon/CMakeLists.txt +91 -0
- data/ext/lemon-1.3.1/lemon/adaptors.h +3638 -0
- data/ext/lemon-1.3.1/lemon/arg_parser.cc +474 -0
- data/ext/lemon-1.3.1/lemon/arg_parser.h +440 -0
- data/ext/lemon-1.3.1/lemon/assert.h +214 -0
- data/ext/lemon-1.3.1/lemon/base.cc +37 -0
- data/ext/lemon-1.3.1/lemon/bellman_ford.h +1116 -0
- data/ext/lemon-1.3.1/lemon/bfs.h +1754 -0
- data/ext/lemon-1.3.1/lemon/bin_heap.h +347 -0
- data/ext/lemon-1.3.1/lemon/binomial_heap.h +445 -0
- data/ext/lemon-1.3.1/lemon/bits/alteration_notifier.h +472 -0
- data/ext/lemon-1.3.1/lemon/bits/array_map.h +351 -0
- data/ext/lemon-1.3.1/lemon/bits/bezier.h +174 -0
- data/ext/lemon-1.3.1/lemon/bits/default_map.h +182 -0
- data/ext/lemon-1.3.1/lemon/bits/edge_set_extender.h +627 -0
- data/ext/lemon-1.3.1/lemon/bits/enable_if.h +131 -0
- data/ext/lemon-1.3.1/lemon/bits/graph_adaptor_extender.h +401 -0
- data/ext/lemon-1.3.1/lemon/bits/graph_extender.h +1332 -0
- data/ext/lemon-1.3.1/lemon/bits/lock.h +65 -0
- data/ext/lemon-1.3.1/lemon/bits/map_extender.h +332 -0
- data/ext/lemon-1.3.1/lemon/bits/path_dump.h +177 -0
- data/ext/lemon-1.3.1/lemon/bits/solver_bits.h +194 -0
- data/ext/lemon-1.3.1/lemon/bits/traits.h +388 -0
- data/ext/lemon-1.3.1/lemon/bits/variant.h +494 -0
- data/ext/lemon-1.3.1/lemon/bits/vector_map.h +244 -0
- data/ext/lemon-1.3.1/lemon/bits/windows.cc +166 -0
- data/ext/lemon-1.3.1/lemon/bits/windows.h +44 -0
- data/ext/lemon-1.3.1/lemon/bucket_heap.h +594 -0
- data/ext/lemon-1.3.1/lemon/capacity_scaling.h +1014 -0
- data/ext/lemon-1.3.1/lemon/cbc.cc +460 -0
- data/ext/lemon-1.3.1/lemon/cbc.h +129 -0
- data/ext/lemon-1.3.1/lemon/christofides_tsp.h +254 -0
- data/ext/lemon-1.3.1/lemon/circulation.h +807 -0
- data/ext/lemon-1.3.1/lemon/clp.cc +464 -0
- data/ext/lemon-1.3.1/lemon/clp.h +164 -0
- data/ext/lemon-1.3.1/lemon/color.cc +44 -0
- data/ext/lemon-1.3.1/lemon/color.h +204 -0
- data/ext/lemon-1.3.1/lemon/concept_check.h +77 -0
- data/ext/lemon-1.3.1/lemon/concepts/bpgraph.h +1029 -0
- data/ext/lemon-1.3.1/lemon/concepts/digraph.h +491 -0
- data/ext/lemon-1.3.1/lemon/concepts/graph.h +788 -0
- data/ext/lemon-1.3.1/lemon/concepts/graph_components.h +2134 -0
- data/ext/lemon-1.3.1/lemon/concepts/heap.h +324 -0
- data/ext/lemon-1.3.1/lemon/concepts/maps.h +223 -0
- data/ext/lemon-1.3.1/lemon/concepts/path.h +312 -0
- data/ext/lemon-1.3.1/lemon/config.h.in +22 -0
- data/ext/lemon-1.3.1/lemon/connectivity.h +1688 -0
- data/ext/lemon-1.3.1/lemon/core.h +2506 -0
- data/ext/lemon-1.3.1/lemon/cost_scaling.h +1607 -0
- data/ext/lemon-1.3.1/lemon/counter.h +249 -0
- data/ext/lemon-1.3.1/lemon/cplex.cc +994 -0
- data/ext/lemon-1.3.1/lemon/cplex.h +292 -0
- data/ext/lemon-1.3.1/lemon/cycle_canceling.h +1230 -0
- data/ext/lemon-1.3.1/lemon/dfs.h +1637 -0
- data/ext/lemon-1.3.1/lemon/dheap.h +352 -0
- data/ext/lemon-1.3.1/lemon/dijkstra.h +1303 -0
- data/ext/lemon-1.3.1/lemon/dim2.h +726 -0
- data/ext/lemon-1.3.1/lemon/dimacs.h +448 -0
- data/ext/lemon-1.3.1/lemon/edge_set.h +1420 -0
- data/ext/lemon-1.3.1/lemon/edmonds_karp.h +556 -0
- data/ext/lemon-1.3.1/lemon/elevator.h +982 -0
- data/ext/lemon-1.3.1/lemon/error.h +276 -0
- data/ext/lemon-1.3.1/lemon/euler.h +287 -0
- data/ext/lemon-1.3.1/lemon/fib_heap.h +475 -0
- data/ext/lemon-1.3.1/lemon/fractional_matching.h +2139 -0
- data/ext/lemon-1.3.1/lemon/full_graph.h +1082 -0
- data/ext/lemon-1.3.1/lemon/glpk.cc +1012 -0
- data/ext/lemon-1.3.1/lemon/glpk.h +263 -0
- data/ext/lemon-1.3.1/lemon/gomory_hu.h +568 -0
- data/ext/lemon-1.3.1/lemon/graph_to_eps.h +1186 -0
- data/ext/lemon-1.3.1/lemon/greedy_tsp.h +251 -0
- data/ext/lemon-1.3.1/lemon/grid_graph.h +699 -0
- data/ext/lemon-1.3.1/lemon/grosso_locatelli_pullan_mc.h +840 -0
- data/ext/lemon-1.3.1/lemon/hao_orlin.h +1015 -0
- data/ext/lemon-1.3.1/lemon/hartmann_orlin_mmc.h +654 -0
- data/ext/lemon-1.3.1/lemon/howard_mmc.h +651 -0
- data/ext/lemon-1.3.1/lemon/hypercube_graph.h +459 -0
- data/ext/lemon-1.3.1/lemon/insertion_tsp.h +533 -0
- data/ext/lemon-1.3.1/lemon/karp_mmc.h +590 -0
- data/ext/lemon-1.3.1/lemon/kruskal.h +324 -0
- data/ext/lemon-1.3.1/lemon/lemon.pc.in +10 -0
- data/ext/lemon-1.3.1/lemon/lgf_reader.h +3854 -0
- data/ext/lemon-1.3.1/lemon/lgf_writer.h +2687 -0
- data/ext/lemon-1.3.1/lemon/list_graph.h +2510 -0
- data/ext/lemon-1.3.1/lemon/lp.h +95 -0
- data/ext/lemon-1.3.1/lemon/lp_base.cc +30 -0
- data/ext/lemon-1.3.1/lemon/lp_base.h +2147 -0
- data/ext/lemon-1.3.1/lemon/lp_skeleton.cc +143 -0
- data/ext/lemon-1.3.1/lemon/lp_skeleton.h +234 -0
- data/ext/lemon-1.3.1/lemon/maps.h +4057 -0
- data/ext/lemon-1.3.1/lemon/matching.h +3505 -0
- data/ext/lemon-1.3.1/lemon/math.h +77 -0
- data/ext/lemon-1.3.1/lemon/max_cardinality_search.h +794 -0
- data/ext/lemon-1.3.1/lemon/min_cost_arborescence.h +808 -0
- data/ext/lemon-1.3.1/lemon/nagamochi_ibaraki.h +702 -0
- data/ext/lemon-1.3.1/lemon/nauty_reader.h +113 -0
- data/ext/lemon-1.3.1/lemon/nearest_neighbor_tsp.h +238 -0
- data/ext/lemon-1.3.1/lemon/network_simplex.h +1659 -0
- data/ext/lemon-1.3.1/lemon/opt2_tsp.h +367 -0
- data/ext/lemon-1.3.1/lemon/pairing_heap.h +474 -0
- data/ext/lemon-1.3.1/lemon/path.h +1164 -0
- data/ext/lemon-1.3.1/lemon/planarity.h +2754 -0
- data/ext/lemon-1.3.1/lemon/preflow.h +985 -0
- data/ext/lemon-1.3.1/lemon/quad_heap.h +343 -0
- data/ext/lemon-1.3.1/lemon/radix_heap.h +438 -0
- data/ext/lemon-1.3.1/lemon/radix_sort.h +487 -0
- data/ext/lemon-1.3.1/lemon/random.cc +29 -0
- data/ext/lemon-1.3.1/lemon/random.h +1005 -0
- data/ext/lemon-1.3.1/lemon/smart_graph.h +1344 -0
- data/ext/lemon-1.3.1/lemon/soplex.cc +465 -0
- data/ext/lemon-1.3.1/lemon/soplex.h +158 -0
- data/ext/lemon-1.3.1/lemon/static_graph.h +476 -0
- data/ext/lemon-1.3.1/lemon/suurballe.h +776 -0
- data/ext/lemon-1.3.1/lemon/time_measure.h +610 -0
- data/ext/lemon-1.3.1/lemon/tolerance.h +242 -0
- data/ext/lemon-1.3.1/lemon/unionfind.h +1824 -0
- data/ext/lemon-1.3.1/scripts/unify-sources.sh +390 -0
- data/ext/lemon-1.3.1/scripts/valgrind-wrapper.sh +22 -0
- data/ext/lemongraph/arc_map.cc +1007 -0
- data/ext/lemongraph/digraph.cc +282 -0
- data/ext/lemongraph/digraph_arc.cc +153 -0
- data/ext/lemongraph/digraph_node.cc +277 -0
- data/ext/lemongraph/edge_map.cc +770 -0
- data/ext/lemongraph/extconf.rb +53 -0
- data/ext/lemongraph/graph.cc +351 -0
- data/ext/lemongraph/graph_arc.cc +95 -0
- data/ext/lemongraph/graph_edge.cc +153 -0
- data/ext/lemongraph/graph_item.cc +76 -0
- data/ext/lemongraph/graph_node.cc +321 -0
- data/ext/lemongraph/lemongraph.cc +260 -0
- data/ext/lemongraph/lemongraph.hh +295 -0
- data/ext/lemongraph/lemongraph.map +6 -0
- data/ext/lemongraph/lemongraph_export.hh +31 -0
- data/ext/lemongraph/node_map.cc +1011 -0
- data/lemongraph.gemspec +176 -0
- data/lib/lemongraph/graphviz.rb +240 -0
- data/lib/lemongraph/version.rb +4 -0
- data/lib/lemongraph.rb +21 -0
- data/samples/lemondeps.rb +38 -0
- metadata +202 -0
|
@@ -0,0 +1,699 @@
|
|
|
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-2009
|
|
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 <lemon/core.h>
|
|
23
|
+
#include <lemon/bits/graph_extender.h>
|
|
24
|
+
#include <lemon/dim2.h>
|
|
25
|
+
#include <lemon/assert.h>
|
|
26
|
+
|
|
27
|
+
///\ingroup graphs
|
|
28
|
+
///\file
|
|
29
|
+
///\brief GridGraph class.
|
|
30
|
+
|
|
31
|
+
namespace lemon {
|
|
32
|
+
|
|
33
|
+
class GridGraphBase {
|
|
34
|
+
|
|
35
|
+
public:
|
|
36
|
+
|
|
37
|
+
typedef GridGraphBase Graph;
|
|
38
|
+
|
|
39
|
+
class Node;
|
|
40
|
+
class Edge;
|
|
41
|
+
class Arc;
|
|
42
|
+
|
|
43
|
+
public:
|
|
44
|
+
|
|
45
|
+
GridGraphBase() {}
|
|
46
|
+
|
|
47
|
+
protected:
|
|
48
|
+
|
|
49
|
+
void construct(int width, int height) {
|
|
50
|
+
_width = width; _height = height;
|
|
51
|
+
_node_num = width * height;
|
|
52
|
+
_edge_num = 2 * _node_num - width - height;
|
|
53
|
+
_edge_limit = _node_num - _width;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
public:
|
|
57
|
+
|
|
58
|
+
Node operator()(int i, int j) const {
|
|
59
|
+
LEMON_DEBUG(0 <= i && i < _width &&
|
|
60
|
+
0 <= j && j < _height, "Index out of range");
|
|
61
|
+
return Node(i + j * _width);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
int col(Node n) const {
|
|
65
|
+
return n._id % _width;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
int row(Node n) const {
|
|
69
|
+
return n._id / _width;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
dim2::Point<int> pos(Node n) const {
|
|
73
|
+
return dim2::Point<int>(col(n), row(n));
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
int width() const {
|
|
77
|
+
return _width;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
int height() const {
|
|
81
|
+
return _height;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
typedef True NodeNumTag;
|
|
85
|
+
typedef True EdgeNumTag;
|
|
86
|
+
typedef True ArcNumTag;
|
|
87
|
+
|
|
88
|
+
int nodeNum() const { return _node_num; }
|
|
89
|
+
int edgeNum() const { return _edge_num; }
|
|
90
|
+
int arcNum() const { return 2 * _edge_num; }
|
|
91
|
+
|
|
92
|
+
Node u(Edge edge) const {
|
|
93
|
+
if (edge._id < _edge_limit) {
|
|
94
|
+
return edge._id;
|
|
95
|
+
} else {
|
|
96
|
+
return (edge._id - _edge_limit) % (_width - 1) +
|
|
97
|
+
(edge._id - _edge_limit) / (_width - 1) * _width;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
Node v(Edge edge) const {
|
|
102
|
+
if (edge._id < _edge_limit) {
|
|
103
|
+
return edge._id + _width;
|
|
104
|
+
} else {
|
|
105
|
+
return (edge._id - _edge_limit) % (_width - 1) +
|
|
106
|
+
(edge._id - _edge_limit) / (_width - 1) * _width + 1;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
Node source(Arc arc) const {
|
|
111
|
+
return (arc._id & 1) == 1 ? u(arc) : v(arc);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
Node target(Arc arc) const {
|
|
115
|
+
return (arc._id & 1) == 1 ? v(arc) : u(arc);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
static int id(Node node) { return node._id; }
|
|
119
|
+
static int id(Edge edge) { return edge._id; }
|
|
120
|
+
static int id(Arc arc) { return arc._id; }
|
|
121
|
+
|
|
122
|
+
int maxNodeId() const { return _node_num - 1; }
|
|
123
|
+
int maxEdgeId() const { return _edge_num - 1; }
|
|
124
|
+
int maxArcId() const { return 2 * _edge_num - 1; }
|
|
125
|
+
|
|
126
|
+
static Node nodeFromId(int id) { return Node(id);}
|
|
127
|
+
static Edge edgeFromId(int id) { return Edge(id);}
|
|
128
|
+
static Arc arcFromId(int id) { return Arc(id);}
|
|
129
|
+
|
|
130
|
+
typedef True FindEdgeTag;
|
|
131
|
+
typedef True FindArcTag;
|
|
132
|
+
|
|
133
|
+
Edge findEdge(Node u, Node v, Edge prev = INVALID) const {
|
|
134
|
+
if (prev != INVALID) return INVALID;
|
|
135
|
+
if (v._id > u._id) {
|
|
136
|
+
if (v._id - u._id == _width)
|
|
137
|
+
return Edge(u._id);
|
|
138
|
+
if (v._id - u._id == 1 && u._id % _width < _width - 1) {
|
|
139
|
+
return Edge(u._id / _width * (_width - 1) +
|
|
140
|
+
u._id % _width + _edge_limit);
|
|
141
|
+
}
|
|
142
|
+
} else {
|
|
143
|
+
if (u._id - v._id == _width)
|
|
144
|
+
return Edge(v._id);
|
|
145
|
+
if (u._id - v._id == 1 && v._id % _width < _width - 1) {
|
|
146
|
+
return Edge(v._id / _width * (_width - 1) +
|
|
147
|
+
v._id % _width + _edge_limit);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return INVALID;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
Arc findArc(Node u, Node v, Arc prev = INVALID) const {
|
|
154
|
+
if (prev != INVALID) return INVALID;
|
|
155
|
+
if (v._id > u._id) {
|
|
156
|
+
if (v._id - u._id == _width)
|
|
157
|
+
return Arc((u._id << 1) | 1);
|
|
158
|
+
if (v._id - u._id == 1 && u._id % _width < _width - 1) {
|
|
159
|
+
return Arc(((u._id / _width * (_width - 1) +
|
|
160
|
+
u._id % _width + _edge_limit) << 1) | 1);
|
|
161
|
+
}
|
|
162
|
+
} else {
|
|
163
|
+
if (u._id - v._id == _width)
|
|
164
|
+
return Arc(v._id << 1);
|
|
165
|
+
if (u._id - v._id == 1 && v._id % _width < _width - 1) {
|
|
166
|
+
return Arc((v._id / _width * (_width - 1) +
|
|
167
|
+
v._id % _width + _edge_limit) << 1);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return INVALID;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
class Node {
|
|
174
|
+
friend class GridGraphBase;
|
|
175
|
+
|
|
176
|
+
protected:
|
|
177
|
+
int _id;
|
|
178
|
+
Node(int id) : _id(id) {}
|
|
179
|
+
public:
|
|
180
|
+
Node() {}
|
|
181
|
+
Node (Invalid) : _id(-1) {}
|
|
182
|
+
bool operator==(const Node node) const {return _id == node._id;}
|
|
183
|
+
bool operator!=(const Node node) const {return _id != node._id;}
|
|
184
|
+
bool operator<(const Node node) const {return _id < node._id;}
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
class Edge {
|
|
188
|
+
friend class GridGraphBase;
|
|
189
|
+
friend class Arc;
|
|
190
|
+
|
|
191
|
+
protected:
|
|
192
|
+
int _id;
|
|
193
|
+
|
|
194
|
+
Edge(int id) : _id(id) {}
|
|
195
|
+
|
|
196
|
+
public:
|
|
197
|
+
Edge() {}
|
|
198
|
+
Edge (Invalid) : _id(-1) {}
|
|
199
|
+
bool operator==(const Edge edge) const {return _id == edge._id;}
|
|
200
|
+
bool operator!=(const Edge edge) const {return _id != edge._id;}
|
|
201
|
+
bool operator<(const Edge edge) const {return _id < edge._id;}
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
class Arc {
|
|
205
|
+
friend class GridGraphBase;
|
|
206
|
+
|
|
207
|
+
protected:
|
|
208
|
+
int _id;
|
|
209
|
+
|
|
210
|
+
Arc(int id) : _id(id) {}
|
|
211
|
+
|
|
212
|
+
public:
|
|
213
|
+
Arc() {}
|
|
214
|
+
Arc (Invalid) : _id(-1) {}
|
|
215
|
+
operator Edge() const { return _id != -1 ? Edge(_id >> 1) : INVALID; }
|
|
216
|
+
bool operator==(const Arc arc) const {return _id == arc._id;}
|
|
217
|
+
bool operator!=(const Arc arc) const {return _id != arc._id;}
|
|
218
|
+
bool operator<(const Arc arc) const {return _id < arc._id;}
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
static bool direction(Arc arc) {
|
|
222
|
+
return (arc._id & 1) == 1;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
static Arc direct(Edge edge, bool dir) {
|
|
226
|
+
return Arc((edge._id << 1) | (dir ? 1 : 0));
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
void first(Node& node) const {
|
|
230
|
+
node._id = _node_num - 1;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
static void next(Node& node) {
|
|
234
|
+
--node._id;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
void first(Edge& edge) const {
|
|
238
|
+
edge._id = _edge_num - 1;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
static void next(Edge& edge) {
|
|
242
|
+
--edge._id;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
void first(Arc& arc) const {
|
|
246
|
+
arc._id = 2 * _edge_num - 1;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
static void next(Arc& arc) {
|
|
250
|
+
--arc._id;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
void firstOut(Arc& arc, const Node& node) const {
|
|
254
|
+
if (node._id % _width < _width - 1) {
|
|
255
|
+
arc._id = (_edge_limit + node._id % _width +
|
|
256
|
+
(node._id / _width) * (_width - 1)) << 1 | 1;
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
if (node._id < _node_num - _width) {
|
|
260
|
+
arc._id = node._id << 1 | 1;
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
if (node._id % _width > 0) {
|
|
264
|
+
arc._id = (_edge_limit + node._id % _width +
|
|
265
|
+
(node._id / _width) * (_width - 1) - 1) << 1;
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
if (node._id >= _width) {
|
|
269
|
+
arc._id = (node._id - _width) << 1;
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
arc._id = -1;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
void nextOut(Arc& arc) const {
|
|
276
|
+
int nid = arc._id >> 1;
|
|
277
|
+
if ((arc._id & 1) == 1) {
|
|
278
|
+
if (nid >= _edge_limit) {
|
|
279
|
+
nid = (nid - _edge_limit) % (_width - 1) +
|
|
280
|
+
(nid - _edge_limit) / (_width - 1) * _width;
|
|
281
|
+
if (nid < _node_num - _width) {
|
|
282
|
+
arc._id = nid << 1 | 1;
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
if (nid % _width > 0) {
|
|
287
|
+
arc._id = (_edge_limit + nid % _width +
|
|
288
|
+
(nid / _width) * (_width - 1) - 1) << 1;
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
if (nid >= _width) {
|
|
292
|
+
arc._id = (nid - _width) << 1;
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
} else {
|
|
296
|
+
if (nid >= _edge_limit) {
|
|
297
|
+
nid = (nid - _edge_limit) % (_width - 1) +
|
|
298
|
+
(nid - _edge_limit) / (_width - 1) * _width + 1;
|
|
299
|
+
if (nid >= _width) {
|
|
300
|
+
arc._id = (nid - _width) << 1;
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
arc._id = -1;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
void firstIn(Arc& arc, const Node& node) const {
|
|
309
|
+
if (node._id % _width < _width - 1) {
|
|
310
|
+
arc._id = (_edge_limit + node._id % _width +
|
|
311
|
+
(node._id / _width) * (_width - 1)) << 1;
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
if (node._id < _node_num - _width) {
|
|
315
|
+
arc._id = node._id << 1;
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
if (node._id % _width > 0) {
|
|
319
|
+
arc._id = (_edge_limit + node._id % _width +
|
|
320
|
+
(node._id / _width) * (_width - 1) - 1) << 1 | 1;
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
if (node._id >= _width) {
|
|
324
|
+
arc._id = (node._id - _width) << 1 | 1;
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
arc._id = -1;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
void nextIn(Arc& arc) const {
|
|
331
|
+
int nid = arc._id >> 1;
|
|
332
|
+
if ((arc._id & 1) == 0) {
|
|
333
|
+
if (nid >= _edge_limit) {
|
|
334
|
+
nid = (nid - _edge_limit) % (_width - 1) +
|
|
335
|
+
(nid - _edge_limit) / (_width - 1) * _width;
|
|
336
|
+
if (nid < _node_num - _width) {
|
|
337
|
+
arc._id = nid << 1;
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
if (nid % _width > 0) {
|
|
342
|
+
arc._id = (_edge_limit + nid % _width +
|
|
343
|
+
(nid / _width) * (_width - 1) - 1) << 1 | 1;
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
if (nid >= _width) {
|
|
347
|
+
arc._id = (nid - _width) << 1 | 1;
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
350
|
+
} else {
|
|
351
|
+
if (nid >= _edge_limit) {
|
|
352
|
+
nid = (nid - _edge_limit) % (_width - 1) +
|
|
353
|
+
(nid - _edge_limit) / (_width - 1) * _width + 1;
|
|
354
|
+
if (nid >= _width) {
|
|
355
|
+
arc._id = (nid - _width) << 1 | 1;
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
arc._id = -1;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
void firstInc(Edge& edge, bool& dir, const Node& node) const {
|
|
364
|
+
if (node._id % _width < _width - 1) {
|
|
365
|
+
edge._id = _edge_limit + node._id % _width +
|
|
366
|
+
(node._id / _width) * (_width - 1);
|
|
367
|
+
dir = true;
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
if (node._id < _node_num - _width) {
|
|
371
|
+
edge._id = node._id;
|
|
372
|
+
dir = true;
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
375
|
+
if (node._id % _width > 0) {
|
|
376
|
+
edge._id = _edge_limit + node._id % _width +
|
|
377
|
+
(node._id / _width) * (_width - 1) - 1;
|
|
378
|
+
dir = false;
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
if (node._id >= _width) {
|
|
382
|
+
edge._id = node._id - _width;
|
|
383
|
+
dir = false;
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
386
|
+
edge._id = -1;
|
|
387
|
+
dir = true;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
void nextInc(Edge& edge, bool& dir) const {
|
|
391
|
+
int nid = edge._id;
|
|
392
|
+
if (dir) {
|
|
393
|
+
if (nid >= _edge_limit) {
|
|
394
|
+
nid = (nid - _edge_limit) % (_width - 1) +
|
|
395
|
+
(nid - _edge_limit) / (_width - 1) * _width;
|
|
396
|
+
if (nid < _node_num - _width) {
|
|
397
|
+
edge._id = nid;
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
if (nid % _width > 0) {
|
|
402
|
+
edge._id = _edge_limit + nid % _width +
|
|
403
|
+
(nid / _width) * (_width - 1) - 1;
|
|
404
|
+
dir = false;
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
if (nid >= _width) {
|
|
408
|
+
edge._id = nid - _width;
|
|
409
|
+
dir = false;
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
412
|
+
} else {
|
|
413
|
+
if (nid >= _edge_limit) {
|
|
414
|
+
nid = (nid - _edge_limit) % (_width - 1) +
|
|
415
|
+
(nid - _edge_limit) / (_width - 1) * _width + 1;
|
|
416
|
+
if (nid >= _width) {
|
|
417
|
+
edge._id = nid - _width;
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
edge._id = -1;
|
|
423
|
+
dir = true;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
Arc right(Node n) const {
|
|
427
|
+
if (n._id % _width < _width - 1) {
|
|
428
|
+
return Arc(((_edge_limit + n._id % _width +
|
|
429
|
+
(n._id / _width) * (_width - 1)) << 1) | 1);
|
|
430
|
+
} else {
|
|
431
|
+
return INVALID;
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
Arc left(Node n) const {
|
|
436
|
+
if (n._id % _width > 0) {
|
|
437
|
+
return Arc((_edge_limit + n._id % _width +
|
|
438
|
+
(n._id / _width) * (_width - 1) - 1) << 1);
|
|
439
|
+
} else {
|
|
440
|
+
return INVALID;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
Arc up(Node n) const {
|
|
445
|
+
if (n._id < _edge_limit) {
|
|
446
|
+
return Arc((n._id << 1) | 1);
|
|
447
|
+
} else {
|
|
448
|
+
return INVALID;
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
Arc down(Node n) const {
|
|
453
|
+
if (n._id >= _width) {
|
|
454
|
+
return Arc((n._id - _width) << 1);
|
|
455
|
+
} else {
|
|
456
|
+
return INVALID;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
private:
|
|
461
|
+
int _width, _height;
|
|
462
|
+
int _node_num, _edge_num;
|
|
463
|
+
int _edge_limit;
|
|
464
|
+
};
|
|
465
|
+
|
|
466
|
+
|
|
467
|
+
typedef GraphExtender<GridGraphBase> ExtendedGridGraphBase;
|
|
468
|
+
|
|
469
|
+
/// \ingroup graphs
|
|
470
|
+
///
|
|
471
|
+
/// \brief Grid graph class
|
|
472
|
+
///
|
|
473
|
+
/// GridGraph implements a special graph type. The nodes of the
|
|
474
|
+
/// graph can be indexed by two integer values \c (i,j) where \c i is
|
|
475
|
+
/// in the range <tt>[0..width()-1]</tt> and j is in the range
|
|
476
|
+
/// <tt>[0..height()-1]</tt>. Two nodes are connected in the graph if
|
|
477
|
+
/// the indices differ exactly on one position and the difference is
|
|
478
|
+
/// also exactly one. The nodes of the graph can be obtained by position
|
|
479
|
+
/// using the \c operator()() function and the indices of the nodes can
|
|
480
|
+
/// be obtained using \c pos(), \c col() and \c row() members. The outgoing
|
|
481
|
+
/// arcs can be retrieved with the \c right(), \c up(), \c left()
|
|
482
|
+
/// and \c down() functions, where the bottom-left corner is the
|
|
483
|
+
/// origin.
|
|
484
|
+
///
|
|
485
|
+
/// This class is completely static and it needs constant memory space.
|
|
486
|
+
/// Thus you can neither add nor delete nodes or edges, however
|
|
487
|
+
/// the structure can be resized using resize().
|
|
488
|
+
///
|
|
489
|
+
/// \image html grid_graph.png
|
|
490
|
+
/// \image latex grid_graph.eps "Grid graph" width=\textwidth
|
|
491
|
+
///
|
|
492
|
+
/// A short example about the basic usage:
|
|
493
|
+
///\code
|
|
494
|
+
/// GridGraph graph(rows, cols);
|
|
495
|
+
/// GridGraph::NodeMap<int> val(graph);
|
|
496
|
+
/// for (int i = 0; i < graph.width(); ++i) {
|
|
497
|
+
/// for (int j = 0; j < graph.height(); ++j) {
|
|
498
|
+
/// val[graph(i, j)] = i + j;
|
|
499
|
+
/// }
|
|
500
|
+
/// }
|
|
501
|
+
///\endcode
|
|
502
|
+
///
|
|
503
|
+
/// This type fully conforms to the \ref concepts::Graph "Graph concept".
|
|
504
|
+
/// Most of its member functions and nested classes are documented
|
|
505
|
+
/// only in the concept class.
|
|
506
|
+
///
|
|
507
|
+
/// This class provides constant time counting for nodes, edges and arcs.
|
|
508
|
+
class GridGraph : public ExtendedGridGraphBase {
|
|
509
|
+
typedef ExtendedGridGraphBase Parent;
|
|
510
|
+
|
|
511
|
+
public:
|
|
512
|
+
|
|
513
|
+
/// \brief Map to get the indices of the nodes as \ref dim2::Point
|
|
514
|
+
/// "dim2::Point<int>".
|
|
515
|
+
///
|
|
516
|
+
/// Map to get the indices of the nodes as \ref dim2::Point
|
|
517
|
+
/// "dim2::Point<int>".
|
|
518
|
+
class IndexMap {
|
|
519
|
+
public:
|
|
520
|
+
/// \brief The key type of the map
|
|
521
|
+
typedef GridGraph::Node Key;
|
|
522
|
+
/// \brief The value type of the map
|
|
523
|
+
typedef dim2::Point<int> Value;
|
|
524
|
+
|
|
525
|
+
/// \brief Constructor
|
|
526
|
+
IndexMap(const GridGraph& graph) : _graph(graph) {}
|
|
527
|
+
|
|
528
|
+
/// \brief The subscript operator
|
|
529
|
+
Value operator[](Key key) const {
|
|
530
|
+
return _graph.pos(key);
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
private:
|
|
534
|
+
const GridGraph& _graph;
|
|
535
|
+
};
|
|
536
|
+
|
|
537
|
+
/// \brief Map to get the column of the nodes.
|
|
538
|
+
///
|
|
539
|
+
/// Map to get the column of the nodes.
|
|
540
|
+
class ColMap {
|
|
541
|
+
public:
|
|
542
|
+
/// \brief The key type of the map
|
|
543
|
+
typedef GridGraph::Node Key;
|
|
544
|
+
/// \brief The value type of the map
|
|
545
|
+
typedef int Value;
|
|
546
|
+
|
|
547
|
+
/// \brief Constructor
|
|
548
|
+
ColMap(const GridGraph& graph) : _graph(graph) {}
|
|
549
|
+
|
|
550
|
+
/// \brief The subscript operator
|
|
551
|
+
Value operator[](Key key) const {
|
|
552
|
+
return _graph.col(key);
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
private:
|
|
556
|
+
const GridGraph& _graph;
|
|
557
|
+
};
|
|
558
|
+
|
|
559
|
+
/// \brief Map to get the row of the nodes.
|
|
560
|
+
///
|
|
561
|
+
/// Map to get the row of the nodes.
|
|
562
|
+
class RowMap {
|
|
563
|
+
public:
|
|
564
|
+
/// \brief The key type of the map
|
|
565
|
+
typedef GridGraph::Node Key;
|
|
566
|
+
/// \brief The value type of the map
|
|
567
|
+
typedef int Value;
|
|
568
|
+
|
|
569
|
+
/// \brief Constructor
|
|
570
|
+
RowMap(const GridGraph& graph) : _graph(graph) {}
|
|
571
|
+
|
|
572
|
+
/// \brief The subscript operator
|
|
573
|
+
Value operator[](Key key) const {
|
|
574
|
+
return _graph.row(key);
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
private:
|
|
578
|
+
const GridGraph& _graph;
|
|
579
|
+
};
|
|
580
|
+
|
|
581
|
+
/// \brief Constructor
|
|
582
|
+
///
|
|
583
|
+
/// Construct a grid graph with the given size.
|
|
584
|
+
GridGraph(int width, int height) { construct(width, height); }
|
|
585
|
+
|
|
586
|
+
/// \brief Resizes the graph
|
|
587
|
+
///
|
|
588
|
+
/// This function resizes the graph. It fully destroys and
|
|
589
|
+
/// rebuilds the structure, therefore the maps of the graph will be
|
|
590
|
+
/// reallocated automatically and the previous values will be lost.
|
|
591
|
+
void resize(int width, int height) {
|
|
592
|
+
Parent::notifier(Arc()).clear();
|
|
593
|
+
Parent::notifier(Edge()).clear();
|
|
594
|
+
Parent::notifier(Node()).clear();
|
|
595
|
+
construct(width, height);
|
|
596
|
+
Parent::notifier(Node()).build();
|
|
597
|
+
Parent::notifier(Edge()).build();
|
|
598
|
+
Parent::notifier(Arc()).build();
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
/// \brief The node on the given position.
|
|
602
|
+
///
|
|
603
|
+
/// Gives back the node on the given position.
|
|
604
|
+
Node operator()(int i, int j) const {
|
|
605
|
+
return Parent::operator()(i, j);
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
/// \brief The column index of the node.
|
|
609
|
+
///
|
|
610
|
+
/// Gives back the column index of the node.
|
|
611
|
+
int col(Node n) const {
|
|
612
|
+
return Parent::col(n);
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
/// \brief The row index of the node.
|
|
616
|
+
///
|
|
617
|
+
/// Gives back the row index of the node.
|
|
618
|
+
int row(Node n) const {
|
|
619
|
+
return Parent::row(n);
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
/// \brief The position of the node.
|
|
623
|
+
///
|
|
624
|
+
/// Gives back the position of the node, ie. the <tt>(col,row)</tt> pair.
|
|
625
|
+
dim2::Point<int> pos(Node n) const {
|
|
626
|
+
return Parent::pos(n);
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
/// \brief The number of the columns.
|
|
630
|
+
///
|
|
631
|
+
/// Gives back the number of the columns.
|
|
632
|
+
int width() const {
|
|
633
|
+
return Parent::width();
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
/// \brief The number of the rows.
|
|
637
|
+
///
|
|
638
|
+
/// Gives back the number of the rows.
|
|
639
|
+
int height() const {
|
|
640
|
+
return Parent::height();
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
/// \brief The arc goes right from the node.
|
|
644
|
+
///
|
|
645
|
+
/// Gives back the arc goes right from the node. If there is not
|
|
646
|
+
/// outgoing arc then it gives back INVALID.
|
|
647
|
+
Arc right(Node n) const {
|
|
648
|
+
return Parent::right(n);
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
/// \brief The arc goes left from the node.
|
|
652
|
+
///
|
|
653
|
+
/// Gives back the arc goes left from the node. If there is not
|
|
654
|
+
/// outgoing arc then it gives back INVALID.
|
|
655
|
+
Arc left(Node n) const {
|
|
656
|
+
return Parent::left(n);
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
/// \brief The arc goes up from the node.
|
|
660
|
+
///
|
|
661
|
+
/// Gives back the arc goes up from the node. If there is not
|
|
662
|
+
/// outgoing arc then it gives back INVALID.
|
|
663
|
+
Arc up(Node n) const {
|
|
664
|
+
return Parent::up(n);
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
/// \brief The arc goes down from the node.
|
|
668
|
+
///
|
|
669
|
+
/// Gives back the arc goes down from the node. If there is not
|
|
670
|
+
/// outgoing arc then it gives back INVALID.
|
|
671
|
+
Arc down(Node n) const {
|
|
672
|
+
return Parent::down(n);
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
/// \brief Index map of the grid graph
|
|
676
|
+
///
|
|
677
|
+
/// Just returns an IndexMap for the grid graph.
|
|
678
|
+
IndexMap indexMap() const {
|
|
679
|
+
return IndexMap(*this);
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
/// \brief Row map of the grid graph
|
|
683
|
+
///
|
|
684
|
+
/// Just returns a RowMap for the grid graph.
|
|
685
|
+
RowMap rowMap() const {
|
|
686
|
+
return RowMap(*this);
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
/// \brief Column map of the grid graph
|
|
690
|
+
///
|
|
691
|
+
/// Just returns a ColMap for the grid graph.
|
|
692
|
+
ColMap colMap() const {
|
|
693
|
+
return ColMap(*this);
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
};
|
|
697
|
+
|
|
698
|
+
}
|
|
699
|
+
#endif
|