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,1082 @@
|
|
|
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-2013
|
|
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 LEMON_FULL_GRAPH_H
|
|
20
|
+
#define LEMON_FULL_GRAPH_H
|
|
21
|
+
|
|
22
|
+
#include <lemon/core.h>
|
|
23
|
+
#include <lemon/bits/graph_extender.h>
|
|
24
|
+
|
|
25
|
+
///\ingroup graphs
|
|
26
|
+
///\file
|
|
27
|
+
///\brief FullDigraph and FullGraph classes.
|
|
28
|
+
|
|
29
|
+
namespace lemon {
|
|
30
|
+
|
|
31
|
+
class FullDigraphBase {
|
|
32
|
+
public:
|
|
33
|
+
|
|
34
|
+
typedef FullDigraphBase Digraph;
|
|
35
|
+
|
|
36
|
+
class Node;
|
|
37
|
+
class Arc;
|
|
38
|
+
|
|
39
|
+
protected:
|
|
40
|
+
|
|
41
|
+
int _node_num;
|
|
42
|
+
int _arc_num;
|
|
43
|
+
|
|
44
|
+
FullDigraphBase() {}
|
|
45
|
+
|
|
46
|
+
void construct(int n) { _node_num = n; _arc_num = n * n; }
|
|
47
|
+
|
|
48
|
+
public:
|
|
49
|
+
|
|
50
|
+
typedef True NodeNumTag;
|
|
51
|
+
typedef True ArcNumTag;
|
|
52
|
+
|
|
53
|
+
Node operator()(int ix) const { return Node(ix); }
|
|
54
|
+
static int index(const Node& node) { return node._id; }
|
|
55
|
+
|
|
56
|
+
Arc arc(const Node& s, const Node& t) const {
|
|
57
|
+
return Arc(s._id * _node_num + t._id);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
int nodeNum() const { return _node_num; }
|
|
61
|
+
int arcNum() const { return _arc_num; }
|
|
62
|
+
|
|
63
|
+
int maxNodeId() const { return _node_num - 1; }
|
|
64
|
+
int maxArcId() const { return _arc_num - 1; }
|
|
65
|
+
|
|
66
|
+
Node source(Arc arc) const { return arc._id / _node_num; }
|
|
67
|
+
Node target(Arc arc) const { return arc._id % _node_num; }
|
|
68
|
+
|
|
69
|
+
static int id(Node node) { return node._id; }
|
|
70
|
+
static int id(Arc arc) { return arc._id; }
|
|
71
|
+
|
|
72
|
+
static Node nodeFromId(int id) { return Node(id);}
|
|
73
|
+
static Arc arcFromId(int id) { return Arc(id);}
|
|
74
|
+
|
|
75
|
+
typedef True FindArcTag;
|
|
76
|
+
|
|
77
|
+
Arc findArc(Node s, Node t, Arc prev = INVALID) const {
|
|
78
|
+
return prev == INVALID ? arc(s, t) : INVALID;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
class Node {
|
|
82
|
+
friend class FullDigraphBase;
|
|
83
|
+
|
|
84
|
+
protected:
|
|
85
|
+
int _id;
|
|
86
|
+
Node(int id) : _id(id) {}
|
|
87
|
+
public:
|
|
88
|
+
Node() {}
|
|
89
|
+
Node (Invalid) : _id(-1) {}
|
|
90
|
+
bool operator==(const Node node) const {return _id == node._id;}
|
|
91
|
+
bool operator!=(const Node node) const {return _id != node._id;}
|
|
92
|
+
bool operator<(const Node node) const {return _id < node._id;}
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
class Arc {
|
|
96
|
+
friend class FullDigraphBase;
|
|
97
|
+
|
|
98
|
+
protected:
|
|
99
|
+
int _id; // _node_num * source + target;
|
|
100
|
+
|
|
101
|
+
Arc(int id) : _id(id) {}
|
|
102
|
+
|
|
103
|
+
public:
|
|
104
|
+
Arc() { }
|
|
105
|
+
Arc (Invalid) { _id = -1; }
|
|
106
|
+
bool operator==(const Arc arc) const {return _id == arc._id;}
|
|
107
|
+
bool operator!=(const Arc arc) const {return _id != arc._id;}
|
|
108
|
+
bool operator<(const Arc arc) const {return _id < arc._id;}
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
void first(Node& node) const {
|
|
112
|
+
node._id = _node_num - 1;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
static void next(Node& node) {
|
|
116
|
+
--node._id;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
void first(Arc& arc) const {
|
|
120
|
+
arc._id = _arc_num - 1;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
static void next(Arc& arc) {
|
|
124
|
+
--arc._id;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
void firstOut(Arc& arc, const Node& node) const {
|
|
128
|
+
arc._id = (node._id + 1) * _node_num - 1;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
void nextOut(Arc& arc) const {
|
|
132
|
+
if (arc._id % _node_num == 0) arc._id = 0;
|
|
133
|
+
--arc._id;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
void firstIn(Arc& arc, const Node& node) const {
|
|
137
|
+
arc._id = _arc_num + node._id - _node_num;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
void nextIn(Arc& arc) const {
|
|
141
|
+
arc._id -= _node_num;
|
|
142
|
+
if (arc._id < 0) arc._id = -1;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
typedef DigraphExtender<FullDigraphBase> ExtendedFullDigraphBase;
|
|
148
|
+
|
|
149
|
+
/// \ingroup graphs
|
|
150
|
+
///
|
|
151
|
+
/// \brief A directed full graph class.
|
|
152
|
+
///
|
|
153
|
+
/// FullDigraph is a simple and fast implmenetation of directed full
|
|
154
|
+
/// (complete) graphs. It contains an arc from each node to each node
|
|
155
|
+
/// (including a loop for each node), therefore the number of arcs
|
|
156
|
+
/// is the square of the number of nodes.
|
|
157
|
+
/// This class is completely static and it needs constant memory space.
|
|
158
|
+
/// Thus you can neither add nor delete nodes or arcs, however
|
|
159
|
+
/// the structure can be resized using resize().
|
|
160
|
+
///
|
|
161
|
+
/// This type fully conforms to the \ref concepts::Digraph "Digraph concept".
|
|
162
|
+
/// Most of its member functions and nested classes are documented
|
|
163
|
+
/// only in the concept class.
|
|
164
|
+
///
|
|
165
|
+
/// This class provides constant time counting for nodes and arcs.
|
|
166
|
+
///
|
|
167
|
+
/// \note FullDigraph and FullGraph classes are very similar,
|
|
168
|
+
/// but there are two differences. While this class conforms only
|
|
169
|
+
/// to the \ref concepts::Digraph "Digraph" concept, FullGraph
|
|
170
|
+
/// conforms to the \ref concepts::Graph "Graph" concept,
|
|
171
|
+
/// moreover FullGraph does not contain a loop for each
|
|
172
|
+
/// node as this class does.
|
|
173
|
+
///
|
|
174
|
+
/// \sa FullGraph
|
|
175
|
+
class FullDigraph : public ExtendedFullDigraphBase {
|
|
176
|
+
typedef ExtendedFullDigraphBase Parent;
|
|
177
|
+
|
|
178
|
+
public:
|
|
179
|
+
|
|
180
|
+
/// \brief Default constructor.
|
|
181
|
+
///
|
|
182
|
+
/// Default constructor. The number of nodes and arcs will be zero.
|
|
183
|
+
FullDigraph() { construct(0); }
|
|
184
|
+
|
|
185
|
+
/// \brief Constructor
|
|
186
|
+
///
|
|
187
|
+
/// Constructor.
|
|
188
|
+
/// \param n The number of the nodes.
|
|
189
|
+
FullDigraph(int n) { construct(n); }
|
|
190
|
+
|
|
191
|
+
/// \brief Resizes the digraph
|
|
192
|
+
///
|
|
193
|
+
/// This function resizes the digraph. It fully destroys and
|
|
194
|
+
/// rebuilds the structure, therefore the maps of the digraph will be
|
|
195
|
+
/// reallocated automatically and the previous values will be lost.
|
|
196
|
+
void resize(int n) {
|
|
197
|
+
Parent::notifier(Arc()).clear();
|
|
198
|
+
Parent::notifier(Node()).clear();
|
|
199
|
+
construct(n);
|
|
200
|
+
Parent::notifier(Node()).build();
|
|
201
|
+
Parent::notifier(Arc()).build();
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/// \brief Returns the node with the given index.
|
|
205
|
+
///
|
|
206
|
+
/// Returns the node with the given index. Since this structure is
|
|
207
|
+
/// completely static, the nodes can be indexed with integers from
|
|
208
|
+
/// the range <tt>[0..nodeNum()-1]</tt>.
|
|
209
|
+
/// The index of a node is the same as its ID.
|
|
210
|
+
/// \sa index()
|
|
211
|
+
Node operator()(int ix) const { return Parent::operator()(ix); }
|
|
212
|
+
|
|
213
|
+
/// \brief Returns the index of the given node.
|
|
214
|
+
///
|
|
215
|
+
/// Returns the index of the given node. Since this structure is
|
|
216
|
+
/// completely static, the nodes can be indexed with integers from
|
|
217
|
+
/// the range <tt>[0..nodeNum()-1]</tt>.
|
|
218
|
+
/// The index of a node is the same as its ID.
|
|
219
|
+
/// \sa operator()()
|
|
220
|
+
static int index(const Node& node) { return Parent::index(node); }
|
|
221
|
+
|
|
222
|
+
/// \brief Returns the arc connecting the given nodes.
|
|
223
|
+
///
|
|
224
|
+
/// Returns the arc connecting the given nodes.
|
|
225
|
+
Arc arc(Node u, Node v) const {
|
|
226
|
+
return Parent::arc(u, v);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/// \brief Number of nodes.
|
|
230
|
+
int nodeNum() const { return Parent::nodeNum(); }
|
|
231
|
+
/// \brief Number of arcs.
|
|
232
|
+
int arcNum() const { return Parent::arcNum(); }
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
class FullGraphBase {
|
|
237
|
+
public:
|
|
238
|
+
|
|
239
|
+
typedef FullGraphBase Graph;
|
|
240
|
+
|
|
241
|
+
class Node;
|
|
242
|
+
class Arc;
|
|
243
|
+
class Edge;
|
|
244
|
+
|
|
245
|
+
protected:
|
|
246
|
+
|
|
247
|
+
int _node_num;
|
|
248
|
+
int _edge_num;
|
|
249
|
+
|
|
250
|
+
FullGraphBase() {}
|
|
251
|
+
|
|
252
|
+
void construct(int n) { _node_num = n; _edge_num = n * (n - 1) / 2; }
|
|
253
|
+
|
|
254
|
+
int _uid(int e) const {
|
|
255
|
+
int u = e / _node_num;
|
|
256
|
+
int v = e % _node_num;
|
|
257
|
+
return u < v ? u : _node_num - 2 - u;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
int _vid(int e) const {
|
|
261
|
+
int u = e / _node_num;
|
|
262
|
+
int v = e % _node_num;
|
|
263
|
+
return u < v ? v : _node_num - 1 - v;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
void _uvid(int e, int& u, int& v) const {
|
|
267
|
+
u = e / _node_num;
|
|
268
|
+
v = e % _node_num;
|
|
269
|
+
if (u >= v) {
|
|
270
|
+
u = _node_num - 2 - u;
|
|
271
|
+
v = _node_num - 1 - v;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
void _stid(int a, int& s, int& t) const {
|
|
276
|
+
if ((a & 1) == 1) {
|
|
277
|
+
_uvid(a >> 1, s, t);
|
|
278
|
+
} else {
|
|
279
|
+
_uvid(a >> 1, t, s);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
int _eid(int u, int v) const {
|
|
284
|
+
if (u < (_node_num - 1) / 2) {
|
|
285
|
+
return u * _node_num + v;
|
|
286
|
+
} else {
|
|
287
|
+
return (_node_num - 1 - u) * _node_num - v - 1;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
public:
|
|
292
|
+
|
|
293
|
+
Node operator()(int ix) const { return Node(ix); }
|
|
294
|
+
static int index(const Node& node) { return node._id; }
|
|
295
|
+
|
|
296
|
+
Edge edge(const Node& u, const Node& v) const {
|
|
297
|
+
if (u._id < v._id) {
|
|
298
|
+
return Edge(_eid(u._id, v._id));
|
|
299
|
+
} else if (u._id != v._id) {
|
|
300
|
+
return Edge(_eid(v._id, u._id));
|
|
301
|
+
} else {
|
|
302
|
+
return INVALID;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
Arc arc(const Node& s, const Node& t) const {
|
|
307
|
+
if (s._id < t._id) {
|
|
308
|
+
return Arc((_eid(s._id, t._id) << 1) | 1);
|
|
309
|
+
} else if (s._id != t._id) {
|
|
310
|
+
return Arc(_eid(t._id, s._id) << 1);
|
|
311
|
+
} else {
|
|
312
|
+
return INVALID;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
typedef True NodeNumTag;
|
|
317
|
+
typedef True ArcNumTag;
|
|
318
|
+
typedef True EdgeNumTag;
|
|
319
|
+
|
|
320
|
+
int nodeNum() const { return _node_num; }
|
|
321
|
+
int arcNum() const { return 2 * _edge_num; }
|
|
322
|
+
int edgeNum() const { return _edge_num; }
|
|
323
|
+
|
|
324
|
+
static int id(Node node) { return node._id; }
|
|
325
|
+
static int id(Arc arc) { return arc._id; }
|
|
326
|
+
static int id(Edge edge) { return edge._id; }
|
|
327
|
+
|
|
328
|
+
int maxNodeId() const { return _node_num-1; }
|
|
329
|
+
int maxArcId() const { return 2 * _edge_num-1; }
|
|
330
|
+
int maxEdgeId() const { return _edge_num-1; }
|
|
331
|
+
|
|
332
|
+
static Node nodeFromId(int id) { return Node(id);}
|
|
333
|
+
static Arc arcFromId(int id) { return Arc(id);}
|
|
334
|
+
static Edge edgeFromId(int id) { return Edge(id);}
|
|
335
|
+
|
|
336
|
+
Node u(Edge edge) const {
|
|
337
|
+
return Node(_uid(edge._id));
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
Node v(Edge edge) const {
|
|
341
|
+
return Node(_vid(edge._id));
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
Node source(Arc arc) const {
|
|
345
|
+
return Node((arc._id & 1) == 1 ?
|
|
346
|
+
_uid(arc._id >> 1) : _vid(arc._id >> 1));
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
Node target(Arc arc) const {
|
|
350
|
+
return Node((arc._id & 1) == 1 ?
|
|
351
|
+
_vid(arc._id >> 1) : _uid(arc._id >> 1));
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
typedef True FindEdgeTag;
|
|
355
|
+
typedef True FindArcTag;
|
|
356
|
+
|
|
357
|
+
Edge findEdge(Node u, Node v, Edge prev = INVALID) const {
|
|
358
|
+
return prev != INVALID ? INVALID : edge(u, v);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
Arc findArc(Node s, Node t, Arc prev = INVALID) const {
|
|
362
|
+
return prev != INVALID ? INVALID : arc(s, t);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
class Node {
|
|
366
|
+
friend class FullGraphBase;
|
|
367
|
+
|
|
368
|
+
protected:
|
|
369
|
+
int _id;
|
|
370
|
+
Node(int id) : _id(id) {}
|
|
371
|
+
public:
|
|
372
|
+
Node() {}
|
|
373
|
+
Node (Invalid) { _id = -1; }
|
|
374
|
+
bool operator==(const Node node) const {return _id == node._id;}
|
|
375
|
+
bool operator!=(const Node node) const {return _id != node._id;}
|
|
376
|
+
bool operator<(const Node node) const {return _id < node._id;}
|
|
377
|
+
};
|
|
378
|
+
|
|
379
|
+
class Edge {
|
|
380
|
+
friend class FullGraphBase;
|
|
381
|
+
friend class Arc;
|
|
382
|
+
|
|
383
|
+
protected:
|
|
384
|
+
int _id;
|
|
385
|
+
|
|
386
|
+
Edge(int id) : _id(id) {}
|
|
387
|
+
|
|
388
|
+
public:
|
|
389
|
+
Edge() { }
|
|
390
|
+
Edge (Invalid) { _id = -1; }
|
|
391
|
+
|
|
392
|
+
bool operator==(const Edge edge) const {return _id == edge._id;}
|
|
393
|
+
bool operator!=(const Edge edge) const {return _id != edge._id;}
|
|
394
|
+
bool operator<(const Edge edge) const {return _id < edge._id;}
|
|
395
|
+
};
|
|
396
|
+
|
|
397
|
+
class Arc {
|
|
398
|
+
friend class FullGraphBase;
|
|
399
|
+
|
|
400
|
+
protected:
|
|
401
|
+
int _id;
|
|
402
|
+
|
|
403
|
+
Arc(int id) : _id(id) {}
|
|
404
|
+
|
|
405
|
+
public:
|
|
406
|
+
Arc() { }
|
|
407
|
+
Arc (Invalid) { _id = -1; }
|
|
408
|
+
|
|
409
|
+
operator Edge() const { return Edge(_id != -1 ? (_id >> 1) : -1); }
|
|
410
|
+
|
|
411
|
+
bool operator==(const Arc arc) const {return _id == arc._id;}
|
|
412
|
+
bool operator!=(const Arc arc) const {return _id != arc._id;}
|
|
413
|
+
bool operator<(const Arc arc) const {return _id < arc._id;}
|
|
414
|
+
};
|
|
415
|
+
|
|
416
|
+
static bool direction(Arc arc) {
|
|
417
|
+
return (arc._id & 1) == 1;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
static Arc direct(Edge edge, bool dir) {
|
|
421
|
+
return Arc((edge._id << 1) | (dir ? 1 : 0));
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
void first(Node& node) const {
|
|
425
|
+
node._id = _node_num - 1;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
static void next(Node& node) {
|
|
429
|
+
--node._id;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
void first(Arc& arc) const {
|
|
433
|
+
arc._id = (_edge_num << 1) - 1;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
static void next(Arc& arc) {
|
|
437
|
+
--arc._id;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
void first(Edge& edge) const {
|
|
441
|
+
edge._id = _edge_num - 1;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
static void next(Edge& edge) {
|
|
445
|
+
--edge._id;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
void firstOut(Arc& arc, const Node& node) const {
|
|
449
|
+
int s = node._id, t = _node_num - 1;
|
|
450
|
+
if (s < t) {
|
|
451
|
+
arc._id = (_eid(s, t) << 1) | 1;
|
|
452
|
+
} else {
|
|
453
|
+
--t;
|
|
454
|
+
arc._id = (t != -1 ? (_eid(t, s) << 1) : -1);
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
void nextOut(Arc& arc) const {
|
|
459
|
+
int s, t;
|
|
460
|
+
_stid(arc._id, s, t);
|
|
461
|
+
--t;
|
|
462
|
+
if (s < t) {
|
|
463
|
+
arc._id = (_eid(s, t) << 1) | 1;
|
|
464
|
+
} else {
|
|
465
|
+
if (s == t) --t;
|
|
466
|
+
arc._id = (t != -1 ? (_eid(t, s) << 1) : -1);
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
void firstIn(Arc& arc, const Node& node) const {
|
|
471
|
+
int s = _node_num - 1, t = node._id;
|
|
472
|
+
if (s > t) {
|
|
473
|
+
arc._id = (_eid(t, s) << 1);
|
|
474
|
+
} else {
|
|
475
|
+
--s;
|
|
476
|
+
arc._id = (s != -1 ? (_eid(s, t) << 1) | 1 : -1);
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
void nextIn(Arc& arc) const {
|
|
481
|
+
int s, t;
|
|
482
|
+
_stid(arc._id, s, t);
|
|
483
|
+
--s;
|
|
484
|
+
if (s > t) {
|
|
485
|
+
arc._id = (_eid(t, s) << 1);
|
|
486
|
+
} else {
|
|
487
|
+
if (s == t) --s;
|
|
488
|
+
arc._id = (s != -1 ? (_eid(s, t) << 1) | 1 : -1);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
void firstInc(Edge& edge, bool& dir, const Node& node) const {
|
|
493
|
+
int u = node._id, v = _node_num - 1;
|
|
494
|
+
if (u < v) {
|
|
495
|
+
edge._id = _eid(u, v);
|
|
496
|
+
dir = true;
|
|
497
|
+
} else {
|
|
498
|
+
--v;
|
|
499
|
+
edge._id = (v != -1 ? _eid(v, u) : -1);
|
|
500
|
+
dir = false;
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
void nextInc(Edge& edge, bool& dir) const {
|
|
505
|
+
int u, v;
|
|
506
|
+
if (dir) {
|
|
507
|
+
_uvid(edge._id, u, v);
|
|
508
|
+
--v;
|
|
509
|
+
if (u < v) {
|
|
510
|
+
edge._id = _eid(u, v);
|
|
511
|
+
} else {
|
|
512
|
+
--v;
|
|
513
|
+
edge._id = (v != -1 ? _eid(v, u) : -1);
|
|
514
|
+
dir = false;
|
|
515
|
+
}
|
|
516
|
+
} else {
|
|
517
|
+
_uvid(edge._id, v, u);
|
|
518
|
+
--v;
|
|
519
|
+
edge._id = (v != -1 ? _eid(v, u) : -1);
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
};
|
|
524
|
+
|
|
525
|
+
typedef GraphExtender<FullGraphBase> ExtendedFullGraphBase;
|
|
526
|
+
|
|
527
|
+
/// \ingroup graphs
|
|
528
|
+
///
|
|
529
|
+
/// \brief An undirected full graph class.
|
|
530
|
+
///
|
|
531
|
+
/// FullGraph is a simple and fast implmenetation of undirected full
|
|
532
|
+
/// (complete) graphs. It contains an edge between every distinct pair
|
|
533
|
+
/// of nodes, therefore the number of edges is <tt>n(n-1)/2</tt>.
|
|
534
|
+
/// This class is completely static and it needs constant memory space.
|
|
535
|
+
/// Thus you can neither add nor delete nodes or edges, however
|
|
536
|
+
/// the structure can be resized using resize().
|
|
537
|
+
///
|
|
538
|
+
/// This type fully conforms to the \ref concepts::Graph "Graph concept".
|
|
539
|
+
/// Most of its member functions and nested classes are documented
|
|
540
|
+
/// only in the concept class.
|
|
541
|
+
///
|
|
542
|
+
/// This class provides constant time counting for nodes, edges and arcs.
|
|
543
|
+
///
|
|
544
|
+
/// \note FullDigraph and FullGraph classes are very similar,
|
|
545
|
+
/// but there are two differences. While FullDigraph
|
|
546
|
+
/// conforms only to the \ref concepts::Digraph "Digraph" concept,
|
|
547
|
+
/// this class conforms to the \ref concepts::Graph "Graph" concept,
|
|
548
|
+
/// moreover this class does not contain a loop for each
|
|
549
|
+
/// node as FullDigraph does.
|
|
550
|
+
///
|
|
551
|
+
/// \sa FullDigraph
|
|
552
|
+
class FullGraph : public ExtendedFullGraphBase {
|
|
553
|
+
typedef ExtendedFullGraphBase Parent;
|
|
554
|
+
|
|
555
|
+
public:
|
|
556
|
+
|
|
557
|
+
/// \brief Default constructor.
|
|
558
|
+
///
|
|
559
|
+
/// Default constructor. The number of nodes and edges will be zero.
|
|
560
|
+
FullGraph() { construct(0); }
|
|
561
|
+
|
|
562
|
+
/// \brief Constructor
|
|
563
|
+
///
|
|
564
|
+
/// Constructor.
|
|
565
|
+
/// \param n The number of the nodes.
|
|
566
|
+
FullGraph(int n) { construct(n); }
|
|
567
|
+
|
|
568
|
+
/// \brief Resizes the graph
|
|
569
|
+
///
|
|
570
|
+
/// This function resizes the graph. It fully destroys and
|
|
571
|
+
/// rebuilds the structure, therefore the maps of the graph will be
|
|
572
|
+
/// reallocated automatically and the previous values will be lost.
|
|
573
|
+
void resize(int n) {
|
|
574
|
+
Parent::notifier(Arc()).clear();
|
|
575
|
+
Parent::notifier(Edge()).clear();
|
|
576
|
+
Parent::notifier(Node()).clear();
|
|
577
|
+
construct(n);
|
|
578
|
+
Parent::notifier(Node()).build();
|
|
579
|
+
Parent::notifier(Edge()).build();
|
|
580
|
+
Parent::notifier(Arc()).build();
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
/// \brief Returns the node with the given index.
|
|
584
|
+
///
|
|
585
|
+
/// Returns the node with the given index. Since this structure is
|
|
586
|
+
/// completely static, the nodes can be indexed with integers from
|
|
587
|
+
/// the range <tt>[0..nodeNum()-1]</tt>.
|
|
588
|
+
/// The index of a node is the same as its ID.
|
|
589
|
+
/// \sa index()
|
|
590
|
+
Node operator()(int ix) const { return Parent::operator()(ix); }
|
|
591
|
+
|
|
592
|
+
/// \brief Returns the index of the given node.
|
|
593
|
+
///
|
|
594
|
+
/// Returns the index of the given node. Since this structure is
|
|
595
|
+
/// completely static, the nodes can be indexed with integers from
|
|
596
|
+
/// the range <tt>[0..nodeNum()-1]</tt>.
|
|
597
|
+
/// The index of a node is the same as its ID.
|
|
598
|
+
/// \sa operator()()
|
|
599
|
+
static int index(const Node& node) { return Parent::index(node); }
|
|
600
|
+
|
|
601
|
+
/// \brief Returns the arc connecting the given nodes.
|
|
602
|
+
///
|
|
603
|
+
/// Returns the arc connecting the given nodes.
|
|
604
|
+
Arc arc(Node s, Node t) const {
|
|
605
|
+
return Parent::arc(s, t);
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
/// \brief Returns the edge connecting the given nodes.
|
|
609
|
+
///
|
|
610
|
+
/// Returns the edge connecting the given nodes.
|
|
611
|
+
Edge edge(Node u, Node v) const {
|
|
612
|
+
return Parent::edge(u, v);
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
/// \brief Number of nodes.
|
|
616
|
+
int nodeNum() const { return Parent::nodeNum(); }
|
|
617
|
+
/// \brief Number of arcs.
|
|
618
|
+
int arcNum() const { return Parent::arcNum(); }
|
|
619
|
+
/// \brief Number of edges.
|
|
620
|
+
int edgeNum() const { return Parent::edgeNum(); }
|
|
621
|
+
|
|
622
|
+
};
|
|
623
|
+
|
|
624
|
+
class FullBpGraphBase {
|
|
625
|
+
|
|
626
|
+
protected:
|
|
627
|
+
|
|
628
|
+
int _red_num, _blue_num;
|
|
629
|
+
int _node_num, _edge_num;
|
|
630
|
+
|
|
631
|
+
public:
|
|
632
|
+
|
|
633
|
+
typedef FullBpGraphBase Graph;
|
|
634
|
+
|
|
635
|
+
class Node;
|
|
636
|
+
class Arc;
|
|
637
|
+
class Edge;
|
|
638
|
+
|
|
639
|
+
class Node {
|
|
640
|
+
friend class FullBpGraphBase;
|
|
641
|
+
protected:
|
|
642
|
+
|
|
643
|
+
int _id;
|
|
644
|
+
explicit Node(int id) { _id = id;}
|
|
645
|
+
|
|
646
|
+
public:
|
|
647
|
+
Node() {}
|
|
648
|
+
Node (Invalid) { _id = -1; }
|
|
649
|
+
bool operator==(const Node& node) const {return _id == node._id;}
|
|
650
|
+
bool operator!=(const Node& node) const {return _id != node._id;}
|
|
651
|
+
bool operator<(const Node& node) const {return _id < node._id;}
|
|
652
|
+
};
|
|
653
|
+
|
|
654
|
+
class RedNode : public Node {
|
|
655
|
+
friend class FullBpGraphBase;
|
|
656
|
+
protected:
|
|
657
|
+
|
|
658
|
+
explicit RedNode(int pid) : Node(pid) {}
|
|
659
|
+
|
|
660
|
+
public:
|
|
661
|
+
RedNode() {}
|
|
662
|
+
RedNode(const RedNode& node) : Node(node) {}
|
|
663
|
+
RedNode(Invalid) : Node(INVALID){}
|
|
664
|
+
};
|
|
665
|
+
|
|
666
|
+
class BlueNode : public Node {
|
|
667
|
+
friend class FullBpGraphBase;
|
|
668
|
+
protected:
|
|
669
|
+
|
|
670
|
+
explicit BlueNode(int pid) : Node(pid) {}
|
|
671
|
+
|
|
672
|
+
public:
|
|
673
|
+
BlueNode() {}
|
|
674
|
+
BlueNode(const BlueNode& node) : Node(node) {}
|
|
675
|
+
BlueNode(Invalid) : Node(INVALID){}
|
|
676
|
+
};
|
|
677
|
+
|
|
678
|
+
class Edge {
|
|
679
|
+
friend class FullBpGraphBase;
|
|
680
|
+
protected:
|
|
681
|
+
|
|
682
|
+
int _id;
|
|
683
|
+
explicit Edge(int id) { _id = id;}
|
|
684
|
+
|
|
685
|
+
public:
|
|
686
|
+
Edge() {}
|
|
687
|
+
Edge (Invalid) { _id = -1; }
|
|
688
|
+
bool operator==(const Edge& arc) const {return _id == arc._id;}
|
|
689
|
+
bool operator!=(const Edge& arc) const {return _id != arc._id;}
|
|
690
|
+
bool operator<(const Edge& arc) const {return _id < arc._id;}
|
|
691
|
+
};
|
|
692
|
+
|
|
693
|
+
class Arc {
|
|
694
|
+
friend class FullBpGraphBase;
|
|
695
|
+
protected:
|
|
696
|
+
|
|
697
|
+
int _id;
|
|
698
|
+
explicit Arc(int id) { _id = id;}
|
|
699
|
+
|
|
700
|
+
public:
|
|
701
|
+
operator Edge() const {
|
|
702
|
+
return _id != -1 ? edgeFromId(_id / 2) : INVALID;
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
Arc() {}
|
|
706
|
+
Arc (Invalid) { _id = -1; }
|
|
707
|
+
bool operator==(const Arc& arc) const {return _id == arc._id;}
|
|
708
|
+
bool operator!=(const Arc& arc) const {return _id != arc._id;}
|
|
709
|
+
bool operator<(const Arc& arc) const {return _id < arc._id;}
|
|
710
|
+
};
|
|
711
|
+
|
|
712
|
+
|
|
713
|
+
protected:
|
|
714
|
+
|
|
715
|
+
FullBpGraphBase()
|
|
716
|
+
: _red_num(0), _blue_num(0), _node_num(0), _edge_num(0) {}
|
|
717
|
+
|
|
718
|
+
void construct(int redNum, int blueNum) {
|
|
719
|
+
_red_num = redNum; _blue_num = blueNum;
|
|
720
|
+
_node_num = redNum + blueNum; _edge_num = redNum * blueNum;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
public:
|
|
724
|
+
|
|
725
|
+
typedef True NodeNumTag;
|
|
726
|
+
typedef True EdgeNumTag;
|
|
727
|
+
typedef True ArcNumTag;
|
|
728
|
+
|
|
729
|
+
int nodeNum() const { return _node_num; }
|
|
730
|
+
int redNum() const { return _red_num; }
|
|
731
|
+
int blueNum() const { return _blue_num; }
|
|
732
|
+
int edgeNum() const { return _edge_num; }
|
|
733
|
+
int arcNum() const { return 2 * _edge_num; }
|
|
734
|
+
|
|
735
|
+
int maxNodeId() const { return _node_num - 1; }
|
|
736
|
+
int maxRedId() const { return _red_num - 1; }
|
|
737
|
+
int maxBlueId() const { return _blue_num - 1; }
|
|
738
|
+
int maxEdgeId() const { return _edge_num - 1; }
|
|
739
|
+
int maxArcId() const { return 2 * _edge_num - 1; }
|
|
740
|
+
|
|
741
|
+
bool red(Node n) const { return n._id < _red_num; }
|
|
742
|
+
bool blue(Node n) const { return n._id >= _red_num; }
|
|
743
|
+
|
|
744
|
+
static RedNode asRedNodeUnsafe(Node n) { return RedNode(n._id); }
|
|
745
|
+
static BlueNode asBlueNodeUnsafe(Node n) { return BlueNode(n._id); }
|
|
746
|
+
|
|
747
|
+
Node source(Arc a) const {
|
|
748
|
+
if (a._id & 1) {
|
|
749
|
+
return Node((a._id >> 1) % _red_num);
|
|
750
|
+
} else {
|
|
751
|
+
return Node((a._id >> 1) / _red_num + _red_num);
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
Node target(Arc a) const {
|
|
755
|
+
if (a._id & 1) {
|
|
756
|
+
return Node((a._id >> 1) / _red_num + _red_num);
|
|
757
|
+
} else {
|
|
758
|
+
return Node((a._id >> 1) % _red_num);
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
RedNode redNode(Edge e) const {
|
|
763
|
+
return RedNode(e._id % _red_num);
|
|
764
|
+
}
|
|
765
|
+
BlueNode blueNode(Edge e) const {
|
|
766
|
+
return BlueNode(e._id / _red_num + _red_num);
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
static bool direction(Arc a) {
|
|
770
|
+
return (a._id & 1) == 1;
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
static Arc direct(Edge e, bool d) {
|
|
774
|
+
return Arc(e._id * 2 + (d ? 1 : 0));
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
void first(Node& node) const {
|
|
778
|
+
node._id = _node_num - 1;
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
static void next(Node& node) {
|
|
782
|
+
--node._id;
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
void first(RedNode& node) const {
|
|
786
|
+
node._id = _red_num - 1;
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
static void next(RedNode& node) {
|
|
790
|
+
--node._id;
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
void first(BlueNode& node) const {
|
|
794
|
+
if (_red_num == _node_num) node._id = -1;
|
|
795
|
+
else node._id = _node_num - 1;
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
void next(BlueNode& node) const {
|
|
799
|
+
if (node._id == _red_num) node._id = -1;
|
|
800
|
+
else --node._id;
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
void first(Arc& arc) const {
|
|
804
|
+
arc._id = 2 * _edge_num - 1;
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
static void next(Arc& arc) {
|
|
808
|
+
--arc._id;
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
void first(Edge& arc) const {
|
|
812
|
+
arc._id = _edge_num - 1;
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
static void next(Edge& arc) {
|
|
816
|
+
--arc._id;
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
void firstOut(Arc &a, const Node& v) const {
|
|
820
|
+
if (v._id < _red_num) {
|
|
821
|
+
a._id = 2 * (v._id + _red_num * (_blue_num - 1)) + 1;
|
|
822
|
+
} else {
|
|
823
|
+
a._id = 2 * (_red_num - 1 + _red_num * (v._id - _red_num));
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
void nextOut(Arc &a) const {
|
|
827
|
+
if (a._id & 1) {
|
|
828
|
+
a._id -= 2 * _red_num;
|
|
829
|
+
if (a._id < 0) a._id = -1;
|
|
830
|
+
} else {
|
|
831
|
+
if (a._id % (2 * _red_num) == 0) a._id = -1;
|
|
832
|
+
else a._id -= 2;
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
void firstIn(Arc &a, const Node& v) const {
|
|
837
|
+
if (v._id < _red_num) {
|
|
838
|
+
a._id = 2 * (v._id + _red_num * (_blue_num - 1));
|
|
839
|
+
} else {
|
|
840
|
+
a._id = 2 * (_red_num - 1 + _red_num * (v._id - _red_num)) + 1;
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
void nextIn(Arc &a) const {
|
|
844
|
+
if (a._id & 1) {
|
|
845
|
+
if (a._id % (2 * _red_num) == 1) a._id = -1;
|
|
846
|
+
else a._id -= 2;
|
|
847
|
+
} else {
|
|
848
|
+
a._id -= 2 * _red_num;
|
|
849
|
+
if (a._id < 0) a._id = -1;
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
void firstInc(Edge &e, bool& d, const Node& v) const {
|
|
854
|
+
if (v._id < _red_num) {
|
|
855
|
+
d = true;
|
|
856
|
+
e._id = v._id + _red_num * (_blue_num - 1);
|
|
857
|
+
} else {
|
|
858
|
+
d = false;
|
|
859
|
+
e._id = _red_num - 1 + _red_num * (v._id - _red_num);
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
void nextInc(Edge &e, bool& d) const {
|
|
863
|
+
if (d) {
|
|
864
|
+
e._id -= _red_num;
|
|
865
|
+
if (e._id < 0) e._id = -1;
|
|
866
|
+
} else {
|
|
867
|
+
if (e._id % _red_num == 0) e._id = -1;
|
|
868
|
+
else --e._id;
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
static int id(const Node& v) { return v._id; }
|
|
873
|
+
int id(const RedNode& v) const { return v._id; }
|
|
874
|
+
int id(const BlueNode& v) const { return v._id - _red_num; }
|
|
875
|
+
static int id(Arc e) { return e._id; }
|
|
876
|
+
static int id(Edge e) { return e._id; }
|
|
877
|
+
|
|
878
|
+
static Node nodeFromId(int id) { return Node(id);}
|
|
879
|
+
static Arc arcFromId(int id) { return Arc(id);}
|
|
880
|
+
static Edge edgeFromId(int id) { return Edge(id);}
|
|
881
|
+
|
|
882
|
+
bool valid(Node n) const {
|
|
883
|
+
return n._id >= 0 && n._id < _node_num;
|
|
884
|
+
}
|
|
885
|
+
bool valid(Arc a) const {
|
|
886
|
+
return a._id >= 0 && a._id < 2 * _edge_num;
|
|
887
|
+
}
|
|
888
|
+
bool valid(Edge e) const {
|
|
889
|
+
return e._id >= 0 && e._id < _edge_num;
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
RedNode redNode(int index) const {
|
|
893
|
+
return RedNode(index);
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
int index(RedNode n) const {
|
|
897
|
+
return n._id;
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
BlueNode blueNode(int index) const {
|
|
901
|
+
return BlueNode(index + _red_num);
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
int index(BlueNode n) const {
|
|
905
|
+
return n._id - _red_num;
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
void clear() {
|
|
909
|
+
_red_num = 0; _blue_num = 0;
|
|
910
|
+
_node_num = 0; _edge_num = 0;
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
Edge edge(const Node& u, const Node& v) const {
|
|
914
|
+
if (u._id < _red_num) {
|
|
915
|
+
if (v._id < _red_num) {
|
|
916
|
+
return Edge(-1);
|
|
917
|
+
} else {
|
|
918
|
+
return Edge(u._id + _red_num * (v._id - _red_num));
|
|
919
|
+
}
|
|
920
|
+
} else {
|
|
921
|
+
if (v._id < _red_num) {
|
|
922
|
+
return Edge(v._id + _red_num * (u._id - _red_num));
|
|
923
|
+
} else {
|
|
924
|
+
return Edge(-1);
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
Arc arc(const Node& u, const Node& v) const {
|
|
930
|
+
if (u._id < _red_num) {
|
|
931
|
+
if (v._id < _red_num) {
|
|
932
|
+
return Arc(-1);
|
|
933
|
+
} else {
|
|
934
|
+
return Arc(2 * (u._id + _red_num * (v._id - _red_num)) + 1);
|
|
935
|
+
}
|
|
936
|
+
} else {
|
|
937
|
+
if (v._id < _red_num) {
|
|
938
|
+
return Arc(2 * (v._id + _red_num * (u._id - _red_num)));
|
|
939
|
+
} else {
|
|
940
|
+
return Arc(-1);
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
typedef True FindEdgeTag;
|
|
946
|
+
typedef True FindArcTag;
|
|
947
|
+
|
|
948
|
+
Edge findEdge(Node u, Node v, Edge prev = INVALID) const {
|
|
949
|
+
return prev != INVALID ? INVALID : edge(u, v);
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
Arc findArc(Node s, Node t, Arc prev = INVALID) const {
|
|
953
|
+
return prev != INVALID ? INVALID : arc(s, t);
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
};
|
|
957
|
+
|
|
958
|
+
typedef BpGraphExtender<FullBpGraphBase> ExtendedFullBpGraphBase;
|
|
959
|
+
|
|
960
|
+
/// \ingroup graphs
|
|
961
|
+
///
|
|
962
|
+
/// \brief An undirected full bipartite graph class.
|
|
963
|
+
///
|
|
964
|
+
/// FullBpGraph is a simple and fast implmenetation of undirected
|
|
965
|
+
/// full bipartite graphs. It contains an edge between every
|
|
966
|
+
/// red-blue pairs of nodes, therefore the number of edges is
|
|
967
|
+
/// <tt>nr*nb</tt>. This class is completely static and it needs
|
|
968
|
+
/// constant memory space. Thus you can neither add nor delete
|
|
969
|
+
/// nodes or edges, however the structure can be resized using
|
|
970
|
+
/// resize().
|
|
971
|
+
///
|
|
972
|
+
/// This type fully conforms to the \ref concepts::BpGraph "BpGraph concept".
|
|
973
|
+
/// Most of its member functions and nested classes are documented
|
|
974
|
+
/// only in the concept class.
|
|
975
|
+
///
|
|
976
|
+
/// This class provides constant time counting for nodes, edges and arcs.
|
|
977
|
+
///
|
|
978
|
+
/// \sa FullGraph
|
|
979
|
+
class FullBpGraph : public ExtendedFullBpGraphBase {
|
|
980
|
+
public:
|
|
981
|
+
|
|
982
|
+
typedef ExtendedFullBpGraphBase Parent;
|
|
983
|
+
|
|
984
|
+
/// \brief Default constructor.
|
|
985
|
+
///
|
|
986
|
+
/// Default constructor. The number of nodes and edges will be zero.
|
|
987
|
+
FullBpGraph() { construct(0, 0); }
|
|
988
|
+
|
|
989
|
+
/// \brief Constructor
|
|
990
|
+
///
|
|
991
|
+
/// Constructor.
|
|
992
|
+
/// \param redNum The number of the red nodes.
|
|
993
|
+
/// \param blueNum The number of the blue nodes.
|
|
994
|
+
FullBpGraph(int redNum, int blueNum) { construct(redNum, blueNum); }
|
|
995
|
+
|
|
996
|
+
/// \brief Resizes the graph
|
|
997
|
+
///
|
|
998
|
+
/// This function resizes the graph. It fully destroys and
|
|
999
|
+
/// rebuilds the structure, therefore the maps of the graph will be
|
|
1000
|
+
/// reallocated automatically and the previous values will be lost.
|
|
1001
|
+
void resize(int redNum, int blueNum) {
|
|
1002
|
+
Parent::notifier(Arc()).clear();
|
|
1003
|
+
Parent::notifier(Edge()).clear();
|
|
1004
|
+
Parent::notifier(Node()).clear();
|
|
1005
|
+
Parent::notifier(BlueNode()).clear();
|
|
1006
|
+
Parent::notifier(RedNode()).clear();
|
|
1007
|
+
construct(redNum, blueNum);
|
|
1008
|
+
Parent::notifier(RedNode()).build();
|
|
1009
|
+
Parent::notifier(BlueNode()).build();
|
|
1010
|
+
Parent::notifier(Node()).build();
|
|
1011
|
+
Parent::notifier(Edge()).build();
|
|
1012
|
+
Parent::notifier(Arc()).build();
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
using Parent::redNode;
|
|
1016
|
+
using Parent::blueNode;
|
|
1017
|
+
|
|
1018
|
+
/// \brief Returns the red node with the given index.
|
|
1019
|
+
///
|
|
1020
|
+
/// Returns the red node with the given index. Since this
|
|
1021
|
+
/// structure is completely static, the red nodes can be indexed
|
|
1022
|
+
/// with integers from the range <tt>[0..redNum()-1]</tt>.
|
|
1023
|
+
/// \sa redIndex()
|
|
1024
|
+
RedNode redNode(int index) const { return Parent::redNode(index); }
|
|
1025
|
+
|
|
1026
|
+
/// \brief Returns the index of the given red node.
|
|
1027
|
+
///
|
|
1028
|
+
/// Returns the index of the given red node. Since this structure
|
|
1029
|
+
/// is completely static, the red nodes can be indexed with
|
|
1030
|
+
/// integers from the range <tt>[0..redNum()-1]</tt>.
|
|
1031
|
+
///
|
|
1032
|
+
/// \sa operator()()
|
|
1033
|
+
int index(RedNode node) const { return Parent::index(node); }
|
|
1034
|
+
|
|
1035
|
+
/// \brief Returns the blue node with the given index.
|
|
1036
|
+
///
|
|
1037
|
+
/// Returns the blue node with the given index. Since this
|
|
1038
|
+
/// structure is completely static, the blue nodes can be indexed
|
|
1039
|
+
/// with integers from the range <tt>[0..blueNum()-1]</tt>.
|
|
1040
|
+
/// \sa blueIndex()
|
|
1041
|
+
BlueNode blueNode(int index) const { return Parent::blueNode(index); }
|
|
1042
|
+
|
|
1043
|
+
/// \brief Returns the index of the given blue node.
|
|
1044
|
+
///
|
|
1045
|
+
/// Returns the index of the given blue node. Since this structure
|
|
1046
|
+
/// is completely static, the blue nodes can be indexed with
|
|
1047
|
+
/// integers from the range <tt>[0..blueNum()-1]</tt>.
|
|
1048
|
+
///
|
|
1049
|
+
/// \sa operator()()
|
|
1050
|
+
int index(BlueNode node) const { return Parent::index(node); }
|
|
1051
|
+
|
|
1052
|
+
/// \brief Returns the edge which connects the given nodes.
|
|
1053
|
+
///
|
|
1054
|
+
/// Returns the edge which connects the given nodes.
|
|
1055
|
+
Edge edge(const Node& u, const Node& v) const {
|
|
1056
|
+
return Parent::edge(u, v);
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
/// \brief Returns the arc which connects the given nodes.
|
|
1060
|
+
///
|
|
1061
|
+
/// Returns the arc which connects the given nodes.
|
|
1062
|
+
Arc arc(const Node& u, const Node& v) const {
|
|
1063
|
+
return Parent::arc(u, v);
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1066
|
+
/// \brief Number of nodes.
|
|
1067
|
+
int nodeNum() const { return Parent::nodeNum(); }
|
|
1068
|
+
/// \brief Number of red nodes.
|
|
1069
|
+
int redNum() const { return Parent::redNum(); }
|
|
1070
|
+
/// \brief Number of blue nodes.
|
|
1071
|
+
int blueNum() const { return Parent::blueNum(); }
|
|
1072
|
+
/// \brief Number of arcs.
|
|
1073
|
+
int arcNum() const { return Parent::arcNum(); }
|
|
1074
|
+
/// \brief Number of edges.
|
|
1075
|
+
int edgeNum() const { return Parent::edgeNum(); }
|
|
1076
|
+
};
|
|
1077
|
+
|
|
1078
|
+
|
|
1079
|
+
} //namespace lemon
|
|
1080
|
+
|
|
1081
|
+
|
|
1082
|
+
#endif //LEMON_FULL_GRAPH_H
|