!
!
!
3
3
52
52
4
4
137
137
86
86
44
44
229
229
44
44
109
109
16
16
147
147
36
37
111
111
Changeset was too big and was cut off... Show full diff
1 |
/* -*- C++ -*- |
|
1 |
/* -*- mode: C++; indent-tabs-mode: nil; -*- |
|
2 | 2 |
* |
3 |
* This file is a part of LEMON, a generic C++ optimization library |
|
3 |
* This file is a part of LEMON, a generic C++ optimization library. |
|
4 | 4 |
* |
5 | 5 |
* Copyright (C) 2003-2008 |
6 | 6 |
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
7 | 7 |
* (Egervary Research Group on Combinatorial Optimization, EGRES). |
8 | 8 |
* |
9 | 9 |
* Permission to use, modify and distribute this software is granted |
... | ... |
@@ -61,13 +61,13 @@ |
61 | 61 |
ap.mandatoryGroup("gr"); |
62 | 62 |
// Set the options of the group exclusive (only one option can be given) |
63 | 63 |
ap.onlyOneGroup("gr"); |
64 | 64 |
// Add non-parsed arguments (e.g. input files) |
65 | 65 |
ap.other("infile", "The input file.") |
66 | 66 |
.other("..."); |
67 |
|
|
67 |
|
|
68 | 68 |
// Perform the parsing process |
69 | 69 |
// (in case of any error it terminates the program) |
70 | 70 |
ap.parse(); |
71 | 71 |
|
72 | 72 |
// Check each option if it has been given and print its value |
73 | 73 |
std::cout << "Parameters of '" << ap.commandName() << "':\n"; |
... | ... |
@@ -81,23 +81,23 @@ |
81 | 81 |
if(ap.given("name")) std::cout << " Value of -name: " << s << std::endl; |
82 | 82 |
if(ap.given("f")) std::cout << " -f is given\n"; |
83 | 83 |
if(ap.given("nohelp")) std::cout << " Value of -nohelp: " << nh << std::endl; |
84 | 84 |
if(ap.given("gra")) std::cout << " -gra is given\n"; |
85 | 85 |
if(ap.given("grb")) std::cout << " -grb is given\n"; |
86 | 86 |
if(ap.given("grc")) std::cout << " -grc is given\n"; |
87 |
|
|
87 |
|
|
88 | 88 |
switch(ap.files().size()) { |
89 | 89 |
case 0: |
90 | 90 |
std::cout << " No file argument was given.\n"; |
91 | 91 |
break; |
92 | 92 |
case 1: |
93 | 93 |
std::cout << " 1 file argument was given. It is:\n"; |
94 | 94 |
break; |
95 | 95 |
default: |
96 | 96 |
std::cout << " " |
97 |
|
|
97 |
<< ap.files().size() << " file arguments were given. They are:\n"; |
|
98 | 98 |
} |
99 | 99 |
for(unsigned int i=0;i<ap.files().size();++i) |
100 | 100 |
std::cout << " '" << ap.files()[i] << "'\n"; |
101 |
|
|
101 |
|
|
102 | 102 |
return 0; |
103 | 103 |
} |
1 |
/* -*- C++ -*- |
|
1 |
/* -*- mode: C++; indent-tabs-mode: nil; -*- |
|
2 | 2 |
* |
3 |
* This file is a part of LEMON, a generic C++ optimization library |
|
3 |
* This file is a part of LEMON, a generic C++ optimization library. |
|
4 | 4 |
* |
5 | 5 |
* Copyright (C) 2003-2008 |
6 | 6 |
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
7 | 7 |
* (Egervary Research Group on Combinatorial Optimization, EGRES). |
8 | 8 |
* |
9 | 9 |
* Permission to use, modify and distribute this software is granted |
... | ... |
@@ -46,42 +46,42 @@ |
46 | 46 |
// Create a small digraph |
47 | 47 |
ListDigraph g; |
48 | 48 |
typedef ListDigraph::Node Node; |
49 | 49 |
typedef ListDigraph::NodeIt NodeIt; |
50 | 50 |
typedef ListDigraph::Arc Arc; |
51 | 51 |
typedef dim2::Point<int> Point; |
52 |
|
|
52 |
|
|
53 | 53 |
Node n1=g.addNode(); |
54 | 54 |
Node n2=g.addNode(); |
55 | 55 |
Node n3=g.addNode(); |
56 | 56 |
Node n4=g.addNode(); |
57 | 57 |
Node n5=g.addNode(); |
58 | 58 |
|
59 | 59 |
ListDigraph::NodeMap<Point> coords(g); |
60 | 60 |
ListDigraph::NodeMap<double> sizes(g); |
61 | 61 |
ListDigraph::NodeMap<int> colors(g); |
62 | 62 |
ListDigraph::NodeMap<int> shapes(g); |
63 | 63 |
ListDigraph::ArcMap<int> acolors(g); |
64 | 64 |
ListDigraph::ArcMap<int> widths(g); |
65 |
|
|
65 |
|
|
66 | 66 |
coords[n1]=Point(50,50); sizes[n1]=1; colors[n1]=1; shapes[n1]=0; |
67 | 67 |
coords[n2]=Point(50,70); sizes[n2]=2; colors[n2]=2; shapes[n2]=2; |
68 | 68 |
coords[n3]=Point(70,70); sizes[n3]=1; colors[n3]=3; shapes[n3]=0; |
69 | 69 |
coords[n4]=Point(70,50); sizes[n4]=2; colors[n4]=4; shapes[n4]=1; |
70 | 70 |
coords[n5]=Point(85,60); sizes[n5]=3; colors[n5]=5; shapes[n5]=2; |
71 |
|
|
71 |
|
|
72 | 72 |
Arc a; |
73 | 73 |
|
74 | 74 |
a=g.addArc(n1,n2); acolors[a]=0; widths[a]=1; |
75 | 75 |
a=g.addArc(n2,n3); acolors[a]=0; widths[a]=1; |
76 | 76 |
a=g.addArc(n3,n5); acolors[a]=0; widths[a]=3; |
77 | 77 |
a=g.addArc(n5,n4); acolors[a]=0; widths[a]=1; |
78 | 78 |
a=g.addArc(n4,n1); acolors[a]=0; widths[a]=1; |
79 | 79 |
a=g.addArc(n2,n4); acolors[a]=1; widths[a]=2; |
80 | 80 |
a=g.addArc(n3,n4); acolors[a]=2; widths[a]=1; |
81 |
|
|
81 |
|
|
82 | 82 |
IdMap<ListDigraph,Node> id(g); |
83 | 83 |
|
84 | 84 |
// Create five .eps files showing the digraph with different options |
85 | 85 |
cout << "Create 'graph_to_eps_demo_out_1_pure.eps'" << endl; |
86 | 86 |
graphToEps(g,"graph_to_eps_demo_out_1_pure.eps"). |
87 | 87 |
coords(coords). |
... | ... |
@@ -179,29 +179,29 @@ |
179 | 179 |
run(); |
180 | 180 |
|
181 | 181 |
// Create an .eps file showing the colors of a default Palette |
182 | 182 |
ListDigraph h; |
183 | 183 |
ListDigraph::NodeMap<int> hcolors(h); |
184 | 184 |
ListDigraph::NodeMap<Point> hcoords(h); |
185 |
|
|
185 |
|
|
186 | 186 |
int cols=int(sqrt(double(palette.size()))); |
187 | 187 |
for(int i=0;i<int(paletteW.size());i++) { |
188 | 188 |
Node n=h.addNode(); |
189 | 189 |
hcoords[n]=Point(1+i%cols,1+i/cols); |
190 | 190 |
hcolors[n]=i; |
191 | 191 |
} |
192 |
|
|
192 |
|
|
193 | 193 |
cout << "Create 'graph_to_eps_demo_out_6_colors.eps'" << endl; |
194 | 194 |
graphToEps(h,"graph_to_eps_demo_out_6_colors.eps"). |
195 | 195 |
scale(60). |
196 | 196 |
title("Sample .eps figure (Palette demo)"). |
197 | 197 |
copyright("(C) 2003-2008 LEMON Project"). |
198 | 198 |
coords(hcoords). |
199 | 199 |
absoluteNodeSizes().absoluteArcWidths(). |
200 | 200 |
nodeScale(.45). |
201 | 201 |
distantColorNodeTexts(). |
202 | 202 |
nodeTexts(hcolors).nodeTextSize(.6). |
203 | 203 |
nodeColors(composeMap(paletteW,hcolors)). |
204 | 204 |
run(); |
205 |
|
|
205 |
|
|
206 | 206 |
return 0; |
207 | 207 |
} |
1 |
/* -*- C++ -*- |
|
1 |
/* -*- mode: C++; indent-tabs-mode: nil; -*- |
|
2 | 2 |
* |
3 |
* This file is a part of LEMON, a generic C++ optimization library |
|
3 |
* This file is a part of LEMON, a generic C++ optimization library. |
|
4 | 4 |
* |
5 | 5 |
* Copyright (C) 2003-2008 |
6 | 6 |
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
7 | 7 |
* (Egervary Research Group on Combinatorial Optimization, EGRES). |
8 | 8 |
* |
9 | 9 |
* Permission to use, modify and distribute this software is granted |
... | ... |
@@ -18,13 +18,13 @@ |
18 | 18 |
|
19 | 19 |
///\ingroup demos |
20 | 20 |
///\file |
21 | 21 |
///\brief Demonstrating graph input and output |
22 | 22 |
/// |
23 | 23 |
/// This program gives an example of how to read and write a digraph |
24 |
/// and additional maps from/to a stream or a file using the |
|
24 |
/// and additional maps from/to a stream or a file using the |
|
25 | 25 |
/// \ref lgf-format "LGF" format. |
26 | 26 |
/// |
27 | 27 |
/// The \c "digraph.lgf" file: |
28 | 28 |
/// \include digraph.lgf |
29 | 29 |
/// |
30 | 30 |
/// And the program which reads it and prints the digraph to the |
... | ... |
@@ -39,13 +39,13 @@ |
39 | 39 |
using namespace lemon; |
40 | 40 |
|
41 | 41 |
int main() { |
42 | 42 |
SmartDigraph g; |
43 | 43 |
SmartDigraph::ArcMap<int> cap(g); |
44 | 44 |
SmartDigraph::Node s, t; |
45 |
|
|
45 |
|
|
46 | 46 |
try { |
47 | 47 |
digraphReader("digraph.lgf", g). // read the directed graph into g |
48 | 48 |
arcMap("capacity", cap). // read the 'capacity' arc map into cap |
49 | 49 |
node("source", s). // read 'source' node to s |
50 | 50 |
node("target", t). // read 'target' node to t |
51 | 51 |
run(); |
1 |
/* -*- C++ -*- |
|
1 |
/* -*- mode: C++; indent-tabs-mode: nil; -*- |
|
2 | 2 |
* |
3 |
* This file is a part of LEMON, a generic C++ optimization library |
|
3 |
* This file is a part of LEMON, a generic C++ optimization library. |
|
4 | 4 |
* |
5 | 5 |
* Copyright (C) 2003-2008 |
6 | 6 |
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
7 | 7 |
* (Egervary Research Group on Combinatorial Optimization, EGRES). |
8 | 8 |
* |
9 | 9 |
* Permission to use, modify and distribute this software is granted |
... | ... |
@@ -15,13 +15,13 @@ |
15 | 15 |
* purpose. |
16 | 16 |
* |
17 | 17 |
*/ |
18 | 18 |
|
19 | 19 |
/*! |
20 | 20 |
|
21 |
\page coding_style LEMON Coding Style |
|
21 |
\page coding_style LEMON Coding Style |
|
22 | 22 |
|
23 | 23 |
\section naming_conv Naming Conventions |
24 | 24 |
|
25 | 25 |
In order to make development easier we have made some conventions |
26 | 26 |
according to coding style. These include names of types, classes, |
27 | 27 |
functions, variables, constants and exceptions. If these conventions |
... | ... |
@@ -65,37 +65,37 @@ |
65 | 65 |
|
66 | 66 |
\subsection cs-class Classes and other types |
67 | 67 |
|
68 | 68 |
The name of a class or any type should look like the following. |
69 | 69 |
|
70 | 70 |
\code |
71 |
AllWordsCapitalizedWithoutUnderscores |
|
71 |
AllWordsCapitalizedWithoutUnderscores |
|
72 | 72 |
\endcode |
73 | 73 |
|
74 | 74 |
\subsection cs-func Methods and other functions |
75 | 75 |
|
76 | 76 |
The name of a function should look like the following. |
77 | 77 |
|
78 | 78 |
\code |
79 |
firstWordLowerCaseRestCapitalizedWithoutUnderscores |
|
79 |
firstWordLowerCaseRestCapitalizedWithoutUnderscores |
|
80 | 80 |
\endcode |
81 | 81 |
|
82 | 82 |
\subsection cs-funcs Constants, Macros |
83 | 83 |
|
84 | 84 |
The names of constants and macros should look like the following. |
85 | 85 |
|
86 | 86 |
\code |
87 |
ALL_UPPER_CASE_WITH_UNDERSCORES |
|
87 |
ALL_UPPER_CASE_WITH_UNDERSCORES |
|
88 | 88 |
\endcode |
89 | 89 |
|
90 |
\subsection cs-loc-var Class and instance member variables, auto variables |
|
90 |
\subsection cs-loc-var Class and instance member variables, auto variables |
|
91 | 91 |
|
92 | 92 |
The names of class and instance member variables and auto variables (=variables used locally in methods) should look like the following. |
93 | 93 |
|
94 | 94 |
\code |
95 |
all_lower_case_with_underscores |
|
95 |
all_lower_case_with_underscores |
|
96 | 96 |
\endcode |
97 | 97 |
|
98 | 98 |
\subsection pri-loc-var Private member variables |
99 | 99 |
|
100 | 100 |
Private member variables should start with underscore |
101 | 101 |
1 |
/* -*- C++ -*- |
|
1 |
/* -*- mode: C++; indent-tabs-mode: nil; -*- |
|
2 | 2 |
* |
3 |
* This file is a part of LEMON, a generic C++ optimization library |
|
3 |
* This file is a part of LEMON, a generic C++ optimization library. |
|
4 | 4 |
* |
5 | 5 |
* Copyright (C) 2003-2008 |
6 | 6 |
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
7 | 7 |
* (Egervary Research Group on Combinatorial Optimization, EGRES). |
8 | 8 |
* |
9 | 9 |
* Permission to use, modify and distribute this software is granted |
... | ... |
@@ -71,9 +71,9 @@ |
71 | 71 |
|
72 | 72 |
/** |
73 | 73 |
\dir bits |
74 | 74 |
\brief Implementation helper files |
75 | 75 |
|
76 | 76 |
This directory contains some helper classes to implement graphs, maps and |
77 |
some other classes. As a user you typically don't have to deal with these |
|
77 |
some other classes. As a user you typically don't have to deal with these |
|
78 | 78 |
files. |
79 | 79 |
*/ |
1 |
/* -*- C++ -*- |
|
1 |
/* -*- mode: C++; indent-tabs-mode: nil; -*- |
|
2 | 2 |
* |
3 |
* This file is a part of LEMON, a generic C++ optimization library |
|
3 |
* This file is a part of LEMON, a generic C++ optimization library. |
|
4 | 4 |
* |
5 | 5 |
* Copyright (C) 2003-2008 |
6 | 6 |
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
7 | 7 |
* (Egervary Research Group on Combinatorial Optimization, EGRES). |
8 | 8 |
* |
9 | 9 |
* Permission to use, modify and distribute this software is granted |
... | ... |
@@ -23,66 +23,66 @@ |
23 | 23 |
|
24 | 24 |
/** |
25 | 25 |
@defgroup graphs Graph Structures |
26 | 26 |
@ingroup datas |
27 | 27 |
\brief Graph structures implemented in LEMON. |
28 | 28 |
|
29 |
The implementation of combinatorial algorithms heavily relies on |
|
30 |
efficient graph implementations. LEMON offers data structures which are |
|
31 |
planned to be easily used in an experimental phase of implementation studies, |
|
32 |
and thereafter the program code can be made efficient by small modifications. |
|
29 |
The implementation of combinatorial algorithms heavily relies on |
|
30 |
efficient graph implementations. LEMON offers data structures which are |
|
31 |
planned to be easily used in an experimental phase of implementation studies, |
|
32 |
and thereafter the program code can be made efficient by small modifications. |
|
33 | 33 |
|
34 | 34 |
The most efficient implementation of diverse applications require the |
35 | 35 |
usage of different physical graph implementations. These differences |
36 | 36 |
appear in the size of graph we require to handle, memory or time usage |
37 | 37 |
limitations or in the set of operations through which the graph can be |
38 | 38 |
accessed. LEMON provides several physical graph structures to meet |
39 | 39 |
the diverging requirements of the possible users. In order to save on |
40 | 40 |
running time or on memory usage, some structures may fail to provide |
41 | 41 |
some graph features like arc/edge or node deletion. |
42 | 42 |
|
43 |
Alteration of standard containers need a very limited number of |
|
44 |
operations, these together satisfy the everyday requirements. |
|
45 |
In the case of graph structures, different operations are needed which do |
|
46 |
not alter the physical graph, but gives another view. If some nodes or |
|
43 |
Alteration of standard containers need a very limited number of |
|
44 |
operations, these together satisfy the everyday requirements. |
|
45 |
In the case of graph structures, different operations are needed which do |
|
46 |
not alter the physical graph, but gives another view. If some nodes or |
|
47 | 47 |
arcs have to be hidden or the reverse oriented graph have to be used, then |
48 |
this is the case. It also may happen that in a flow implementation |
|
49 |
the residual graph can be accessed by another algorithm, or a node-set |
|
50 |
is to be shrunk for another algorithm. |
|
51 |
LEMON also provides a variety of graphs for these requirements called |
|
52 |
\ref graph_adaptors "graph adaptors". Adaptors cannot be used alone but only |
|
53 |
in conjunction with other graph representations. |
|
48 |
this is the case. It also may happen that in a flow implementation |
|
49 |
the residual graph can be accessed by another algorithm, or a node-set |
|
50 |
is to be shrunk for another algorithm. |
|
51 |
LEMON also provides a variety of graphs for these requirements called |
|
52 |
\ref graph_adaptors "graph adaptors". Adaptors cannot be used alone but only |
|
53 |
in conjunction with other graph representations. |
|
54 | 54 |
|
55 | 55 |
You are free to use the graph structure that fit your requirements |
56 | 56 |
the best, most graph algorithms and auxiliary data structures can be used |
57 |
with any graph structures. |
|
57 |
with any graph structures. |
|
58 | 58 |
*/ |
59 | 59 |
|
60 | 60 |
/** |
61 | 61 |
@defgroup semi_adaptors Semi-Adaptor Classes for Graphs |
62 | 62 |
@ingroup graphs |
63 | 63 |
\brief Graph types between real graphs and graph adaptors. |
64 | 64 |
|
65 | 65 |
This group describes some graph types between real graphs and graph adaptors. |
66 |
These classes wrap graphs to give new functionality as the adaptors do it. |
|
66 |
These classes wrap graphs to give new functionality as the adaptors do it. |
|
67 | 67 |
On the other hand they are not light-weight structures as the adaptors. |
68 | 68 |
*/ |
69 | 69 |
|
70 | 70 |
/** |
71 |
@defgroup maps Maps |
|
71 |
@defgroup maps Maps |
|
72 | 72 |
@ingroup datas |
73 | 73 |
\brief Map structures implemented in LEMON. |
74 | 74 |
|
75 | 75 |
This group describes the map structures implemented in LEMON. |
76 | 76 |
|
77 | 77 |
LEMON provides several special purpose maps that e.g. combine |
78 | 78 |
new maps from existing ones. |
79 | 79 |
*/ |
80 | 80 |
|
81 | 81 |
/** |
82 |
@defgroup graph_maps Graph Maps |
|
82 |
@defgroup graph_maps Graph Maps |
|
83 | 83 |
@ingroup maps |
84 | 84 |
\brief Special graph-related maps. |
85 | 85 |
|
86 | 86 |
This group describes maps that are specifically designed to assign |
87 | 87 |
values to the nodes and arcs of graphs. |
88 | 88 |
*/ |
... | ... |
@@ -112,20 +112,20 @@ |
112 | 112 |
} else if (deg == 1) { |
113 | 113 |
return Color(1.0, 0.5, 1.0); |
114 | 114 |
} else { |
115 | 115 |
return Color(0.0, 0.0, 0.0); |
116 | 116 |
} |
117 | 117 |
} |
118 |
|
|
118 |
|
|
119 | 119 |
Digraph::NodeMap<int> degree_map(graph); |
120 |
|
|
120 |
|
|
121 | 121 |
digraphToEps(graph, "graph.eps") |
122 | 122 |
.coords(coords).scaleToA4().undirected() |
123 | 123 |
.nodeColors(composeMap(functorToMap(nodeColor), degree_map)) |
124 | 124 |
.run(); |
125 |
\endcode |
|
125 |
\endcode |
|
126 | 126 |
The \c functorToMap() function makes an \c int to \c Color map from the |
127 | 127 |
\e nodeColor() function. The \c composeMap() compose the \e degree_map |
128 | 128 |
and the previously created map. The composed map is a proper function to |
129 | 129 |
get the color of each node. |
130 | 130 |
|
131 | 131 |
The usage with class type algorithms is little bit harder. In this |
... | ... |
@@ -137,25 +137,25 @@ |
137 | 137 |
typedef Digraph::ArcMap<double> DoubleArcMap; |
138 | 138 |
DoubleArcMap length(graph); |
139 | 139 |
DoubleArcMap speed(graph); |
140 | 140 |
|
141 | 141 |
typedef DivMap<DoubleArcMap, DoubleArcMap> TimeMap; |
142 | 142 |
TimeMap time(length, speed); |
143 |
|
|
143 |
|
|
144 | 144 |
Dijkstra<Digraph, TimeMap> dijkstra(graph, time); |
145 | 145 |
dijkstra.run(source, target); |
146 | 146 |
\endcode |
147 | 147 |
We have a length map and a maximum speed map on the arcs of a digraph. |
148 | 148 |
The minimum time to pass the arc can be calculated as the division of |
149 | 149 |
the two maps which can be done implicitly with the \c DivMap template |
150 | 150 |
class. We use the implicit minimum time map as the length map of the |
151 | 151 |
\c Dijkstra algorithm. |
152 | 152 |
*/ |
153 | 153 |
|
154 | 154 |
/** |
155 |
@defgroup matrices Matrices |
|
155 |
@defgroup matrices Matrices |
|
156 | 156 |
@ingroup datas |
157 | 157 |
\brief Two dimensional data storages implemented in LEMON. |
158 | 158 |
|
159 | 159 |
This group describes two dimensional data storages implemented in LEMON. |
160 | 160 |
*/ |
161 | 161 |
|
... | ... |
@@ -197,27 +197,27 @@ |
197 | 197 |
|
198 | 198 |
/** |
199 | 199 |
@defgroup search Graph Search |
200 | 200 |
@ingroup algs |
201 | 201 |
\brief Common graph search algorithms. |
202 | 202 |
|
203 |
This group describes the common graph search algorithms like |
|
203 |
This group describes the common graph search algorithms like |
|
204 | 204 |
Breadth-first search (Bfs) and Depth-first search (Dfs). |
205 | 205 |
*/ |
206 | 206 |
|
207 | 207 |
/** |
208 | 208 |
@defgroup shortest_path Shortest Path algorithms |
209 | 209 |
@ingroup algs |
210 | 210 |
\brief Algorithms for finding shortest paths. |
211 | 211 |
|
212 | 212 |
This group describes the algorithms for finding shortest paths in graphs. |
213 | 213 |
*/ |
214 | 214 |
|
215 |
/** |
|
216 |
@defgroup max_flow Maximum Flow algorithms |
|
217 |
|
|
215 |
/** |
|
216 |
@defgroup max_flow Maximum Flow algorithms |
|
217 |
@ingroup algs |
|
218 | 218 |
\brief Algorithms for finding maximum flows. |
219 | 219 |
|
220 | 220 |
This group describes the algorithms for finding maximum flows and |
221 | 221 |
feasible circulations. |
222 | 222 |
|
223 | 223 |
The maximum flow problem is to find a flow between a single source and |
... | ... |
@@ -228,13 +228,13 @@ |
228 | 228 |
|
229 | 229 |
\f[ 0 \le f_a \le c_a \f] |
230 | 230 |
\f[ \sum_{v\in\delta^{-}(u)}f_{vu}=\sum_{v\in\delta^{+}(u)}f_{uv} \qquad \forall u \in V \setminus \{s,t\}\f] |
231 | 231 |
\f[ \max \sum_{v\in\delta^{+}(s)}f_{uv} - \sum_{v\in\delta^{-}(s)}f_{vu}\f] |
232 | 232 |
|
233 | 233 |
LEMON contains several algorithms for solving maximum flow problems: |
234 |
- \ref lemon::EdmondsKarp "Edmonds-Karp" |
|
234 |
- \ref lemon::EdmondsKarp "Edmonds-Karp" |
|
235 | 235 |
- \ref lemon::Preflow "Goldberg's Preflow algorithm" |
236 | 236 |
- \ref lemon::DinitzSleatorTarjan "Dinitz's blocking flow algorithm with dynamic trees" |
237 | 237 |
- \ref lemon::GoldbergTarjan "Preflow algorithm with dynamic trees" |
238 | 238 |
|
239 | 239 |
In most cases the \ref lemon::Preflow "Preflow" algorithm provides the |
240 | 240 |
fastest method to compute the maximum flow. All impelementations |
... | ... |
@@ -247,18 +247,18 @@ |
247 | 247 |
@defgroup min_cost_flow Minimum Cost Flow algorithms |
248 | 248 |
@ingroup algs |
249 | 249 |
|
250 | 250 |
\brief Algorithms for finding minimum cost flows and circulations. |
251 | 251 |
|
252 | 252 |
This group describes the algorithms for finding minimum cost flows and |
253 |
circulations. |
|
253 |
circulations. |
|
254 | 254 |
*/ |
255 | 255 |
|
256 | 256 |
/** |
257 |
@defgroup min_cut Minimum Cut algorithms |
|
258 |
@ingroup algs |
|
257 |
@defgroup min_cut Minimum Cut algorithms |
|
258 |
@ingroup algs |
|
259 | 259 |
|
260 | 260 |
\brief Algorithms for finding minimum cut in graphs. |
261 | 261 |
|
262 | 262 |
This group describes the algorithms for finding minimum cut in graphs. |
263 | 263 |
|
264 | 264 |
The minimum cut problem is to find a non-empty and non-complete |
... | ... |
@@ -269,13 +269,13 @@ |
269 | 269 |
|
270 | 270 |
\f[ \min_{X \subset V, X\not\in \{\emptyset, V\}}\sum_{uv\in A, u\in X, v\not\in X}c_{uv}\f] |
271 | 271 |
|
272 | 272 |
LEMON contains several algorithms related to minimum cut problems: |
273 | 273 |
|
274 | 274 |
- \ref lemon::HaoOrlin "Hao-Orlin algorithm" to calculate minimum cut |
275 |
in directed graphs |
|
275 |
in directed graphs |
|
276 | 276 |
- \ref lemon::NagamochiIbaraki "Nagamochi-Ibaraki algorithm" to |
277 | 277 |
calculate minimum cut in undirected graphs |
278 | 278 |
- \ref lemon::GomoryHuTree "Gomory-Hu tree computation" to calculate all |
279 | 279 |
pairs minimum cut in undirected graphs |
280 | 280 |
|
281 | 281 |
If you want to find minimum cut just between two distinict nodes, |
... | ... |
@@ -304,38 +304,38 @@ |
304 | 304 |
|
305 | 305 |
\image html planar.png |
306 | 306 |
\image latex planar.eps "Plane graph" width=\textwidth |
307 | 307 |
*/ |
308 | 308 |
|
309 | 309 |
/** |
310 |
@defgroup matching Matching algorithms |
|
310 |
@defgroup matching Matching algorithms |
|
311 | 311 |
@ingroup algs |
312 | 312 |
\brief Algorithms for finding matchings in graphs and bipartite graphs. |
313 | 313 |
|
314 | 314 |
This group contains algorithm objects and functions to calculate |
315 | 315 |
matchings in graphs and bipartite graphs. The general matching problem is |
316 | 316 |
finding a subset of the arcs which does not shares common endpoints. |
317 |
|
|
317 |
|
|
318 | 318 |
There are several different algorithms for calculate matchings in |
319 | 319 |
graphs. The matching problems in bipartite graphs are generally |
320 | 320 |
easier than in general graphs. The goal of the matching optimization |
321 | 321 |
can be the finding maximum cardinality, maximum weight or minimum cost |
322 | 322 |
matching. The search can be constrained to find perfect or |
323 | 323 |
maximum cardinality matching. |
324 | 324 |
|
325 | 325 |
Lemon contains the next algorithms: |
326 |
- \ref lemon::MaxBipartiteMatching "MaxBipartiteMatching" Hopcroft-Karp |
|
327 |
augmenting path algorithm for calculate maximum cardinality matching in |
|
326 |
- \ref lemon::MaxBipartiteMatching "MaxBipartiteMatching" Hopcroft-Karp |
|
327 |
augmenting path algorithm for calculate maximum cardinality matching in |
|
328 | 328 |
bipartite graphs |
329 |
- \ref lemon::PrBipartiteMatching "PrBipartiteMatching" Push-Relabel |
|
330 |
algorithm for calculate maximum cardinality matching in bipartite graphs |
|
331 |
- \ref lemon::MaxWeightedBipartiteMatching "MaxWeightedBipartiteMatching" |
|
332 |
Successive shortest path algorithm for calculate maximum weighted matching |
|
329 |
- \ref lemon::PrBipartiteMatching "PrBipartiteMatching" Push-Relabel |
|
330 |
algorithm for calculate maximum cardinality matching in bipartite graphs |
|
331 |
- \ref lemon::MaxWeightedBipartiteMatching "MaxWeightedBipartiteMatching" |
|
332 |
Successive shortest path algorithm for calculate maximum weighted matching |
|
333 | 333 |
and maximum weighted bipartite matching in bipartite graph |
334 |
- \ref lemon::MinCostMaxBipartiteMatching "MinCostMaxBipartiteMatching" |
|
335 |
Successive shortest path algorithm for calculate minimum cost maximum |
|
334 |
- \ref lemon::MinCostMaxBipartiteMatching "MinCostMaxBipartiteMatching" |
|
335 |
Successive shortest path algorithm for calculate minimum cost maximum |
|
336 | 336 |
matching in bipartite graph |
337 | 337 |
- \ref lemon::MaxMatching "MaxMatching" Edmond's blossom shrinking algorithm |
338 | 338 |
for calculate maximum cardinality matching in general graph |
339 | 339 |
- \ref lemon::MaxWeightedMatching "MaxWeightedMatching" Edmond's blossom |
340 | 340 |
shrinking algorithm for calculate maximum weighted matching in general |
341 | 341 |
graph |
... | ... |
@@ -393,14 +393,14 @@ |
393 | 393 |
This group describes Lp and Mip solver interfaces for LEMON. The |
394 | 394 |
various LP solvers could be used in the same manner with this |
395 | 395 |
interface. |
396 | 396 |
|
397 | 397 |
*/ |
398 | 398 |
|
399 |
/** |
|
400 |
@defgroup lp_utils Tools for Lp and Mip solvers |
|
399 |
/** |
|
400 |
@defgroup lp_utils Tools for Lp and Mip solvers |
|
401 | 401 |
@ingroup lp_group |
402 | 402 |
\brief Helper tools to the Lp and Mip solvers. |
403 | 403 |
|
404 | 404 |
This group adds some helper tools to general optimization framework |
405 | 405 |
implemented in LEMON. |
406 | 406 |
*/ |
... | ... |
@@ -411,13 +411,13 @@ |
411 | 411 |
\brief Metaheuristics for LEMON library. |
412 | 412 |
|
413 | 413 |
This group describes some metaheuristic optimization tools. |
414 | 414 |
*/ |
415 | 415 |
|
416 | 416 |
/** |
417 |
@defgroup utils Tools and Utilities |
|
417 |
@defgroup utils Tools and Utilities |
|
418 | 418 |
\brief Tools and utilities for programming in LEMON |
419 | 419 |
|
420 | 420 |
Tools and utilities for programming in LEMON. |
421 | 421 |
*/ |
422 | 422 |
|
423 | 423 |
/** |
... | ... |
@@ -464,13 +464,13 @@ |
464 | 464 |
*/ |
465 | 465 |
|
466 | 466 |
/** |
467 | 467 |
@defgroup io_group Input-Output |
468 | 468 |
\brief Graph Input-Output methods |
469 | 469 |
|
470 |
This group describes the tools for importing and exporting graphs |
|
470 |
This group describes the tools for importing and exporting graphs |
|
471 | 471 |
and graph related data. Now it supports the LEMON format, the |
472 | 472 |
\c DIMACS format and the encapsulated postscript (EPS) format. |
473 | 473 |
*/ |
474 | 474 |
|
475 | 475 |
/** |
476 | 476 |
@defgroup lemon_io Lemon Input-Output |
... | ... |
@@ -483,25 +483,25 @@ |
483 | 483 |
/** |
484 | 484 |
@defgroup eps_io Postscript exporting |
485 | 485 |
@ingroup io_group |
486 | 486 |
\brief General \c EPS drawer and graph exporter |
487 | 487 |
|
488 | 488 |
This group describes general \c EPS drawing methods and special |
489 |
graph exporting tools. |
|
489 |
graph exporting tools. |
|
490 | 490 |
*/ |
491 | 491 |
|
492 | 492 |
|
493 | 493 |
/** |
494 | 494 |
@defgroup concept Concepts |
495 | 495 |
\brief Skeleton classes and concept checking classes |
496 | 496 |
|
497 | 497 |
This group describes the data/algorithm skeletons and concept checking |
498 | 498 |
classes implemented in LEMON. |
499 | 499 |
|
500 | 500 |
The purpose of the classes in this group is fourfold. |
501 |
|
|
501 |
|
|
502 | 502 |
- These classes contain the documentations of the concepts. In order |
503 | 503 |
to avoid document multiplications, an implementation of a concept |
504 | 504 |
simply refers to the corresponding concept class. |
505 | 505 |
|
506 | 506 |
- These classes declare every functions, <tt>typedef</tt>s etc. an |
507 | 507 |
implementation of the concepts should provide, however completely |
... | ... |
@@ -548,12 +548,12 @@ |
548 | 548 |
build the library. |
549 | 549 |
*/ |
550 | 550 |
|
551 | 551 |
/** |
552 | 552 |
@defgroup tools Standalone utility applications |
553 | 553 |
|
554 |
Some utility applications are listed here. |
|
554 |
Some utility applications are listed here. |
|
555 | 555 |
|
556 | 556 |
The standard compilation procedure (<tt>./configure;make</tt>) will compile |
557 |
them, as well. |
|
557 |
them, as well. |
|
558 | 558 |
*/ |
559 | 559 |
1 |
/* -*- C++ -*- |
|
1 |
/* -*- mode: C++; indent-tabs-mode: nil; -*- |
|
2 | 2 |
* |
3 |
* This file is a part of LEMON, a generic C++ optimization library |
|
3 |
* This file is a part of LEMON, a generic C++ optimization library. |
|
4 | 4 |
* |
5 | 5 |
* Copyright (C) 2003-2008 |
6 | 6 |
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
7 | 7 |
* (Egervary Research Group on Combinatorial Optimization, EGRES). |
8 | 8 |
* |
9 | 9 |
* Permission to use, modify and distribute this software is granted |
... | ... |
@@ -40,13 +40,13 @@ |
40 | 40 |
|
41 | 41 |
The standard sections are column oriented, each line consists of |
42 | 42 |
<em>token</em>s separated by whitespaces. A token can be \e plain or |
43 | 43 |
\e quoted. A plain token is just a sequence of non-whitespace characters, |
44 | 44 |
while a quoted token is a |
45 | 45 |
character sequence surrounded by double quotes, and it can also |
46 |
contain whitespaces and escape sequences. |
|
46 |
contain whitespaces and escape sequences. |
|
47 | 47 |
|
48 | 48 |
The \c \@nodes section describes a set of nodes and associated |
49 | 49 |
maps. The first is a header line, its columns are the names of the |
50 | 50 |
maps appearing in the following lines. |
51 | 51 |
One of the maps must be called \c |
52 | 52 |
"label", which plays special role in the file. |
... | ... |
@@ -69,13 +69,13 @@ |
69 | 69 |
describe the arcs. The first two tokens of each line are |
70 | 70 |
the source and the target node of the arc, respectively, then come the map |
71 | 71 |
values. The source and target tokens must be node labels. |
72 | 72 |
|
73 | 73 |
\code |
74 | 74 |
@arcs |
75 |
|
|
75 |
capacity |
|
76 | 76 |
1 2 16 |
77 | 77 |
1 3 12 |
78 | 78 |
2 3 18 |
79 | 79 |
\endcode |
80 | 80 |
|
81 | 81 |
The \c \@edges is just a synonym of \c \@arcs. The @arcs section can |
1 |
/* -*- C++ -*- |
|
1 |
/* -*- mode: C++; indent-tabs-mode: nil; -*- |
|
2 | 2 |
* |
3 |
* This file is a part of LEMON, a generic C++ optimization library |
|
3 |
* This file is a part of LEMON, a generic C++ optimization library. |
|
4 | 4 |
* |
5 | 5 |
* Copyright (C) 2003-2008 |
6 | 6 |
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
7 | 7 |
* (Egervary Research Group on Combinatorial Optimization, EGRES). |
8 | 8 |
* |
9 | 9 |
* Permission to use, modify and distribute this software is granted |
1 |
/* -*- C++ -*- |
|
1 |
/* -*- mode: C++; indent-tabs-mode: nil; -*- |
|
2 | 2 |
* |
3 |
* This file is a part of LEMON, a generic C++ optimization library |
|
3 |
* This file is a part of LEMON, a generic C++ optimization library. |
|
4 | 4 |
* |
5 | 5 |
* Copyright (C) 2003-2008 |
6 | 6 |
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
7 | 7 |
* (Egervary Research Group on Combinatorial Optimization, EGRES). |
8 | 8 |
* |
9 | 9 |
* Permission to use, modify and distribute this software is granted |
... | ... |
@@ -38,21 +38,21 @@ |
38 | 38 |
non-commercial applications under very permissive |
39 | 39 |
\ref license "license terms". |
40 | 40 |
</b> |
41 | 41 |
|
42 | 42 |
\subsection howtoread How to read the documentation |
43 | 43 |
|
44 |
If you want to get a quick start and see the most important features then |
|
44 |
If you want to get a quick start and see the most important features then |
|
45 | 45 |
take a look at our \ref quicktour |
46 | 46 |
"Quick Tour to LEMON" which will guide you along. |
47 | 47 |
|
48 |
If you already feel like using our library, see the page that tells you |
|
48 |
If you already feel like using our library, see the page that tells you |
|
49 | 49 |
\ref getstart "How to start using LEMON". |
50 | 50 |
|
51 |
If you |
|
52 |
want to see how LEMON works, see |
|
51 |
If you |
|
52 |
want to see how LEMON works, see |
|
53 | 53 |
some \ref demoprograms "demo programs"! |
54 | 54 |
|
55 | 55 |
If you know what you are looking for then try to find it under the |
56 | 56 |
<a class="el" href="modules.html">Modules</a> |
57 | 57 |
section. |
58 | 58 |
1 |
/* -*- C++ -*- |
|
1 |
/* -*- mode: C++; indent-tabs-mode: nil; -*- |
|
2 | 2 |
* |
3 |
* This file is a part of LEMON, a generic C++ optimization library |
|
3 |
* This file is a part of LEMON, a generic C++ optimization library. |
|
4 | 4 |
* |
5 | 5 |
* Copyright (C) 2003-2008 |
6 | 6 |
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
7 | 7 |
* (Egervary Research Group on Combinatorial Optimization, EGRES). |
8 | 8 |
* |
9 | 9 |
* Permission to use, modify and distribute this software is granted |
1 |
/* -*- C++ -*- |
|
1 |
/* -*- mode: C++; indent-tabs-mode: nil; -*- |
|
2 | 2 |
* |
3 |
* This file is a part of LEMON, a generic C++ optimization library |
|
3 |
* This file is a part of LEMON, a generic C++ optimization library. |
|
4 | 4 |
* |
5 | 5 |
* Copyright (C) 2003-2008 |
6 | 6 |
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
7 | 7 |
* (Egervary Research Group on Combinatorial Optimization, EGRES). |
8 | 8 |
* |
9 | 9 |
* Permission to use, modify and distribute this software is granted |
1 |
/* -*- C++ -*- |
|
1 |
/* -*- mode: C++; indent-tabs-mode: nil; -*- |
|
2 | 2 |
* |
3 |
* This file is a part of LEMON, a generic C++ optimization library |
|
3 |
* This file is a part of LEMON, a generic C++ optimization library. |
|
4 | 4 |
* |
5 | 5 |
* Copyright (C) 2003-2008 |
6 | 6 |
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
7 | 7 |
* (Egervary Research Group on Combinatorial Optimization, EGRES). |
8 | 8 |
* |
9 | 9 |
* Permission to use, modify and distribute this software is granted |
... | ... |
@@ -35,92 +35,92 @@ |
35 | 35 |
} |
36 | 36 |
|
37 | 37 |
ArgParser::~ArgParser() |
38 | 38 |
{ |
39 | 39 |
for(Opts::iterator i=_opts.begin();i!=_opts.end();++i) |
40 | 40 |
if(i->second.self_delete) |
41 |
switch(i->second.type) { |
|
42 |
case BOOL: |
|
43 |
delete i->second.bool_p; |
|
44 |
break; |
|
45 |
case STRING: |
|
46 |
delete i->second.string_p; |
|
47 |
break; |
|
48 |
case DOUBLE: |
|
49 |
delete i->second.double_p; |
|
50 |
break; |
|
51 |
case INTEGER: |
|
52 |
delete i->second.int_p; |
|
53 |
break; |
|
54 |
case UNKNOWN: |
|
55 |
break; |
|
56 |
case FUNC: |
|
57 |
break; |
|
58 |
} |
|
41 |
switch(i->second.type) { |
|
42 |
case BOOL: |
|
43 |
delete i->second.bool_p; |
|
44 |
break; |
|
45 |
case STRING: |
|
46 |
delete i->second.string_p; |
|
47 |
break; |
|
48 |
case DOUBLE: |
|
49 |
delete i->second.double_p; |
|
50 |
break; |
|
51 |
case INTEGER: |
|
52 |
delete i->second.int_p; |
|
53 |
break; |
|
54 |
case UNKNOWN: |
|
55 |
break; |
|
56 |
case FUNC: |
|
57 |
break; |
|
58 |
} |
|
59 | 59 |
} |
60 |
|
|
60 |
|
|
61 | 61 |
|
62 | 62 |
ArgParser &ArgParser::intOption(const std::string &name, |
63 |
const std::string &help, |
|
64 |
int value, bool obl) |
|
63 |
const std::string &help, |
|
64 |
int value, bool obl) |
|
65 | 65 |
{ |
66 | 66 |
ParData p; |
67 | 67 |
p.int_p=new int(value); |
68 | 68 |
p.self_delete=true; |
69 | 69 |
p.help=help; |
70 | 70 |
p.type=INTEGER; |
71 | 71 |
p.mandatory=obl; |
72 | 72 |
_opts[name]=p; |
73 | 73 |
return *this; |
74 | 74 |
} |
75 | 75 |
|
76 | 76 |
ArgParser &ArgParser::doubleOption(const std::string &name, |
77 |
const std::string &help, |
|
78 |
double value, bool obl) |
|
77 |
const std::string &help, |
|
78 |
double value, bool obl) |
|
79 | 79 |
{ |
80 | 80 |
ParData p; |
81 | 81 |
p.double_p=new double(value); |
82 | 82 |
p.self_delete=true; |
83 | 83 |
p.help=help; |
84 | 84 |
p.type=DOUBLE; |
85 | 85 |
p.mandatory=obl; |
86 | 86 |
_opts[name]=p; |
87 | 87 |
return *this; |
88 | 88 |
} |
89 | 89 |
|
90 | 90 |
ArgParser &ArgParser::boolOption(const std::string &name, |
91 |
const std::string &help, |
|
92 |
bool value, bool obl) |
|
91 |
const std::string &help, |
|
92 |
bool value, bool obl) |
|
93 | 93 |
{ |
94 | 94 |
ParData p; |
95 | 95 |
p.bool_p=new bool(value); |
96 | 96 |
p.self_delete=true; |
97 | 97 |
p.help=help; |
98 | 98 |
p.type=BOOL; |
99 | 99 |
p.mandatory=obl; |
100 | 100 |
_opts[name]=p; |
101 | 101 |
return *this; |
102 | 102 |
} |
103 | 103 |
|
104 | 104 |
ArgParser &ArgParser::stringOption(const std::string &name, |
105 |
const std::string &help, |
|
106 |
std::string value, bool obl) |
|
105 |
const std::string &help, |
|
106 |
std::string value, bool obl) |
|
107 | 107 |
{ |
108 | 108 |
ParData p; |
109 | 109 |
p.string_p=new std::string(value); |
110 | 110 |
p.self_delete=true; |
111 | 111 |
p.help=help; |
112 | 112 |
p.type=STRING; |
113 | 113 |
p.mandatory=obl; |
114 | 114 |
_opts[name]=p; |
115 | 115 |
return *this; |
116 | 116 |
} |
117 | 117 |
|
118 | 118 |
ArgParser &ArgParser::refOption(const std::string &name, |
119 |
const std::string &help, |
|
120 |
int &ref, bool obl) |
|
119 |
const std::string &help, |
|
120 |
int &ref, bool obl) |
|
121 | 121 |
{ |
122 | 122 |
ParData p; |
123 | 123 |
p.int_p=&ref; |
124 | 124 |
p.self_delete=false; |
125 | 125 |
p.help=help; |
126 | 126 |
p.type=INTEGER; |
... | ... |
@@ -158,28 +158,28 @@ |
158 | 158 |
ref = false; |
159 | 159 |
|
160 | 160 |
return *this; |
161 | 161 |
} |
162 | 162 |
|
163 | 163 |
ArgParser &ArgParser::refOption(const std::string &name, |
164 |
const std::string &help, |
|
165 |
std::string &ref, bool obl) |
|
164 |
const std::string &help, |
|
165 |
std::string &ref, bool obl) |
|
166 | 166 |
{ |
167 | 167 |
ParData p; |
168 | 168 |
p.string_p=&ref; |
169 | 169 |
p.self_delete=false; |
170 | 170 |
p.help=help; |
171 | 171 |
p.type=STRING; |
172 | 172 |
p.mandatory=obl; |
173 | 173 |
_opts[name]=p; |
174 | 174 |
return *this; |
175 | 175 |
} |
176 | 176 |
|
177 | 177 |
ArgParser &ArgParser::funcOption(const std::string &name, |
178 |
const std::string &help, |
|
179 |
void (*func)(void *),void *data) |
|
178 |
const std::string &help, |
|
179 |
void (*func)(void *),void *data) |
|
180 | 180 |
{ |
181 | 181 |
ParData p; |
182 | 182 |
p.func_p.p=func; |
183 | 183 |
p.func_p.data=data; |
184 | 184 |
p.self_delete=false; |
185 | 185 |
p.help=help; |
... | ... |
@@ -187,17 +187,17 @@ |
187 | 187 |
p.mandatory=false; |
188 | 188 |
_opts[name]=p; |
189 | 189 |
return *this; |
190 | 190 |
} |
191 | 191 |
|
192 | 192 |
ArgParser &ArgParser::optionGroup(const std::string &group, |
193 |
|
|
193 |
const std::string &opt) |
|
194 | 194 |
{ |
195 | 195 |
Opts::iterator i = _opts.find(opt); |
196 | 196 |
LEMON_ASSERT(i!=_opts.end(), "Unknown option: '"+opt+"'"); |
197 |
LEMON_ASSERT(!(i->second.ingroup), |
|
197 |
LEMON_ASSERT(!(i->second.ingroup), |
|
198 | 198 |
"Option already in option group: '"+opt+"'"); |
199 | 199 |
GroupData &g=_groups[group]; |
200 | 200 |
g.opts.push_back(opt); |
201 | 201 |
i->second.ingroup=true; |
202 | 202 |
return *this; |
203 | 203 |
} |
... | ... |
@@ -207,13 +207,13 @@ |
207 | 207 |
GroupData &g=_groups[group]; |
208 | 208 |
g.only_one=true; |
209 | 209 |
return *this; |
210 | 210 |
} |
211 | 211 |
|
212 | 212 |
ArgParser &ArgParser::synonym(const std::string &syn, |
213 |
|
|
213 |
const std::string &opt) |
|
214 | 214 |
{ |
215 | 215 |
Opts::iterator o = _opts.find(opt); |
216 | 216 |
Opts::iterator s = _opts.find(syn); |
217 | 217 |
LEMON_ASSERT(o!=_opts.end(), "Unknown option: '"+opt+"'"); |
218 | 218 |
LEMON_ASSERT(s==_opts.end(), "Option already used: '"+syn+"'"); |
219 | 219 |
ParData p; |
... | ... |
@@ -230,25 +230,25 @@ |
230 | 230 |
GroupData &g=_groups[group]; |
231 | 231 |
g.mandatory=true; |
232 | 232 |
return *this; |
233 | 233 |
} |
234 | 234 |
|
235 | 235 |
ArgParser &ArgParser::other(const std::string &name, |
236 |
|
|
236 |
const std::string &help) |
|
237 | 237 |
{ |
238 | 238 |
_others_help.push_back(OtherArg(name,help)); |
239 | 239 |
return *this; |
240 | 240 |
} |
241 | 241 |
|
242 | 242 |
void ArgParser::show(std::ostream &os,Opts::iterator i) |
243 | 243 |
{ |
244 | 244 |
os << "-" << i->first; |
245 | 245 |
if(i->second.has_syn) |
246 | 246 |
for(Opts::iterator j=_opts.begin();j!=_opts.end();++j) |
247 |
if(j->second.syn&&j->second.help==i->first) |
|
248 |
os << "|-" << j->first; |
|
247 |
if(j->second.syn&&j->second.help==i->first) |
|
248 |
os << "|-" << j->first; |
|
249 | 249 |
switch(i->second.type) { |
250 | 250 |
case STRING: |
251 | 251 |
os << " str"; |
252 | 252 |
break; |
253 | 253 |
case INTEGER: |
254 | 254 |
os << " int"; |
... | ... |
@@ -267,28 +267,28 @@ |
267 | 267 |
while(o!=i->second.opts.end()) { |
268 | 268 |
show(os,_opts.find(*o)); |
269 | 269 |
++o; |
270 | 270 |
if(o!=i->second.opts.end()) os<<'|'; |
271 | 271 |
} |
272 | 272 |
} |
273 |
|
|
273 |
|
|
274 | 274 |
void ArgParser::showHelp(Opts::iterator i) |
275 | 275 |
{ |
276 | 276 |
if(i->second.help.size()==0||i->second.syn) return; |
277 | 277 |
std::cerr << " "; |
278 | 278 |
show(std::cerr,i); |
279 | 279 |
std::cerr << std::endl; |
280 | 280 |
std::cerr << " " << i->second.help << std::endl; |
281 | 281 |
} |
282 | 282 |
void ArgParser::showHelp(std::vector<ArgParser::OtherArg>::iterator i) |
283 | 283 |
{ |
284 | 284 |
if(i->help.size()==0) return; |
285 | 285 |
std::cerr << " " << i->name << std::endl |
286 |
|
|
286 |
<< " " << i->help << std::endl; |
|
287 | 287 |
} |
288 |
|
|
288 |
|
|
289 | 289 |
void ArgParser::shortHelp() |
290 | 290 |
{ |
291 | 291 |
const unsigned int LINE_LEN=77; |
292 | 292 |
const std::string indent(" "); |
293 | 293 |
std::cerr << "Usage:\n " << _command_name; |
294 | 294 |
int pos=_command_name.size()+2; |
... | ... |
@@ -296,68 +296,68 @@ |
296 | 296 |
std::ostringstream cstr; |
297 | 297 |
cstr << ' '; |
298 | 298 |
if(!g->second.mandatory) cstr << '['; |
299 | 299 |
show(cstr,g); |
300 | 300 |
if(!g->second.mandatory) cstr << ']'; |
301 | 301 |
if(pos+cstr.str().size()>LINE_LEN) { |
302 |
std::cerr << std::endl << indent; |
|
303 |
pos=indent.size(); |
|
302 |
std::cerr << std::endl << indent; |
|
303 |
pos=indent.size(); |
|
304 | 304 |
} |
305 | 305 |
std::cerr << cstr.str(); |
306 | 306 |
pos+=cstr.str().size(); |
307 | 307 |
} |
308 | 308 |
for(Opts::iterator i=_opts.begin();i!=_opts.end();++i) |
309 | 309 |
if(!i->second.ingroup&&!i->second.syn) { |
310 |
std::ostringstream cstr; |
|
311 |
cstr << ' '; |
|
312 |
if(!i->second.mandatory) cstr << '['; |
|
313 |
show(cstr,i); |
|
314 |
if(!i->second.mandatory) cstr << ']'; |
|
315 |
if(pos+cstr.str().size()>LINE_LEN) { |
|
316 |
std::cerr << std::endl << indent; |
|
317 |
pos=indent.size(); |
|
318 |
} |
|
319 |
std::cerr << cstr.str(); |
|
320 |
|
|
310 |
std::ostringstream cstr; |
|
311 |
cstr << ' '; |
|
312 |
if(!i->second.mandatory) cstr << '['; |
|
313 |
show(cstr,i); |
|
314 |
if(!i->second.mandatory) cstr << ']'; |
|
315 |
if(pos+cstr.str().size()>LINE_LEN) { |
|
316 |
std::cerr << std::endl << indent; |
|
317 |
pos=indent.size(); |
|
318 |
} |
|
319 |
std::cerr << cstr.str(); |
|
320 |
pos+=cstr.str().size(); |
|
321 | 321 |
} |
322 | 322 |
for(std::vector<OtherArg>::iterator i=_others_help.begin(); |
323 |
|
|
323 |
i!=_others_help.end();++i) |
|
324 | 324 |
{ |
325 |
std::ostringstream cstr; |
|
326 |
cstr << ' ' << i->name; |
|
327 |
|
|
328 |
if(pos+cstr.str().size()>LINE_LEN) { |
|
329 |
std::cerr << std::endl << indent; |
|
330 |
pos=indent.size(); |
|
331 |
} |
|
332 |
std::cerr << cstr.str(); |
|
333 |
|
|
325 |
std::ostringstream cstr; |
|
326 |
cstr << ' ' << i->name; |
|
327 |
|
|
328 |
if(pos+cstr.str().size()>LINE_LEN) { |
|
329 |
std::cerr << std::endl << indent; |
|
330 |
pos=indent.size(); |
|
331 |
} |
|
332 |
std::cerr << cstr.str(); |
|
333 |
pos+=cstr.str().size(); |
|
334 | 334 |
} |
335 | 335 |
std::cerr << std::endl; |
336 | 336 |
} |
337 |
|
|
337 |
|
|
338 | 338 |
void ArgParser::showHelp() |
339 | 339 |
{ |
340 | 340 |
shortHelp(); |
341 | 341 |
std::cerr << "Where:\n"; |
342 | 342 |
for(std::vector<OtherArg>::iterator i=_others_help.begin(); |
343 |
|
|
343 |
i!=_others_help.end();++i) showHelp(i); |
|
344 | 344 |
for(Opts::iterator i=_opts.begin();i!=_opts.end();++i) showHelp(i); |
345 | 345 |
exit(1); |
346 | 346 |
} |
347 |
|
|
348 |
|
|
349 |
|
|
347 |
|
|
348 |
|
|
349 |
void ArgParser::unknownOpt(std::string arg) |
|
350 | 350 |
{ |
351 | 351 |
std::cerr << "\nUnknown option: " << arg << "\n"; |
352 | 352 |
std::cerr << "\nType '" << _command_name << |
353 | 353 |
" --help' to obtain a short summary on the usage.\n\n"; |
354 | 354 |
exit(1); |
355 | 355 |
} |
356 |
|
|
357 |
void ArgParser::requiresValue(std::string arg, OptType t) |
|
356 |
|
|
357 |
void ArgParser::requiresValue(std::string arg, OptType t) |
|
358 | 358 |
{ |
359 | 359 |
std::cerr << "Argument '" << arg << "' requires a"; |
360 | 360 |
switch(t) { |
361 | 361 |
case STRING: |
362 | 362 |
std::cerr << " string"; |
363 | 363 |
break; |
... | ... |
@@ -370,96 +370,96 @@ |
370 | 370 |
default: |
371 | 371 |
break; |
372 | 372 |
} |
373 | 373 |
std::cerr << " value\n\n"; |
374 | 374 |
showHelp(); |
375 | 375 |
} |
376 |
|
|
376 |
|
|
377 | 377 |
|
378 | 378 |
void ArgParser::checkMandatories() |
379 | 379 |
{ |
380 | 380 |
bool ok=true; |
381 | 381 |
for(Opts::iterator i=_opts.begin();i!=_opts.end();++i) |
382 |
if(i->second.mandatory&&!i->second.set) |
|
383 |
{ |
|
384 |
if(ok) |
|
385 |
std::cerr << _command_name |
|
386 |
<< ": The following mandatory arguments are missing.\n"; |
|
387 |
ok=false; |
|
388 |
showHelp(i); |
|
389 |
} |
|
382 |
if(i->second.mandatory&&!i->second.set) |
|
383 |
{ |
|
384 |
if(ok) |
|
385 |
std::cerr << _command_name |
|
386 |
<< ": The following mandatory arguments are missing.\n"; |
|
387 |
ok=false; |
|
388 |
showHelp(i); |
|
389 |
} |
|
390 | 390 |
for(Groups::iterator i=_groups.begin();i!=_groups.end();++i) |
391 | 391 |
if(i->second.mandatory||i->second.only_one) |
392 |
{ |
|
393 |
int set=0; |
|
394 |
for(GroupData::Opts::iterator o=i->second.opts.begin(); |
|
395 |
o!=i->second.opts.end();++o) |
|
396 |
if(_opts.find(*o)->second.set) ++set; |
|
397 |
if(i->second.mandatory&&!set) { |
|
398 |
std::cerr << _command_name |
|
399 |
<< ": At least one of the following arguments is mandatory.\n"; |
|
400 |
ok=false; |
|
401 |
for(GroupData::Opts::iterator o=i->second.opts.begin(); |
|
402 |
o!=i->second.opts.end();++o) |
|
403 |
showHelp(_opts.find(*o)); |
|
404 |
} |
|
405 |
if(i->second.only_one&&set>1) { |
|
406 |
std::cerr << _command_name |
|
407 |
<< ": At most one of the following arguments can be given.\n"; |
|
408 |
ok=false; |
|
409 |
for(GroupData::Opts::iterator o=i->second.opts.begin(); |
|
410 |
o!=i->second.opts.end();++o) |
|
411 |
showHelp(_opts.find(*o)); |
|
412 |
} |
|
413 |
} |
|
392 |
{ |
|
393 |
int set=0; |
|
394 |
for(GroupData::Opts::iterator o=i->second.opts.begin(); |
|
395 |
o!=i->second.opts.end();++o) |
|
396 |
if(_opts.find(*o)->second.set) ++set; |
|
397 |
if(i->second.mandatory&&!set) { |
|
398 |
std::cerr << _command_name |
|
399 |
<< ": At least one of the following arguments is mandatory.\n"; |
|
400 |
ok=false; |
|
401 |
for(GroupData::Opts::iterator o=i->second.opts.begin(); |
|
402 |
o!=i->second.opts.end();++o) |
|
403 |
showHelp(_opts.find(*o)); |
|
404 |
} |
|
405 |
if(i->second.only_one&&set>1) { |
|
406 |
std::cerr << _command_name |
|
407 |
<< ": At most one of the following arguments can be given.\n"; |
|
408 |
ok=false; |
|
409 |
for(GroupData::Opts::iterator o=i->second.opts.begin(); |
|
410 |
o!=i->second.opts.end();++o) |
|
411 |
showHelp(_opts.find(*o)); |
|
412 |
} |
|
413 |
} |
|
414 | 414 |
if(!ok) { |
415 | 415 |
std::cerr << "\nType '" << _command_name << |
416 |
|
|
416 |
" --help' to obtain a short summary on the usage.\n\n"; |
|
417 | 417 |
exit(1); |
418 | 418 |
} |
419 | 419 |
} |
420 | 420 |
|
421 | 421 |
ArgParser &ArgParser::parse() |
422 | 422 |
{ |
423 | 423 |
for(int ar=1; ar<_argc; ++ar) { |
424 | 424 |
std::string arg(_argv[ar]); |
425 | 425 |
if (arg[0] != '-' || arg.size() == 1) { |
426 |
|
|
426 |
_file_args.push_back(arg); |
|
427 | 427 |
} |
428 | 428 |
else { |
429 |
Opts::iterator i = _opts.find(arg.substr(1)); |
|
430 |
if(i==_opts.end()) unknownOpt(arg); |
|
431 |
else { |
|
432 |
if(i->second.syn) i=_opts.find(i->second.help); |
|
433 |
ParData &p(i->second); |
|
434 |
if (p.type==BOOL) *p.bool_p=true; |
|
435 |
else if (p.type==FUNC) p.func_p.p(p.func_p.data); |
|
436 |
else if(++ar==_argc) requiresValue(arg, p.type); |
|
437 |
else { |
|
438 |
std::string val(_argv[ar]); |
|
439 |
std::istringstream vals(val); |
|
440 |
switch(p.type) { |
|
441 |
case STRING: |
|
442 |
*p.string_p=val; |
|
443 |
break; |
|
444 |
case INTEGER: |
|
445 |
vals >> *p.int_p; |
|
446 |
break; |
|
447 |
case DOUBLE: |
|
448 |
vals >> *p.double_p; |
|
449 |
break; |
|
450 |
default: |
|
451 |
break; |
|
452 |
} |
|
453 |
if(p.type!=STRING&&(!vals||!vals.eof())) |
|
454 |
requiresValue(arg, p.type); |
|
455 |
} |
|
456 |
p.set = true; |
|
457 |
|
|
429 |
Opts::iterator i = _opts.find(arg.substr(1)); |
|
430 |
if(i==_opts.end()) unknownOpt(arg); |
|
431 |
else { |
|
432 |
if(i->second.syn) i=_opts.find(i->second.help); |
|
433 |
ParData &p(i->second); |
|
434 |
if (p.type==BOOL) *p.bool_p=true; |
|
435 |
else if (p.type==FUNC) p.func_p.p(p.func_p.data); |
|
436 |
else if(++ar==_argc) requiresValue(arg, p.type); |
|
437 |
else { |
|
438 |
std::string val(_argv[ar]); |
|
439 |
std::istringstream vals(val); |
|
440 |
switch(p.type) { |
|
441 |
case STRING: |
|
442 |
*p.string_p=val; |
|
443 |
break; |
|
444 |
case INTEGER: |
|
445 |
vals >> *p.int_p; |
|
446 |
break; |
|
447 |
case DOUBLE: |
|
448 |
vals >> *p.double_p; |
|
449 |
break; |
|
450 |
default: |
|
451 |
break; |
|
452 |
} |
|
453 |
if(p.type!=STRING&&(!vals||!vals.eof())) |
|
454 |
requiresValue(arg, p.type); |
|
455 |
} |
|
456 |
p.set = true; |
|
457 |
} |
|
458 | 458 |
} |
459 | 459 |
} |
460 | 460 |
checkMandatories(); |
461 | 461 |
|
462 | 462 |
return *this; |
463 |
} |
|
463 |
} |
|
464 | 464 |
|
465 | 465 |
} |
1 |
/* -*- C++ -*- |
|
1 |
/* -*- mode: C++; indent-tabs-mode: nil; -*- |
|
2 | 2 |
* |
3 |
* This file is a part of LEMON, a generic C++ optimization library |
|
3 |
* This file is a part of LEMON, a generic C++ optimization library. |
|
4 | 4 |
* |
5 | 5 |
* Copyright (C) 2003-2008 |
6 | 6 |
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
7 | 7 |
* (Egervary Research Group on Combinatorial Optimization, EGRES). |
8 | 8 |
* |
9 | 9 |
* Permission to use, modify and distribute this software is granted |
... | ... |
@@ -38,87 +38,87 @@ |
38 | 38 |
|
39 | 39 |
///\ingroup misc |
40 | 40 |
///Command line arguments parser. |
41 | 41 |
/// |
42 | 42 |
///For a complete example see the \ref arg_parser_demo.cc demo file. |
43 | 43 |
class ArgParser { |
44 |
|
|
44 |
|
|
45 | 45 |
static void _showHelp(void *p); |
46 | 46 |
protected: |
47 |
|
|
47 |
|
|
48 | 48 |
int _argc; |
49 | 49 |
const char **_argv; |
50 |
|
|
50 |
|
|
51 | 51 |
enum OptType { UNKNOWN=0, BOOL=1, STRING=2, DOUBLE=3, INTEGER=4, FUNC=5 }; |
52 |
|
|
52 |
|
|
53 | 53 |
class ParData { |
54 | 54 |
public: |
55 | 55 |
union { |
56 |
bool *bool_p; |
|
57 |
int *int_p; |
|
58 |
double *double_p; |
|
59 |
std::string *string_p; |
|
60 |
struct { |
|
61 |
void (*p)(void *); |
|
62 |
void *data; |
|
63 |
} func_p; |
|
64 |
|
|
56 |
bool *bool_p; |
|
57 |
int *int_p; |
|
58 |
double *double_p; |
|
59 |
std::string *string_p; |
|
60 |
struct { |
|
61 |
void (*p)(void *); |
|
62 |
void *data; |
|
63 |
} func_p; |
|
64 |
|
|
65 | 65 |
}; |
66 | 66 |
std::string help; |
67 | 67 |
bool mandatory; |
68 | 68 |
OptType type; |
69 | 69 |
bool set; |
70 | 70 |
bool ingroup; |
71 | 71 |
bool has_syn; |
72 | 72 |
bool syn; |
73 | 73 |
bool self_delete; |
74 | 74 |
ParData() : mandatory(false), type(UNKNOWN), set(false), ingroup(false), |
75 |
|
|
75 |
has_syn(false), syn(false), self_delete(false) {} |
|
76 | 76 |
}; |
77 | 77 |
|
78 | 78 |
typedef std::map<std::string,ParData> Opts; |
79 | 79 |
Opts _opts; |
80 | 80 |
|
81 |
class GroupData |
|
81 |
class GroupData |
|
82 | 82 |
{ |
83 | 83 |
public: |
84 | 84 |
typedef std::list<std::string> Opts; |
85 | 85 |
Opts opts; |
86 | 86 |
bool only_one; |
87 | 87 |
bool mandatory; |
88 | 88 |
GroupData() :only_one(false), mandatory(false) {} |
89 | 89 |
}; |
90 |
|
|
90 |
|
|
91 | 91 |
typedef std::map<std::string,GroupData> Groups; |
92 | 92 |
Groups _groups; |
93 | 93 |
|
94 | 94 |
struct OtherArg |
95 | 95 |
{ |
96 | 96 |
std::string name; |
97 | 97 |
std::string help; |
98 | 98 |
OtherArg(std::string n, std::string h) :name(n), help(h) {} |
99 | 99 |
|
100 | 100 |
}; |
101 |
|
|
101 |
|
|
102 | 102 |
std::vector<OtherArg> _others_help; |
103 | 103 |
std::vector<std::string> _file_args; |
104 | 104 |
std::string _command_name; |
105 | 105 |
|
106 |
|
|
106 |
|
|
107 | 107 |
private: |
108 | 108 |
//Bind a function to an option. |
109 | 109 |
|
110 | 110 |
//\param name The name of the option. The leading '-' must be omitted. |
111 | 111 |
//\param help A help string. |
112 | 112 |
//\retval func The function to be called when the option is given. It |
113 | 113 |
// must be of type "void f(void *)" |
114 | 114 |
//\param data Data to be passed to \c func |
115 | 115 |
ArgParser &funcOption(const std::string &name, |
116 |
const std::string &help, |
|
117 |
void (*func)(void *),void *data); |
|
118 |
|
|
116 |
const std::string &help, |
|
117 |
void (*func)(void *),void *data); |
|
118 |
|
|
119 | 119 |
public: |
120 | 120 |
|
121 | 121 |
///Constructor |
122 | 122 |
ArgParser(int argc, const char **argv); |
123 | 123 |
|
124 | 124 |
~ArgParser(); |
... | ... |
@@ -133,57 +133,57 @@ |
133 | 133 |
///Add a new integer type option. |
134 | 134 |
///\param name The name of the option. The leading '-' must be omitted. |
135 | 135 |
///\param help A help string. |
136 | 136 |
///\param value A default value for the option. |
137 | 137 |
///\param obl Indicate if the option is mandatory. |
138 | 138 |
ArgParser &intOption(const std::string &name, |
139 |
const std::string &help, |
|
140 |
int value=0, bool obl=false); |
|
139 |
const std::string &help, |
|
140 |
int value=0, bool obl=false); |
|
141 | 141 |
|
142 | 142 |
///Add a new floating point type option |
143 | 143 |
|
144 | 144 |
///Add a new floating point type option. |
145 | 145 |
///\param name The name of the option. The leading '-' must be omitted. |
146 | 146 |
///\param help A help string. |
147 | 147 |
///\param value A default value for the option. |
148 | 148 |
///\param obl Indicate if the option is mandatory. |
149 | 149 |
ArgParser &doubleOption(const std::string &name, |
150 |
const std::string &help, |
|
151 |
double value=0, bool obl=false); |
|
150 |
const std::string &help, |
|
151 |
double value=0, bool obl=false); |
|
152 | 152 |
|
153 | 153 |
///Add a new bool type option |
154 | 154 |
|
155 | 155 |
///Add a new bool type option. |
156 | 156 |
///\param name The name of the option. The leading '-' must be omitted. |
157 | 157 |
///\param help A help string. |
158 | 158 |
///\param value A default value for the option. |
159 | 159 |
///\param obl Indicate if the option is mandatory. |
160 | 160 |
///\note A mandatory bool obtion is of very little use. |
161 | 161 |
ArgParser &boolOption(const std::string &name, |
162 |
const std::string &help, |
|
163 |
bool value=false, bool obl=false); |
|
162 |
const std::string &help, |
|
163 |
bool value=false, bool obl=false); |
|
164 | 164 |
|
165 | 165 |
///Add a new string type option |
166 | 166 |
|
167 | 167 |
///Add a new string type option. |
168 | 168 |
///\param name The name of the option. The leading '-' must be omitted. |
169 | 169 |
///\param help A help string. |
170 | 170 |
///\param value A default value for the option. |
171 | 171 |
///\param obl Indicate if the option is mandatory. |
172 | 172 |
ArgParser &stringOption(const std::string &name, |
173 |
const std::string &help, |
|
174 |
std::string value="", bool obl=false); |
|
173 |
const std::string &help, |
|
174 |
std::string value="", bool obl=false); |
|
175 | 175 |
|
176 | 176 |
///Give help string for non-parsed arguments. |
177 | 177 |
|
178 | 178 |
///With this function you can give help string for non-parsed arguments. |
179 | 179 |
///The parameter \c name will be printed in the short usage line, while |
180 | 180 |
///\c help gives a more detailed description. |
181 | 181 |
ArgParser &other(const std::string &name, |
182 |
const std::string &help=""); |
|
183 |
|
|
182 |
const std::string &help=""); |
|
183 |
|
|
184 | 184 |
///@} |
185 | 185 |
|
186 | 186 |
///\name Options with External Storage |
187 | 187 |
///Using this functions, the value of the option will be directly written |
188 | 188 |
///into a variable once the option appears in the command line. |
189 | 189 |
|
... | ... |
@@ -194,84 +194,84 @@ |
194 | 194 |
///Add a new integer type option with a storage reference. |
195 | 195 |
///\param name The name of the option. The leading '-' must be omitted. |
196 | 196 |
///\param help A help string. |
197 | 197 |
///\param obl Indicate if the option is mandatory. |
198 | 198 |
///\retval ref The value of the argument will be written to this variable. |
199 | 199 |
ArgParser &refOption(const std::string &name, |
200 |
const std::string &help, |
|
201 |
int &ref, bool obl=false); |
|
200 |
const std::string &help, |
|
201 |
int &ref, bool obl=false); |
|
202 | 202 |
|
203 | 203 |
///Add a new floating type option with a storage reference |
204 | 204 |
|
205 | 205 |
///Add a new floating type option with a storage reference. |
206 | 206 |
///\param name The name of the option. The leading '-' must be omitted. |
207 | 207 |
///\param help A help string. |
208 | 208 |
///\param obl Indicate if the option is mandatory. |
209 | 209 |
///\retval ref The value of the argument will be written to this variable. |
210 | 210 |
ArgParser &refOption(const std::string &name, |
211 |
const std::string &help, |
|
212 |
double &ref, bool obl=false); |
|
211 |
const std::string &help, |
|
212 |
double &ref, bool obl=false); |
|
213 | 213 |
|
214 | 214 |
///Add a new bool type option with a storage reference |
215 | 215 |
|
216 | 216 |
///Add a new bool type option with a storage reference. |
217 | 217 |
///\param name The name of the option. The leading '-' must be omitted. |
218 | 218 |
///\param help A help string. |
219 | 219 |
///\param obl Indicate if the option is mandatory. |
220 | 220 |
///\retval ref The value of the argument will be written to this variable. |
221 | 221 |
///\note A mandatory bool obtion is of very little use. |
222 | 222 |
ArgParser &refOption(const std::string &name, |
223 |
const std::string &help, |
|
224 |
bool &ref, bool obl=false); |
|
223 |
const std::string &help, |
|
224 |
bool &ref, bool obl=false); |
|
225 | 225 |
|
226 | 226 |
///Add a new string type option with a storage reference |
227 | 227 |
|
228 | 228 |
///Add a new string type option with a storage reference. |
229 | 229 |
///\param name The name of the option. The leading '-' must be omitted. |
230 | 230 |
///\param help A help string. |
231 | 231 |
///\param obl Indicate if the option is mandatory. |
232 | 232 |
///\retval ref The value of the argument will be written to this variable. |
233 | 233 |
ArgParser &refOption(const std::string &name, |
234 |
const std::string &help, |
|
235 |
std::string &ref, bool obl=false); |
|
236 |
|
|
234 |
const std::string &help, |
|
235 |
std::string &ref, bool obl=false); |
|
236 |
|
|
237 | 237 |
///@} |
238 | 238 |
|
239 | 239 |
///\name Option Groups and Synonyms |
240 | 240 |
/// |
241 |
|
|
241 |
|
|
242 | 242 |
///@{ |
243 | 243 |
|
244 | 244 |
///Bundle some options into a group |
245 | 245 |
|
246 | 246 |
/// You can group some option by calling this function repeatedly for each |
247 | 247 |
/// option to be grouped with the same groupname. |
248 | 248 |
///\param group The group name. |
249 | 249 |
///\param opt The option name. |
250 | 250 |
ArgParser &optionGroup(const std::string &group, |
251 |
|
|
251 |
const std::string &opt); |
|
252 | 252 |
|
253 | 253 |
///Make the members of a group exclusive |
254 | 254 |
|
255 | 255 |
///If you call this function for a group, than at most one of them can be |
256 | 256 |
///given at the same time. |
257 | 257 |
ArgParser &onlyOneGroup(const std::string &group); |
258 |
|
|
258 |
|
|
259 | 259 |
///Make a group mandatory |
260 | 260 |
|
261 | 261 |
///Using this function, at least one of the members of \c group |
262 | 262 |
///must be given. |
263 | 263 |
ArgParser &mandatoryGroup(const std::string &group); |
264 |
|
|
264 |
|
|
265 | 265 |
///Create synonym to an option |
266 | 266 |
|
267 | 267 |
///With this function you can create a synonym \c syn of the |
268 | 268 |
///option \c opt. |
269 | 269 |
ArgParser &synonym(const std::string &syn, |
270 |
const std::string &opt); |
|
271 |
|
|
270 |
const std::string &opt); |
|
271 |
|
|
272 | 272 |
///@} |
273 | 273 |
|
274 | 274 |
void show(std::ostream &os,Opts::iterator i); |
275 | 275 |
void show(std::ostream &os,Groups::iterator i); |
276 | 276 |
void showHelp(Opts::iterator i); |
277 | 277 |
void showHelp(std::vector<OtherArg>::iterator i); |
... | ... |
@@ -279,104 +279,104 @@ |
279 | 279 |
void showHelp(); |
280 | 280 |
|
281 | 281 |
void unknownOpt(std::string arg); |
282 | 282 |
|
283 | 283 |
void requiresValue(std::string arg, OptType t); |
284 | 284 |
void checkMandatories(); |
285 |
|
|
285 |
|
|
286 | 286 |
///Start the parsing process |
287 | 287 |
ArgParser &parse(); |
288 | 288 |
|
289 | 289 |
/// Synonym for parse() |
290 |
ArgParser &run() |
|
290 |
ArgParser &run() |
|
291 | 291 |
{ |
292 | 292 |
return parse(); |
293 | 293 |
} |
294 |
|
|
294 |
|
|
295 | 295 |
///Give back the command name (the 0th argument) |
296 | 296 |
const std::string &commandName() { return _command_name; } |
297 | 297 |
|
298 | 298 |
///Check if an opion has been given to the command. |
299 |
bool given(std::string op) |
|
299 |
bool given(std::string op) |
|
300 | 300 |
{ |
301 | 301 |
Opts::iterator i = _opts.find(op); |
302 | 302 |
return i!=_opts.end()?i->second.set:false; |
303 | 303 |
} |
304 | 304 |
|
305 | 305 |
|
306 | 306 |
///Magic type for operator[] |
307 |
|
|
307 |
|
|
308 | 308 |
///This is the type of the return value of ArgParser::operator[](). |
309 | 309 |
///It automatically converts to \c int, \c double, \c bool or |
310 | 310 |
///\c std::string if the type of the option matches, otherwise it |
311 | 311 |
///throws an exception (i.e. it performs runtime type checking). |
312 |
class RefType |
|
312 |
class RefType |
|
313 | 313 |
{ |
314 | 314 |
ArgParser &_parser; |
315 | 315 |
std::string _name; |
316 | 316 |
public: |
317 | 317 |
///\e |
318 | 318 |
RefType(ArgParser &p,const std::string &n) :_parser(p),_name(n) {} |
319 | 319 |
///\e |
320 |
operator bool() |
|
320 |
operator bool() |
|
321 | 321 |
{ |
322 |
Opts::iterator i = _parser._opts.find(_name); |
|
323 |
LEMON_ASSERT(i!=_parser._opts.end(), |
|
324 |
std::string()+"Unkown option: '"+_name+"'"); |
|
325 |
LEMON_ASSERT(i->second.type==ArgParser::BOOL, |
|
326 |
std::string()+"'"+_name+"' is a bool option"); |
|
327 |
return *(i->second.bool_p); |
|
322 |
Opts::iterator i = _parser._opts.find(_name); |
|
323 |
LEMON_ASSERT(i!=_parser._opts.end(), |
|
324 |
std::string()+"Unkown option: '"+_name+"'"); |
|
325 |
LEMON_ASSERT(i->second.type==ArgParser::BOOL, |
|
326 |
std::string()+"'"+_name+"' is a bool option"); |
|
327 |
return *(i->second.bool_p); |
|
328 | 328 |
} |
329 | 329 |
///\e |
330 | 330 |
operator std::string() |
331 | 331 |
{ |
332 |
Opts::iterator i = _parser._opts.find(_name); |
|
333 |
LEMON_ASSERT(i!=_parser._opts.end(), |
|
334 |
std::string()+"Unkown option: '"+_name+"'"); |
|
335 |
LEMON_ASSERT(i->second.type==ArgParser::STRING, |
|
336 |
std::string()+"'"+_name+"' is a string option"); |
|
337 |
return *(i->second.string_p); |
|
332 |
Opts::iterator i = _parser._opts.find(_name); |
|
333 |
LEMON_ASSERT(i!=_parser._opts.end(), |
|
334 |
std::string()+"Unkown option: '"+_name+"'"); |
|
335 |
LEMON_ASSERT(i->second.type==ArgParser::STRING, |
|
336 |
std::string()+"'"+_name+"' is a string option"); |
|
337 |
return *(i->second.string_p); |
|
338 | 338 |
} |
339 | 339 |
///\e |
340 |
operator double() |
|
340 |
operator double() |
|
341 | 341 |
{ |
342 |
Opts::iterator i = _parser._opts.find(_name); |
|
343 |
LEMON_ASSERT(i!=_parser._opts.end(), |
|
344 |
std::string()+"Unkown option: '"+_name+"'"); |
|
345 |
LEMON_ASSERT(i->second.type==ArgParser::DOUBLE || |
|
346 |
i->second.type==ArgParser::INTEGER, |
|
347 |
std::string()+"'"+_name+"' is a floating point option"); |
|
348 |
return i->second.type==ArgParser::DOUBLE ? |
|
349 |
*(i->second.double_p) : *(i->second.int_p); |
|
342 |
Opts::iterator i = _parser._opts.find(_name); |
|
343 |
LEMON_ASSERT(i!=_parser._opts.end(), |
|
344 |
std::string()+"Unkown option: '"+_name+"'"); |
|
345 |
LEMON_ASSERT(i->second.type==ArgParser::DOUBLE || |
|
346 |
i->second.type==ArgParser::INTEGER, |
|
347 |
std::string()+"'"+_name+"' is a floating point option"); |
|
348 |
return i->second.type==ArgParser::DOUBLE ? |
|
349 |
*(i->second.double_p) : *(i->second.int_p); |
|
350 | 350 |
} |
351 | 351 |
///\e |
352 |
operator int() |
|
352 |
operator int() |
|
353 | 353 |
{ |
354 |
Opts::iterator i = _parser._opts.find(_name); |
|
355 |
LEMON_ASSERT(i!=_parser._opts.end(), |
|
356 |
std::string()+"Unkown option: '"+_name+"'"); |
|
357 |
LEMON_ASSERT(i->second.type==ArgParser::INTEGER, |
|
358 |
std::string()+"'"+_name+"' is an integer option"); |
|
359 |
return *(i->second.int_p); |
|
354 |
Opts::iterator i = _parser._opts.find(_name); |
|
355 |
LEMON_ASSERT(i!=_parser._opts.end(), |
|
356 |
std::string()+"Unkown option: '"+_name+"'"); |
|
357 |
LEMON_ASSERT(i->second.type==ArgParser::INTEGER, |
|
358 |
std::string()+"'"+_name+"' is an integer option"); |
|
359 |
return *(i->second.int_p); |
|
360 | 360 |
} |
361 | 361 |
|
362 | 362 |
}; |
363 | 363 |
|
364 | 364 |
///Give back the value of an option |
365 |
|
|
365 |
|
|
366 | 366 |
///Give back the value of an option. |
367 | 367 |
///\sa RefType |
368 | 368 |
RefType operator[](const std::string &n) |
369 | 369 |
{ |
370 | 370 |
return RefType(*this, n); |
371 |
} |
|
371 |
} |
|
372 | 372 |
|
373 | 373 |
///Give back the non-option type arguments. |
374 | 374 |
|
375 | 375 |
///Give back a reference to a vector consisting of the program arguments |
376 | 376 |
///not starting with a '-' character. |
377 | 377 |
std::vector<std::string> &files() { return _file_args; } |
378 |
|
|
378 |
|
|
379 | 379 |
}; |
380 | 380 |
} |
381 | 381 |
|
382 | 382 |
#endif // LEMON_ARG_PARSER |
1 |
/* -*- C++ -*- |
|
1 |
/* -*- mode: C++; indent-tabs-mode: nil; -*- |
|
2 | 2 |
* |
3 |
* This file is a part of LEMON, a generic C++ optimization library |
|
3 |
* This file is a part of LEMON, a generic C++ optimization library. |
|
4 | 4 |
* |
5 | 5 |
* Copyright (C) 2003-2008 |
6 | 6 |
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
7 | 7 |
* (Egervary Research Group on Combinatorial Optimization, EGRES). |
8 | 8 |
* |
9 | 9 |
* Permission to use, modify and distribute this software is granted |
... | ... |
@@ -25,61 +25,61 @@ |
25 | 25 |
|
26 | 26 |
#include <lemon/error.h> |
27 | 27 |
|
28 | 28 |
namespace lemon { |
29 | 29 |
|
30 | 30 |
inline void assert_fail_log(const char *file, int line, const char *function, |
31 |
|
|
31 |
const char *message, const char *assertion) |
|
32 | 32 |
{ |
33 | 33 |
std::cerr << file << ":" << line << ": "; |
34 | 34 |
if (function) |
35 | 35 |
std::cerr << function << ": "; |
36 | 36 |
std::cerr << message; |
37 | 37 |
if (assertion) |
38 | 38 |
std::cerr << " (assertion '" << assertion << "' failed)"; |
39 | 39 |
std::cerr << std::endl; |
40 | 40 |
} |
41 | 41 |
|
42 | 42 |
inline void assert_fail_abort(const char *file, int line, |
43 |
const char *function, const char* message, |
|
44 |
const char *assertion) |
|
43 |
const char *function, const char* message, |
|
44 |
const char *assertion) |
|
45 | 45 |
{ |
46 | 46 |
assert_fail_log(file, line, function, message, assertion); |
47 | 47 |
std::abort(); |
48 | 48 |
} |
49 | 49 |
|
50 | 50 |
namespace _assert_bits { |
51 |
|
|
52 |
|
|
51 |
|
|
52 |
|
|
53 | 53 |
inline const char* cstringify(const std::string& str) { |
54 | 54 |
return str.c_str(); |
55 | 55 |
} |
56 | 56 |
|
57 | 57 |
inline const char* cstringify(const char* str) { |
58 | 58 |
return str; |
59 |
} |
|
59 |
} |
|
60 | 60 |
} |
61 | 61 |
} |
62 | 62 |
|
63 | 63 |
#endif // LEMON_ASSERT_H |
64 | 64 |
|
65 | 65 |
#undef LEMON_ASSERT |
66 | 66 |
#undef LEMON_FIXME |
67 | 67 |
#undef LEMON_DEBUG |
68 | 68 |
|
69 |
#if (defined(LEMON_ASSERT_LOG) ? 1 : 0) + \ |
|
70 |
(defined(LEMON_ASSERT_ABORT) ? 1 : 0) + \ |
|
69 |
#if (defined(LEMON_ASSERT_LOG) ? 1 : 0) + \ |
|
70 |
(defined(LEMON_ASSERT_ABORT) ? 1 : 0) + \ |
|
71 | 71 |
(defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) > 1 |
72 | 72 |
#error "LEMON assertion system is not set properly" |
73 | 73 |
#endif |
74 | 74 |
|
75 |
#if ((defined(LEMON_ASSERT_LOG) ? 1 : 0) + \ |
|
76 |
(defined(LEMON_ASSERT_ABORT) ? 1 : 0) + \ |
|
77 |
(defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) == 1 || \ |
|
78 |
defined(LEMON_ENABLE_ASSERTS)) && \ |
|
79 |
|
|
75 |
#if ((defined(LEMON_ASSERT_LOG) ? 1 : 0) + \ |
|
76 |
(defined(LEMON_ASSERT_ABORT) ? 1 : 0) + \ |
|
77 |
(defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) == 1 || \ |
|
78 |
defined(LEMON_ENABLE_ASSERTS)) && \ |
|
79 |
(defined(LEMON_DISABLE_ASSERTS) || \ |
|
80 | 80 |
defined(NDEBUG)) |
81 | 81 |
#error "LEMON assertion system is not set properly" |
82 | 82 |
#endif |
83 | 83 |
|
84 | 84 |
|
85 | 85 |
#if defined LEMON_ASSERT_LOG |
... | ... |
@@ -133,18 +133,18 @@ |
133 | 133 |
/// or with compilation parameters: |
134 | 134 |
/// \code |
135 | 135 |
/// g++ -DLEMON_DISABLE_ASSERTS |
136 | 136 |
/// make CXXFLAGS='-DLEMON_DISABLE_ASSERTS' |
137 | 137 |
/// \endcode |
138 | 138 |
/// The checking is also disabled when the standard macro \c NDEBUG is defined. |
139 |
/// |
|
139 |
/// |
|
140 | 140 |
/// The LEMON assertion system has a wide range of customization |
141 | 141 |
/// properties. As a default behaviour the failed assertion prints a |
142 | 142 |
/// short log message to the standard error and aborts the execution. |
143 | 143 |
/// |
144 |
/// The following modes can be used in the assertion system: |
|
144 |
/// The following modes can be used in the assertion system: |
|
145 | 145 |
/// |
146 | 146 |
/// - \c LEMON_ASSERT_LOG The failed assertion prints a short log |
147 | 147 |
/// message to the standard error and continues the execution. |
148 | 148 |
/// - \c LEMON_ASSERT_ABORT This mode is similar to the \c |
149 | 149 |
/// LEMON_ASSERT_LOG, but it aborts the program. It is the default |
150 | 150 |
/// behaviour. |
... | ... |
@@ -152,44 +152,44 @@ |
152 | 152 |
/// function. |
153 | 153 |
/// \code |
154 | 154 |
/// void custom_assert_handler(const char* file, int line, const char* function, |
155 | 155 |
/// const char* message, const char* assertion); |
156 | 156 |
/// \endcode |
157 | 157 |
/// The name of the function should be defined as the \c |
158 |
/// LEMON_CUSTOM_ASSERT_HANDLER macro name. |
|
158 |
/// LEMON_CUSTOM_ASSERT_HANDLER macro name. |
|
159 | 159 |
/// \code |
160 | 160 |
/// #define LEMON_CUSTOM_ASSERT_HANDLER custom_assert_handler |
161 | 161 |
/// \endcode |
162 | 162 |
/// Whenever an assertion is occured, the custom assertion |
163 | 163 |
/// handler is called with appropiate parameters. |
164 | 164 |
/// |
165 | 165 |
/// The assertion mode can also be changed within one compilation unit. |
166 | 166 |
/// If the macros are redefined with other settings and the |
167 | 167 |
/// \ref lemon/assert.h "assert.h" file is reincluded, then the |
168 | 168 |
/// behaviour is changed appropiately to the new settings. |
169 |
# define LEMON_ASSERT(exp, msg) \ |
|
170 |
(static_cast<void> (!!(exp) ? 0 : ( \ |
|
171 |
LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \ |
|
172 |
LEMON_FUNCTION_NAME, \ |
|
173 |
|
|
169 |
# define LEMON_ASSERT(exp, msg) \ |
|
170 |
(static_cast<void> (!!(exp) ? 0 : ( \ |
|
171 |
LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \ |
|
172 |
LEMON_FUNCTION_NAME, \ |
|
173 |
::lemon::_assert_bits::cstringify(msg), #exp), 0))) |
|
174 | 174 |
|
175 | 175 |
/// \ingroup exceptions |
176 | 176 |
/// |
177 | 177 |
/// \brief Macro for mark not yet implemented features. |
178 | 178 |
/// |
179 | 179 |
/// Macro for mark not yet implemented features and outstanding bugs. |
180 | 180 |
/// It is close to be the shortcut of the following code: |
181 | 181 |
/// \code |
182 | 182 |
/// LEMON_ASSERT(false, msg); |
183 | 183 |
/// \endcode |
184 | 184 |
/// |
185 |
/// \see LEMON_ASSERT |
|
186 |
# define LEMON_FIXME(msg) \ |
|
187 |
(LEMON_ASSERT_HANDLER(__FILE__, __LINE__, LEMON_FUNCTION_NAME, \ |
|
188 |
::lemon::_assert_bits::cstringify(msg), \ |
|
189 |
|
|
185 |
/// \see LEMON_ASSERT |
|
186 |
# define LEMON_FIXME(msg) \ |
|
187 |
(LEMON_ASSERT_HANDLER(__FILE__, __LINE__, LEMON_FUNCTION_NAME, \ |
|
188 |
::lemon::_assert_bits::cstringify(msg), \ |
|
189 |
static_cast<const char*>(0))) |
|
190 | 190 |
|
191 | 191 |
/// \ingroup exceptions |
192 | 192 |
/// |
193 | 193 |
/// \brief Macro for internal assertions |
194 | 194 |
/// |
195 | 195 |
/// Macro for internal assertions, it is used in the library to check |
... | ... |
@@ -207,44 +207,44 @@ |
207 | 207 |
/// \endcode |
208 | 208 |
/// |
209 | 209 |
/// This macro works like the \c LEMON_ASSERT macro, therefore the |
210 | 210 |
/// current behaviour depends on the settings of \c LEMON_ASSERT |
211 | 211 |
/// macro. |
212 | 212 |
/// |
213 |
/// \see LEMON_ASSERT |
|
214 |
# define LEMON_DEBUG(exp, msg) \ |
|
215 |
|
|
213 |
/// \see LEMON_ASSERT |
|
214 |
# define LEMON_DEBUG(exp, msg) \ |
|
215 |
(static_cast<void> (!!(exp) ? 0 : ( \ |
|
216 | 216 |
LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \ |
217 |
LEMON_FUNCTION_NAME, \ |
|
218 |
::lemon::_assert_bits::cstringify(msg), #exp), 0))) |
|
217 |
LEMON_FUNCTION_NAME, \ |
|
218 |
::lemon::_assert_bits::cstringify(msg), #exp), 0))) |
|
219 | 219 |
|
220 | 220 |
#else |
221 | 221 |
|
222 | 222 |
# ifndef LEMON_ASSERT_HANDLER |
223 | 223 |
# define LEMON_ASSERT(exp, msg) (static_cast<void>(0)) |
224 | 224 |
# define LEMON_FIXME(msg) (static_cast<void>(0)) |
225 | 225 |
# define LEMON_DEBUG(exp, msg) (static_cast<void>(0)) |
226 | 226 |
# else |
227 |
# define LEMON_ASSERT(exp, msg) \ |
|
228 |
(static_cast<void> (!!(exp) ? 0 : ( \ |
|
227 |
# define LEMON_ASSERT(exp, msg) \ |
|
228 |
(static_cast<void> (!!(exp) ? 0 : ( \ |
|
229 | 229 |
LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \ |
230 |
LEMON_FUNCTION_NAME, \ |
|
231 |
::lemon::_assert_bits::cstringify(msg), \ |
|
232 |
#exp), 0))) |
|
233 |
# define LEMON_FIXME(msg) \ |
|
234 |
(LEMON_ASSERT_HANDLER(__FILE__, __LINE__, LEMON_FUNCTION_NAME, \ |
|
235 |
::lemon::_assert_bits::cstringify(msg), \ |
|
236 |
|
|
230 |
LEMON_FUNCTION_NAME, \ |
|
231 |
::lemon::_assert_bits::cstringify(msg), \ |
|
232 |
#exp), 0))) |
|
233 |
# define LEMON_FIXME(msg) \ |
|
234 |
(LEMON_ASSERT_HANDLER(__FILE__, __LINE__, LEMON_FUNCTION_NAME, \ |
|
235 |
::lemon::_assert_bits::cstringify(msg), \ |
|
236 |
static_cast<const char*>(0))) |
|
237 | 237 |
|
238 | 238 |
# if LEMON_ENABLE_DEBUG |
239 | 239 |
# define LEMON_DEBUG(exp, msg) |
240 | 240 |
(static_cast<void> (!!(exp) ? 0 : ( \ |
241 | 241 |
LEMON_ASSERT_HANDLER(__FILE__, __LINE__, \ |
242 | 242 |
LEMON_FUNCTION_NAME, \ |
243 |
::lemon::_assert_bits::cstringify(msg), \ |
|
244 |
#exp), 0))) |
|
243 |
::lemon::_assert_bits::cstringify(msg), \ |
|
244 |
#exp), 0))) |
|
245 | 245 |
# else |
246 | 246 |
# define LEMON_DEBUG(exp, msg) (static_cast<void>(0)) |
247 | 247 |
# endif |
248 | 248 |
# endif |
249 | 249 |
|
250 | 250 |
#endif |
1 |
/* -*- C++ -*- |
|
1 |
/* -*- mode: C++; indent-tabs-mode: nil; -*- |
|
2 | 2 |
* |
3 |
* This file is a part of LEMON, a generic C++ optimization library |
|
3 |
* This file is a part of LEMON, a generic C++ optimization library. |
|
4 | 4 |
* |
5 | 5 |
* Copyright (C) 2003-2008 |
6 | 6 |
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
7 | 7 |
* (Egervary Research Group on Combinatorial Optimization, EGRES). |
8 | 8 |
* |
9 | 9 |
* Permission to use, modify and distribute this software is granted |
1 |
/* -*- C++ -*- |
|
1 |
/* -*- mode: C++; indent-tabs-mode: nil; -*- |
|
2 | 2 |
* |
3 |
* This file is a part of LEMON, a generic C++ optimization library |
|
3 |
* This file is a part of LEMON, a generic C++ optimization library. |
|
4 | 4 |
* |
5 | 5 |
* Copyright (C) 2003-2008 |
6 | 6 |
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
7 | 7 |
* (Egervary Research Group on Combinatorial Optimization, EGRES). |
8 | 8 |
* |
9 | 9 |
* Permission to use, modify and distribute this software is granted |
... | ... |
@@ -30,91 +30,91 @@ |
30 | 30 |
#include <lemon/error.h> |
31 | 31 |
#include <lemon/maps.h> |
32 | 32 |
|
33 | 33 |
namespace lemon { |
34 | 34 |
|
35 | 35 |
|
36 |
|
|
36 |
|
|
37 | 37 |
///Default traits class of Bfs class. |
38 | 38 |
|
39 | 39 |
///Default traits class of Bfs class. |
40 | 40 |
///\tparam GR Digraph type. |
41 | 41 |
template<class GR> |
42 | 42 |
struct BfsDefaultTraits |
43 | 43 |
{ |
44 |
///The digraph type the algorithm runs on. |
|
44 |
///The digraph type the algorithm runs on. |
|
45 | 45 |
typedef GR Digraph; |
46 | 46 |
///\brief The type of the map that stores the last |
47 | 47 |
///arcs of the shortest paths. |
48 |
/// |
|
48 |
/// |
|
49 | 49 |
///The type of the map that stores the last |
50 | 50 |
///arcs of the shortest paths. |
51 | 51 |
///It must meet the \ref concepts::WriteMap "WriteMap" concept. |
52 | 52 |
/// |
53 | 53 |
typedef typename Digraph::template NodeMap<typename GR::Arc> PredMap; |
54 | 54 |
///Instantiates a PredMap. |
55 |
|
|
56 |
///This function instantiates a \ref PredMap. |
|
55 |
|
|
56 |
///This function instantiates a \ref PredMap. |
|
57 | 57 |
///\param G is the digraph, to which we would like to define the PredMap. |
58 | 58 |
///\todo The digraph alone may be insufficient to initialize |
59 |
static PredMap *createPredMap(const GR &G) |
|
59 |
static PredMap *createPredMap(const GR &G) |
|
60 | 60 |
{ |
61 | 61 |
return new PredMap(G); |
62 | 62 |
} |
63 | 63 |
///The type of the map that indicates which nodes are processed. |
64 |
|
|
64 |
|
|
65 | 65 |
///The type of the map that indicates which nodes are processed. |
66 | 66 |
///It must meet the \ref concepts::WriteMap "WriteMap" concept. |
67 | 67 |
///\todo named parameter to set this type, function to read and write. |
68 | 68 |
typedef NullMap<typename Digraph::Node,bool> ProcessedMap; |
69 | 69 |
///Instantiates a ProcessedMap. |
70 |
|
|
71 |
///This function instantiates a \ref ProcessedMap. |
|
70 |
|
|
71 |
///This function instantiates a \ref ProcessedMap. |
|
72 | 72 |
///\param g is the digraph, to which |
73 | 73 |
///we would like to define the \ref ProcessedMap |
74 | 74 |
#ifdef DOXYGEN |
75 | 75 |
static ProcessedMap *createProcessedMap(const GR &g) |
76 | 76 |
#else |
77 | 77 |
static ProcessedMap *createProcessedMap(const GR &) |
78 | 78 |
#endif |
79 | 79 |
{ |
80 | 80 |
return new ProcessedMap(); |
81 | 81 |
} |
82 | 82 |
///The type of the map that indicates which nodes are reached. |
83 |
|
|
83 |
|
|
84 | 84 |
///The type of the map that indicates which nodes are reached. |
85 | 85 |
///It must meet the \ref concepts::WriteMap "WriteMap" concept. |
86 | 86 |
///\todo named parameter to set this type, function to read and write. |
87 | 87 |
typedef typename Digraph::template NodeMap<bool> ReachedMap; |
88 | 88 |
///Instantiates a ReachedMap. |
89 |
|
|
90 |
///This function instantiates a \ref ReachedMap. |
|
89 |
|
|
90 |
///This function instantiates a \ref ReachedMap. |
|
91 | 91 |
///\param G is the digraph, to which |
92 | 92 |
///we would like to define the \ref ReachedMap. |
93 | 93 |
static ReachedMap *createReachedMap(const GR &G) |
94 | 94 |
{ |
95 | 95 |
return new ReachedMap(G); |
96 | 96 |
} |
97 | 97 |
///The type of the map that stores the dists of the nodes. |
98 |
|
|
98 |
|
|
99 | 99 |
///The type of the map that stores the dists of the nodes. |
100 | 100 |
///It must meet the \ref concepts::WriteMap "WriteMap" concept. |
101 | 101 |
/// |
102 | 102 |
typedef typename Digraph::template NodeMap<int> DistMap; |
103 | 103 |
///Instantiates a DistMap. |
104 |
|
|
105 |
///This function instantiates a \ref DistMap. |
|
104 |
|
|
105 |
///This function instantiates a \ref DistMap. |
|
106 | 106 |
///\param G is the digraph, to which we would like to define the \ref DistMap |
107 | 107 |
static DistMap *createDistMap(const GR &G) |
108 | 108 |
{ |
109 | 109 |
return new DistMap(G); |
110 | 110 |
} |
111 | 111 |
}; |
112 |
|
|
112 |
|
|
113 | 113 |
///%BFS algorithm class. |
114 |
|
|
114 |
|
|
115 | 115 |
///\ingroup search |
116 | 116 |
///This class provides an efficient implementation of the %BFS algorithm. |
117 | 117 |
/// |
118 | 118 |
///\tparam GR The digraph type the algorithm runs on. The default value is |
119 | 119 |
///\ref ListDigraph. The value of GR is not used directly by Bfs, it |
120 | 120 |
///is only passed to \ref BfsDefaultTraits. |
... | ... |
@@ -123,36 +123,36 @@ |
123 | 123 |
///\ref BfsDefaultTraits "BfsDefaultTraits<GR>". |
124 | 124 |
///See \ref BfsDefaultTraits for the documentation of |
125 | 125 |
///a Bfs traits class. |
126 | 126 |
|
127 | 127 |
#ifdef DOXYGEN |
128 | 128 |
template <typename GR, |
129 |
|
|
129 |
typename TR> |
|
130 | 130 |
#else |
131 | 131 |
template <typename GR=ListDigraph, |
132 |
|
|
132 |
typename TR=BfsDefaultTraits<GR> > |
|
133 | 133 |
#endif |
134 | 134 |
class Bfs { |
135 | 135 |
public: |
136 | 136 |
/** |
137 | 137 |
* \brief \ref Exception for uninitialized parameters. |
138 | 138 |
* |
139 | 139 |
* This error represents problems in the initialization |
140 | 140 |
* of the parameters of the algorithms. |
141 | 141 |
*/ |
142 | 142 |
class UninitializedParameter : public lemon::UninitializedParameter { |
143 | 143 |
public: |
144 | 144 |
virtual const char* what() const throw() { |
145 |
|
|
145 |
return "lemon::Bfs::UninitializedParameter"; |
|
146 | 146 |
} |
147 | 147 |
}; |
148 | 148 |
|
149 | 149 |
typedef TR Traits; |
150 | 150 |
///The type of the underlying digraph. |
151 | 151 |
typedef typename TR::Digraph Digraph; |
152 |
|
|
152 |
|
|
153 | 153 |
///\brief The type of the map that stores the last |
154 | 154 |
///arcs of the shortest paths. |
155 | 155 |
typedef typename TR::PredMap PredMap; |
156 | 156 |
///The type of the map indicating which nodes are reached. |
157 | 157 |
typedef typename TR::ReachedMap ReachedMap; |
158 | 158 |
///The type of the map indicating which nodes are processed. |
... | ... |
@@ -187,155 +187,155 @@ |
187 | 187 |
|
188 | 188 |
std::vector<typename Digraph::Node> _queue; |
189 | 189 |
int _queue_head,_queue_tail,_queue_next_dist; |
190 | 190 |
int _curr_dist; |
191 | 191 |
|
192 | 192 |
///Creates the maps if necessary. |
193 |
|
|
193 |
|
|
194 | 194 |
///\todo Better memory allocation (instead of new). |
195 |
void create_maps() |
|
195 |
void create_maps() |
|
196 | 196 |
{ |
197 | 197 |
if(!_pred) { |
198 |
local_pred = true; |
|
199 |
_pred = Traits::createPredMap(*G); |
|
198 |
local_pred = true; |
|
199 |
_pred = Traits::createPredMap(*G); |
|
200 | 200 |
} |
201 | 201 |
if(!_dist) { |
202 |
local_dist = true; |
|
203 |
_dist = Traits::createDistMap(*G); |
|
202 |
local_dist = true; |
|
203 |
_dist = Traits::createDistMap(*G); |
|
204 | 204 |
} |
205 | 205 |
if(!_reached) { |
206 |
local_reached = true; |
|
207 |
_reached = Traits::createReachedMap(*G); |
|
206 |
local_reached = true; |
|
207 |
_reached = Traits::createReachedMap(*G); |
|
208 | 208 |
} |
209 | 209 |
if(!_processed) { |
210 |
local_processed = true; |
|
211 |
_processed = Traits::createProcessedMap(*G); |
|
210 |
local_processed = true; |
|
211 |
_processed = Traits::createProcessedMap(*G); |
|
212 | 212 |
} |
213 | 213 |
} |
214 | 214 |
|
215 | 215 |
protected: |
216 |
|
|
216 |
|
|
217 | 217 |
Bfs() {} |
218 |
|
|
218 |
|
|
219 | 219 |
public: |
220 |
|
|
220 |
|
|
221 | 221 |
typedef Bfs Create; |
222 | 222 |
|
223 | 223 |
///\name Named template parameters |
224 | 224 |
|
225 | 225 |
///@{ |
226 | 226 |
|
227 | 227 |
template <class T> |
228 | 228 |
struct DefPredMapTraits : public Traits { |
229 | 229 |
typedef T PredMap; |
230 |
static PredMap *createPredMap(const Digraph &) |
|
230 |
static PredMap *createPredMap(const Digraph &) |
|
231 | 231 |
{ |
232 |
|
|
232 |
throw UninitializedParameter(); |
|
233 | 233 |
} |
234 | 234 |
}; |
235 | 235 |
///\brief \ref named-templ-param "Named parameter" for setting |
236 | 236 |
///PredMap type |
237 | 237 |
/// |
238 | 238 |
///\ref named-templ-param "Named parameter" for setting PredMap type |
239 | 239 |
/// |
240 | 240 |
template <class T> |
241 |
struct DefPredMap : public Bfs< Digraph, DefPredMapTraits<T> > { |
|
241 |
struct DefPredMap : public Bfs< Digraph, DefPredMapTraits<T> > { |
|
242 | 242 |
typedef Bfs< Digraph, DefPredMapTraits<T> > Create; |
243 | 243 |
}; |
244 |
|
|
244 |
|
|
245 | 245 |
template <class T> |
246 | 246 |
struct DefDistMapTraits : public Traits { |
247 | 247 |
typedef T DistMap; |
248 |
static DistMap *createDistMap(const Digraph &) |
|
248 |
static DistMap *createDistMap(const Digraph &) |
|
249 | 249 |
{ |
250 |
|
|
250 |
throw UninitializedParameter(); |
|
251 | 251 |
} |
252 | 252 |
}; |
253 | 253 |
///\brief \ref named-templ-param "Named parameter" for setting |
254 | 254 |
///DistMap type |
255 | 255 |
/// |
256 | 256 |
///\ref named-templ-param "Named parameter" for setting DistMap type |
257 | 257 |
/// |
258 | 258 |
template <class T> |
259 |
struct DefDistMap : public Bfs< Digraph, DefDistMapTraits<T> > { |
|
259 |
struct DefDistMap : public Bfs< Digraph, DefDistMapTraits<T> > { |
|
260 | 260 |
typedef Bfs< Digraph, DefDistMapTraits<T> > Create; |
261 | 261 |
}; |
262 |
|
|
262 |
|
|
263 | 263 |
template <class T> |
264 | 264 |
struct DefReachedMapTraits : public Traits { |
265 | 265 |
typedef T ReachedMap; |
266 |
static ReachedMap *createReachedMap(const Digraph &) |
|
266 |
static ReachedMap *createReachedMap(const Digraph &) |
|
267 | 267 |
{ |
268 |
|
|
268 |
throw UninitializedParameter(); |
|
269 | 269 |
} |
270 | 270 |
}; |
271 | 271 |
///\brief \ref named-templ-param "Named parameter" for setting |
272 | 272 |
///ReachedMap type |
273 | 273 |
/// |
274 | 274 |
///\ref named-templ-param "Named parameter" for setting ReachedMap type |
275 | 275 |
/// |
276 | 276 |
template <class T> |
277 |
struct DefReachedMap : public Bfs< Digraph, DefReachedMapTraits<T> > { |
|
277 |
struct DefReachedMap : public Bfs< Digraph, DefReachedMapTraits<T> > { |
|
278 | 278 |
typedef Bfs< Digraph, DefReachedMapTraits<T> > Create; |
279 | 279 |
}; |
280 |
|
|
280 |
|
|
281 | 281 |
template <class T> |
282 | 282 |
struct DefProcessedMapTraits : public Traits { |
283 | 283 |
typedef T ProcessedMap; |
284 |
static ProcessedMap *createProcessedMap(const Digraph &) |
|
284 |
static ProcessedMap *createProcessedMap(const Digraph &) |
|
285 | 285 |
{ |
286 |
|
|
286 |
throw UninitializedParameter(); |
|
287 | 287 |
} |
288 | 288 |
}; |
289 | 289 |
///\brief \ref named-templ-param "Named parameter" for setting |
290 | 290 |
///ProcessedMap type |
291 | 291 |
/// |
292 | 292 |
///\ref named-templ-param "Named parameter" for setting ProcessedMap type |
293 | 293 |
/// |
294 | 294 |
template <class T> |
295 | 295 |
struct DefProcessedMap : public Bfs< Digraph, DefProcessedMapTraits<T> > { |
296 | 296 |
typedef Bfs< Digraph, DefProcessedMapTraits<T> > Create; |
297 | 297 |
}; |
298 |
|
|
298 |
|
|
299 | 299 |
struct DefDigraphProcessedMapTraits : public Traits { |
300 | 300 |
typedef typename Digraph::template NodeMap<bool> ProcessedMap; |
301 |
static ProcessedMap *createProcessedMap(const Digraph &G) |
|
301 |
static ProcessedMap *createProcessedMap(const Digraph &G) |
|
302 | 302 |
{ |
303 |
|
|
303 |
return new ProcessedMap(G); |
|
304 | 304 |
} |
305 | 305 |
}; |
306 | 306 |
///\brief \ref named-templ-param "Named parameter" |
307 | 307 |
///for setting the ProcessedMap type to be Digraph::NodeMap<bool>. |
308 | 308 |
/// |
309 | 309 |
///\ref named-templ-param "Named parameter" |
310 | 310 |
///for setting the ProcessedMap type to be Digraph::NodeMap<bool>. |
311 | 311 |
///If you don't set it explicitly, it will be automatically allocated. |
312 | 312 |
template <class T> |
313 | 313 |
struct DefProcessedMapToBeDefaultMap : |
314 |
public Bfs< Digraph, DefDigraphProcessedMapTraits> { |
|
314 |
public Bfs< Digraph, DefDigraphProcessedMapTraits> { |
|
315 | 315 |
typedef Bfs< Digraph, DefDigraphProcessedMapTraits> Create; |
316 | 316 |
}; |
317 |
|
|
317 |
|
|
318 | 318 |
///@} |
319 | 319 |
|
320 |
public: |
|
321 |
|
|
320 |
public: |
|
321 |
|
|
322 | 322 |
///Constructor. |
323 |
|
|
323 |
|
|
324 | 324 |
///\param _G the digraph the algorithm will run on. |
325 | 325 |
/// |
326 | 326 |
Bfs(const Digraph& _G) : |
327 | 327 |
G(&_G), |
328 | 328 |
_pred(NULL), local_pred(false), |
329 | 329 |
_dist(NULL), local_dist(false), |
330 | 330 |
_reached(NULL), local_reached(false), |
331 | 331 |
_processed(NULL), local_processed(false) |
332 | 332 |
{ } |
333 |
|
|
333 |
|
|
334 | 334 |
///Destructor. |
335 |
~Bfs() |
|
335 |
~Bfs() |
|
336 | 336 |
{ |
337 | 337 |
if(local_pred) delete _pred; |
338 | 338 |
if(local_dist) delete _dist; |
339 | 339 |
if(local_reached) delete _reached; |
340 | 340 |
if(local_processed) delete _processed; |
341 | 341 |
} |
... | ... |
@@ -344,68 +344,68 @@ |
344 | 344 |
|
345 | 345 |
///Sets the map storing the predecessor arcs. |
346 | 346 |
///If you don't use this function before calling \ref run(), |
347 | 347 |
///it will allocate one. The destructor deallocates this |
348 | 348 |
///automatically allocated map, of course. |
349 | 349 |
///\return <tt> (*this) </tt> |
350 |
Bfs &predMap(PredMap &m) |
|
350 |
Bfs &predMap(PredMap &m) |
|
351 | 351 |
{ |
352 | 352 |
if(local_pred) { |
353 |
delete _pred; |
|
354 |
local_pred=false; |
|
353 |
delete _pred; |
|
354 |
local_pred=false; |
|
355 | 355 |
} |
356 | 356 |
_pred = &m; |
357 | 357 |
return *this; |
358 | 358 |
} |
359 | 359 |
|
360 | 360 |
///Sets the map indicating the reached nodes. |
361 | 361 |
|
362 | 362 |
///Sets the map indicating the reached nodes. |
363 | 363 |
///If you don't use this function before calling \ref run(), |
364 | 364 |
///it will allocate one. The destructor deallocates this |
365 | 365 |
///automatically allocated map, of course. |
366 | 366 |
///\return <tt> (*this) </tt> |
367 |
Bfs &reachedMap(ReachedMap &m) |
|
367 |
Bfs &reachedMap(ReachedMap &m) |
|
368 | 368 |
{ |
369 | 369 |
if(local_reached) { |
370 |
delete _reached; |
|
371 |
local_reached=false; |
|
370 |
delete _reached; |
|
371 |
local_reached=false; |
|
372 | 372 |
} |
373 | 373 |
_reached = &m; |
374 | 374 |
return *this; |
375 | 375 |
} |
376 | 376 |
|
377 | 377 |
///Sets the map indicating the processed nodes. |
378 | 378 |
|
379 | 379 |
///Sets the map indicating the processed nodes. |
380 | 380 |
///If you don't use this function before calling \ref run(), |
381 | 381 |
///it will allocate one. The destructor deallocates this |
382 | 382 |
///automatically allocated map, of course. |
383 | 383 |
///\return <tt> (*this) </tt> |
384 |
Bfs &processedMap(ProcessedMap &m) |
|
384 |
Bfs &processedMap(ProcessedMap &m) |
|
385 | 385 |
{ |
386 | 386 |
if(local_processed) { |
387 |
delete _processed; |
|
388 |
local_processed=false; |
|
387 |
delete _processed; |
|
388 |
local_processed=false; |
|
389 | 389 |
} |
390 | 390 |
_processed = &m; |
391 | 391 |
return *this; |
392 | 392 |
} |
393 | 393 |
|
394 | 394 |
///Sets the map storing the distances calculated by the algorithm. |
395 | 395 |
|
396 | 396 |
///Sets the map storing the distances calculated by the algorithm. |
397 | 397 |
///If you don't use this function before calling \ref run(), |
398 | 398 |
///it will allocate one. The destructor deallocates this |
399 | 399 |
///automatically allocated map, of course. |
400 | 400 |
///\return <tt> (*this) </tt> |
401 |
Bfs &distMap(DistMap &m) |
|
401 |
Bfs &distMap(DistMap &m) |
|
402 | 402 |
{ |
403 | 403 |
if(local_dist) { |
404 |
delete _dist; |
|
405 |
local_dist=false; |
|
404 |
delete _dist; |
|
405 |
local_dist=false; |
|
406 | 406 |
} |
407 | 407 |
_dist = &m; |
408 | 408 |
return *this; |
409 | 409 |
} |
410 | 410 |
|
411 | 411 |
public: |
... | ... |
@@ -429,57 +429,57 @@ |
429 | 429 |
{ |
430 | 430 |
create_maps(); |
431 | 431 |
_queue.resize(countNodes(*G)); |
432 | 432 |
_queue_head=_queue_tail=0; |
433 | 433 |
_curr_dist=1; |
434 | 434 |
for ( NodeIt u(*G) ; u!=INVALID ; ++u ) { |
435 |
_pred->set(u,INVALID); |
|
436 |
_reached->set(u,false); |
|
437 |
|
|
435 |
_pred->set(u,INVALID); |
|
436 |
_reached->set(u,false); |
|
437 |
_processed->set(u,false); |
|
438 | 438 |
} |
439 | 439 |
} |
440 |
|
|
440 |
|
|
441 | 441 |
///Adds a new source node. |
442 | 442 |
|
443 | 443 |
///Adds a new source node to the set of nodes to be processed. |
444 | 444 |
/// |
445 | 445 |
void addSource(Node s) |
446 | 446 |
{ |
447 | 447 |
if(!(*_reached)[s]) |
448 |
{ |
|
449 |
_reached->set(s,true); |
|
450 |
_pred->set(s,INVALID); |
|
451 |
_dist->set(s,0); |
|
452 |
_queue[_queue_head++]=s; |
|
453 |
_queue_next_dist=_queue_head; |
|
454 |
|
|
448 |
{ |
|
449 |
_reached->set(s,true); |
|
450 |
_pred->set(s,INVALID); |
|
451 |
_dist->set(s,0); |
|
452 |
_queue[_queue_head++]=s; |
|
453 |
_queue_next_dist=_queue_head; |
|
454 |
} |
|
455 | 455 |
} |
456 |
|
|
456 |
|
|
457 | 457 |
///Processes the next node. |
458 | 458 |
|
459 | 459 |
///Processes the next node. |
460 | 460 |
/// |
461 | 461 |
///\return The processed node. |
462 | 462 |
/// |
463 | 463 |
///\warning The queue must not be empty! |
464 | 464 |
Node processNextNode() |
465 | 465 |
{ |
466 | 466 |
if(_queue_tail==_queue_next_dist) { |
467 |
_curr_dist++; |
|
468 |
_queue_next_dist=_queue_head; |
|
467 |
_curr_dist++; |
|
468 |
_queue_next_dist=_queue_head; |
|
469 | 469 |
} |
470 | 470 |
Node n=_queue[_queue_tail++]; |
471 | 471 |
_processed->set(n,true); |
472 | 472 |
Node m; |
473 | 473 |
for(OutArcIt e(*G,n);e!=INVALID;++e) |
474 |
if(!(*_reached)[m=G->target(e)]) { |
|
475 |
_queue[_queue_head++]=m; |
|
476 |
_reached->set(m,true); |
|
477 |
_pred->set(m,e); |
|
478 |
_dist->set(m,_curr_dist); |
|
479 |
} |
|
474 |
if(!(*_reached)[m=G->target(e)]) { |
|
475 |
_queue[_queue_head++]=m; |
|
476 |
_reached->set(m,true); |
|
477 |
_pred->set(m,e); |
|
478 |
_dist->set(m,_curr_dist); |
|
479 |
} |
|
480 | 480 |
return n; |
481 | 481 |
} |
482 | 482 |
|
483 | 483 |
///Processes the next node. |
484 | 484 |
|
485 | 485 |
///Processes the next node. And checks that the given target node |
... | ... |
@@ -492,26 +492,26 @@ |
492 | 492 |
///\return The processed node. |
493 | 493 |
/// |
494 | 494 |
///\warning The queue must not be empty! |
495 | 495 |
Node processNextNode(Node target, bool& reach) |
496 | 496 |
{ |
497 | 497 |
if(_queue_tail==_queue_next_dist) { |
498 |
_curr_dist++; |
|
499 |
_queue_next_dist=_queue_head; |
|
498 |
_curr_dist++; |
|
499 |
_queue_next_dist=_queue_head; |
|
500 | 500 |
} |
501 | 501 |
Node n=_queue[_queue_tail++]; |
502 | 502 |
_processed->set(n,true); |
503 | 503 |
Node m; |
504 | 504 |
for(OutArcIt e(*G,n);e!=INVALID;++e) |
505 |
if(!(*_reached)[m=G->target(e)]) { |
|
506 |
_queue[_queue_head++]=m; |
|
507 |
_reached->set(m,true); |
|
508 |
_pred->set(m,e); |
|
509 |
|
|
505 |
if(!(*_reached)[m=G->target(e)]) { |
|
506 |
_queue[_queue_head++]=m; |
|
507 |
_reached->set(m,true); |
|
508 |
_pred->set(m,e); |
|
509 |
_dist->set(m,_curr_dist); |
|
510 | 510 |
reach = reach || (target == m); |
511 |
|
|
511 |
} |
|
512 | 512 |
return n; |
513 | 513 |
} |
514 | 514 |
|
515 | 515 |
///Processes the next node. |
516 | 516 |
|
517 | 517 |
///Processes the next node. And checks that at least one of |
... | ... |
@@ -525,51 +525,51 @@ |
525 | 525 |
/// |
526 | 526 |
///\warning The queue must not be empty! |
527 | 527 |
template<class NM> |
528 | 528 |
Node processNextNode(const NM& nm, Node& rnode) |
529 | 529 |
{ |
530 | 530 |
if(_queue_tail==_queue_next_dist) { |
531 |
_curr_dist++; |
|
532 |
_queue_next_dist=_queue_head; |
|
531 |
_curr_dist++; |
|
532 |
_queue_next_dist=_queue_head; |
|
533 | 533 |
} |
534 | 534 |
Node n=_queue[_queue_tail++]; |
535 | 535 |
_processed->set(n,true); |
536 | 536 |
Node m; |
537 | 537 |
for(OutArcIt e(*G,n);e!=INVALID;++e) |
538 |
if(!(*_reached)[m=G->target(e)]) { |
|
539 |
_queue[_queue_head++]=m; |
|
540 |
_reached->set(m,true); |
|
541 |
_pred->set(m,e); |
|
542 |
_dist->set(m,_curr_dist); |
|
543 |
if (nm[m] && rnode == INVALID) rnode = m; |
|
544 |
|
|
538 |
if(!(*_reached)[m=G->target(e)]) { |
|
539 |
_queue[_queue_head++]=m; |
|
540 |
_reached->set(m,true); |
|
541 |
_pred->set(m,e); |
|
542 |
_dist->set(m,_curr_dist); |
|
543 |
if (nm[m] && rnode == INVALID) rnode = m; |
|
544 |
} |
|
545 | 545 |
return n; |
546 | 546 |
} |
547 |
|
|
547 |
|
|
548 | 548 |
///Next node to be processed. |
549 | 549 |
|
550 | 550 |
///Next node to be processed. |
551 | 551 |
/// |
552 | 552 |
///\return The next node to be processed or INVALID if the queue is |
553 | 553 |
/// empty. |
554 | 554 |
Node nextNode() |
555 |
{ |
|
555 |
{ |
|
556 | 556 |
return _queue_tail<_queue_head?_queue[_queue_tail]:INVALID; |
557 | 557 |
} |
558 |
|
|
558 |
|
|
559 | 559 |
///\brief Returns \c false if there are nodes |
560 | 560 |
///to be processed in the queue |
561 | 561 |
/// |
562 | 562 |
///Returns \c false if there are nodes |
563 | 563 |
///to be processed in the queue |
564 | 564 |
bool emptyQueue() { return _queue_tail==_queue_head; } |
565 | 565 |
///Returns the number of the nodes to be processed. |
566 |
|
|
566 |
|
|
567 | 567 |
///Returns the number of the nodes to be processed in the queue. |
568 | 568 |
int queueSize() { return _queue_head-_queue_tail; } |
569 |
|
|
569 |
|
|
570 | 570 |
///Executes the algorithm. |
571 | 571 |
|
572 | 572 |
///Executes the algorithm. |
573 | 573 |
/// |
574 | 574 |
///\pre init() must be called and at least one node should be added |
575 | 575 |
///with addSource() before using this function. |
... | ... |
@@ -581,13 +581,13 @@ |
581 | 581 |
///- The shortest path tree. |
582 | 582 |
///- The distance of each node from the root(s). |
583 | 583 |
void start() |
584 | 584 |
{ |
585 | 585 |
while ( !emptyQueue() ) processNextNode(); |
586 | 586 |
} |
587 |
|
|
587 |
|
|
588 | 588 |
///Executes the algorithm until \c dest is reached. |
589 | 589 |
|
590 | 590 |
///Executes the algorithm until \c dest is reached. |
591 | 591 |
/// |
592 | 592 |
///\pre init() must be called and at least one node should be added |
593 | 593 |
///with addSource() before using this function. |
... | ... |
@@ -599,13 +599,13 @@ |
599 | 599 |
///- The distance of \c dest from the root(s). |
600 | 600 |
void start(Node dest) |
601 | 601 |
{ |
602 | 602 |
bool reach = false; |
603 | 603 |
while ( !emptyQueue() && !reach ) processNextNode(dest, reach); |
604 | 604 |
} |
605 |
|
|
605 |
|
|
606 | 606 |
///Executes the algorithm until a condition is met. |
607 | 607 |
|
608 | 608 |
///Executes the algorithm until a condition is met. |
609 | 609 |
/// |
610 | 610 |
///\pre init() must be called and at least one node should be added |
611 | 611 |
///with addSource() before using this function. |
... | ... |
@@ -618,19 +618,19 @@ |
618 | 618 |
///\c INVALID if no such node was found. |
619 | 619 |
template<class NM> |
620 | 620 |
Node start(const NM &nm) |
621 | 621 |
{ |
622 | 622 |
Node rnode = INVALID; |
623 | 623 |
while ( !emptyQueue() && rnode == INVALID ) { |
624 |
|
|
624 |
processNextNode(nm, rnode); |
|
625 | 625 |
} |
626 | 626 |
return rnode; |
627 | 627 |
} |
628 |
|
|
628 |
|
|
629 | 629 |
///Runs %BFS algorithm from node \c s. |
630 |
|
|
630 |
|
|
631 | 631 |
///This method runs the %BFS algorithm from a root node \c s |
632 | 632 |
///in order to |
633 | 633 |
///compute the |
634 | 634 |
///shortest path to each node. The algorithm computes |
635 | 635 |
///- The shortest path tree. |
636 | 636 |
///- The distance of each node from the root. |
... | ... |
@@ -643,15 +643,15 @@ |
643 | 643 |
///\endcode |
644 | 644 |
void run(Node s) { |
645 | 645 |
init(); |
646 | 646 |
addSource(s); |
647 | 647 |
start(); |
648 | 648 |
} |
649 |
|
|
649 |
|
|
650 | 650 |
///Finds the shortest path between \c s and \c t. |
651 |
|
|
651 |
|
|
652 | 652 |
///Finds the shortest path between \c s and \c t. |
653 | 653 |
/// |
654 | 654 |
///\return The length of the shortest s---t path if there exists one, |
655 | 655 |
///0 otherwise. |
656 | 656 |
///\note Apart from the return value, b.run(s) is |
657 | 657 |
///just a shortcut of the following code. |
... | ... |
@@ -663,30 +663,30 @@ |
663 | 663 |
int run(Node s,Node t) { |
664 | 664 |
init(); |
665 | 665 |
addSource(s); |
666 | 666 |
start(t); |
667 | 667 |
return reached(t) ? _curr_dist : 0; |
668 | 668 |
} |
669 |
|
|
669 |
|
|
670 | 670 |
///@} |
671 | 671 |
|
672 | 672 |
///\name Query Functions |
673 | 673 |
///The result of the %BFS algorithm can be obtained using these |
674 | 674 |
///functions.\n |
675 | 675 |
///Before the use of these functions, |
676 | 676 |
///either run() or start() must be calleb. |
677 |
|
|
677 |
|
|
678 | 678 |
///@{ |
679 | 679 |
|
680 | 680 |
typedef PredMapPath<Digraph, PredMap> Path; |
681 | 681 |
|
682 | 682 |
///Gives back the shortest path. |
683 |
|
|
683 |
|
|
684 | 684 |
///Gives back the shortest path. |
685 | 685 |
///\pre The \c t should be reachable from the source. |
686 |
Path path(Node t) |
|
686 |
Path path(Node t) |
|
687 | 687 |
{ |
688 | 688 |
return Path(*G, *_pred, t); |
689 | 689 |
} |
690 | 690 |
|
691 | 691 |
///The distance of a node from the root(s). |
692 | 692 |
|
... | ... |
@@ -719,126 +719,126 @@ |
719 | 719 |
///if \c v itself a root. |
720 | 720 |
///The shortest path tree used here is equal to the shortest path |
721 | 721 |
///tree used in \ref predArc(). |
722 | 722 |
///\pre Either \ref run() or \ref start() must be called before |
723 | 723 |
///using this function. |
724 | 724 |
Node predNode(Node v) const { return (*_pred)[v]==INVALID ? INVALID: |
725 |
G->source((*_pred)[v]); } |
|
726 |
|
|
725 |
G->source((*_pred)[v]); } |
|
726 |
|
|
727 | 727 |
///Returns a reference to the NodeMap of distances. |
728 | 728 |
|
729 | 729 |
///Returns a reference to the NodeMap of distances. |
730 | 730 |
///\pre Either \ref run() or \ref init() must |
731 | 731 |
///be called before using this function. |
732 | 732 |
const DistMap &distMap() const { return *_dist;} |
733 |
|
|
733 |
|
|
734 | 734 |
///Returns a reference to the shortest path tree map. |
735 | 735 |
|
736 | 736 |
///Returns a reference to the NodeMap of the arcs of the |
737 | 737 |
///shortest path tree. |
738 | 738 |
///\pre Either \ref run() or \ref init() |
739 | 739 |
///must be called before using this function. |
740 | 740 |
const PredMap &predMap() const { return *_pred;} |
741 |
|
|
741 |
|
|
742 | 742 |
///Checks if a node is reachable from the root. |
743 | 743 |
|
744 | 744 |
///Returns \c true if \c v is reachable from the root. |
745 | 745 |
///\warning The source nodes are indicated as unreached. |
746 | 746 |
///\pre Either \ref run() or \ref start() |
747 | 747 |
///must be called before using this function. |
748 | 748 |
/// |
749 | 749 |
bool reached(Node v) { return (*_reached)[v]; } |
750 |
|
|
750 |
|
|
751 | 751 |
///@} |
752 | 752 |
}; |
753 | 753 |
|
754 | 754 |
///Default traits class of Bfs function. |
755 | 755 |
|
756 | 756 |
///Default traits class of Bfs function. |
757 | 757 |
///\tparam GR Digraph type. |
758 | 758 |
template<class GR> |
759 | 759 |
struct BfsWizardDefaultTraits |
760 | 760 |
{ |
761 |
///The digraph type the algorithm runs on. |
|
761 |
///The digraph type the algorithm runs on. |
|
762 | 762 |
typedef GR Digraph; |
763 | 763 |
///\brief The type of the map that stores the last |
764 | 764 |
///arcs of the shortest paths. |
765 |
/// |
|
765 |
/// |
|
766 | 766 |
///The type of the map that stores the last |
767 | 767 |
///arcs of the shortest paths. |
768 | 768 |
///It must meet the \ref concepts::WriteMap "WriteMap" concept. |
769 | 769 |
/// |
770 | 770 |
typedef NullMap<typename Digraph::Node,typename GR::Arc> PredMap; |
771 | 771 |
///Instantiates a PredMap. |
772 |
|
|
773 |
///This function instantiates a \ref PredMap. |
|
772 |
|
|
773 |
///This function instantiates a \ref PredMap. |
|
774 | 774 |
///\param g is the digraph, to which we would like to define the PredMap. |
775 | 775 |
///\todo The digraph alone may be insufficient to initialize |
776 | 776 |
#ifdef DOXYGEN |
777 |
static PredMap *createPredMap(const GR &g) |
|
777 |
static PredMap *createPredMap(const GR &g) |
|
778 | 778 |
#else |
779 |
static PredMap *createPredMap(const GR &) |
|
779 |
static PredMap *createPredMap(const GR &) |
|
780 | 780 |
#endif |
781 | 781 |
{ |
782 | 782 |
return new PredMap(); |
783 | 783 |
} |
784 | 784 |
|
785 | 785 |
///The type of the map that indicates which nodes are processed. |
786 |
|
|
786 |
|
|
787 | 787 |
///The type of the map that indicates which nodes are processed. |
788 | 788 |
///It must meet the \ref concepts::WriteMap "WriteMap" concept. |
789 | 789 |
///\todo named parameter to set this type, function to read and write. |
790 | 790 |
typedef NullMap<typename Digraph::Node,bool> ProcessedMap; |
791 | 791 |
///Instantiates a ProcessedMap. |
792 |
|
|
793 |
///This function instantiates a \ref ProcessedMap. |
|
792 |
|
|
793 |
///This function instantiates a \ref ProcessedMap. |
|
794 | 794 |
///\param g is the digraph, to which |
795 | 795 |
///we would like to define the \ref ProcessedMap |
796 | 796 |
#ifdef DOXYGEN |
797 | 797 |
static ProcessedMap *createProcessedMap(const GR &g) |
798 | 798 |
#else |
799 | 799 |
static ProcessedMap *createProcessedMap(const GR &) |
800 | 800 |
#endif |
801 | 801 |
{ |
802 | 802 |
return new ProcessedMap(); |
803 | 803 |
} |
804 | 804 |
///The type of the map that indicates which nodes are reached. |
805 |
|
|
805 |
|
|
806 | 806 |
///The type of the map that indicates which nodes are reached. |
807 | 807 |
///It must meet the \ref concepts::WriteMap "WriteMap" concept. |
808 | 808 |
///\todo named parameter to set this type, function to read and write. |
809 | 809 |
typedef typename Digraph::template NodeMap<bool> ReachedMap; |
810 | 810 |
///Instantiates a ReachedMap. |
811 |
|
|
812 |
///This function instantiates a \ref ReachedMap. |
|
811 |
|
|
812 |
///This function instantiates a \ref ReachedMap. |
|
813 | 813 |
///\param G is the digraph, to which |
814 | 814 |
///we would like to define the \ref ReachedMap. |
815 | 815 |
static ReachedMap *createReachedMap(const GR &G) |
816 | 816 |
{ |
817 | 817 |
return new ReachedMap(G); |
818 | 818 |
} |
819 | 819 |
///The type of the map that stores the dists of the nodes. |
820 |
|
|
820 |
|
|
821 | 821 |
///The type of the map that stores the dists of the nodes. |
822 | 822 |
///It must meet the \ref concepts::WriteMap "WriteMap" concept. |
823 | 823 |
/// |
824 | 824 |
typedef NullMap<typename Digraph::Node,int> DistMap; |
825 | 825 |
///Instantiates a DistMap. |
826 |
|
|
827 |
///This function instantiates a \ref DistMap. |
|
826 |
|
|
827 |
///This function instantiates a \ref DistMap. |
|
828 | 828 |
///\param g is the digraph, to which we would like to define the \ref DistMap |
829 | 829 |
#ifdef DOXYGEN |
830 | 830 |
static DistMap *createDistMap(const GR &g) |
831 | 831 |
#else |
832 | 832 |
static DistMap *createDistMap(const GR &) |
833 | 833 |
#endif |
834 | 834 |
{ |
835 | 835 |
return new DistMap(); |
836 | 836 |
} |
837 | 837 |
}; |
838 |
|
|
838 |
|
|
839 | 839 |
/// Default traits used by \ref BfsWizard |
840 | 840 |
|
841 | 841 |
/// To make it easier to use Bfs algorithm |
842 | 842 |
///we have created a wizard class. |
843 | 843 |
/// This \ref BfsWizard class needs default traits, |
844 | 844 |
///as well as the \ref Bfs class. |
... | ... |
@@ -862,34 +862,34 @@ |
862 | 862 |
///Pointer to the map of predecessors arcs. |
863 | 863 |
void *_pred; |
864 | 864 |
///Pointer to the map of distances. |
865 | 865 |
void *_dist; |
866 | 866 |
///Pointer to the source node. |
867 | 867 |
Node _source; |
868 |
|
|
868 |
|
|
869 | 869 |
public: |
870 | 870 |
/// Constructor. |
871 |
|
|
871 |
|
|
872 | 872 |
/// This constructor does not require parameters, therefore it initiates |
873 | 873 |
/// all of the attributes to default values (0, INVALID). |
874 | 874 |
BfsWizardBase() : _g(0), _reached(0), _processed(0), _pred(0), |
875 |
|
|
875 |
_dist(0), _source(INVALID) {} |
|
876 | 876 |
|
877 | 877 |
/// Constructor. |
878 |
|
|
878 |
|
|
879 | 879 |
/// This constructor requires some parameters, |
880 | 880 |
/// listed in the parameters list. |
881 | 881 |
/// Others are initiated to 0. |
882 | 882 |
/// \param g is the initial value of \ref _g |
883 | 883 |
/// \param s is the initial value of \ref _source |
884 | 884 |
BfsWizardBase(const GR &g, Node s=INVALID) : |
885 |
_g(reinterpret_cast<void*>(const_cast<GR*>(&g))), |
|
885 |
_g(reinterpret_cast<void*>(const_cast<GR*>(&g))), |
|
886 | 886 |
_reached(0), _processed(0), _pred(0), _dist(0), _source(s) {} |
887 | 887 |
|
888 | 888 |
}; |
889 |
|
|
889 |
|
|
890 | 890 |
/// A class to make the usage of Bfs algorithm easier |
891 | 891 |
|
892 | 892 |
/// This class is created to make it easier to use Bfs algorithm. |
893 | 893 |
/// It uses the functions and features of the plain \ref Bfs, |
894 | 894 |
/// but it is much simpler to use it. |
895 | 895 |
/// |
... | ... |
@@ -918,13 +918,13 @@ |
918 | 918 |
//\e |
919 | 919 |
typedef typename Digraph::NodeIt NodeIt; |
920 | 920 |
//\e |
921 | 921 |
typedef typename Digraph::Arc Arc; |
922 | 922 |
//\e |
923 | 923 |
typedef typename Digraph::OutArcIt OutArcIt; |
924 |
|
|
924 |
|
|
925 | 925 |
///\brief The type of the map that stores |
926 | 926 |
///the reached nodes |
927 | 927 |
typedef typename TR::ReachedMap ReachedMap; |
928 | 928 |
///\brief The type of the map that stores |
929 | 929 |
///the processed nodes |
930 | 930 |
typedef typename TR::ProcessedMap ProcessedMap; |
... | ... |
@@ -948,26 +948,26 @@ |
948 | 948 |
///Copy constructor |
949 | 949 |
BfsWizard(const TR &b) : TR(b) {} |
950 | 950 |
|
951 | 951 |
~BfsWizard() {} |
952 | 952 |
|
953 | 953 |
///Runs Bfs algorithm from a given node. |
954 |
|
|
954 |
|
|
955 | 955 |
///Runs Bfs algorithm from a given node. |
956 | 956 |
///The node can be given by the \ref source function. |
957 | 957 |
void run() |
958 | 958 |
{ |
959 | 959 |
if(Base::_source==INVALID) throw UninitializedParameter(); |
960 | 960 |
Bfs<Digraph,TR> alg(*reinterpret_cast<const Digraph*>(Base::_g)); |
961 | 961 |
if(Base::_reached) |
962 |
alg.reachedMap(*reinterpret_cast<ReachedMap*>(Base::_reached)); |
|
963 |
if(Base::_processed) |
|
962 |
alg.reachedMap(*reinterpret_cast<ReachedMap*>(Base::_reached)); |
|
963 |
if(Base::_processed) |
|
964 | 964 |
alg.processedMap(*reinterpret_cast<ProcessedMap*>(Base::_processed)); |
965 |
if(Base::_pred) |
|
965 |
if(Base::_pred) |
|
966 | 966 |
alg.predMap(*reinterpret_cast<PredMap*>(Base::_pred)); |
967 |
if(Base::_dist) |
|
967 |
if(Base::_dist) |
|
968 | 968 |
alg.distMap(*reinterpret_cast<DistMap*>(Base::_dist)); |
969 | 969 |
alg.run(Base::_source); |
970 | 970 |
} |
971 | 971 |
|
972 | 972 |
///Runs Bfs algorithm from the given node. |
973 | 973 |
|
... | ... |
@@ -982,101 +982,101 @@ |
982 | 982 |
template<class T> |
983 | 983 |
struct DefPredMapBase : public Base { |
984 | 984 |
typedef T PredMap; |
985 | 985 |
static PredMap *createPredMap(const Digraph &) { return 0; }; |
986 | 986 |
DefPredMapBase(const TR &b) : TR(b) {} |
987 | 987 |
}; |
988 |
|
|
988 |
|
|
989 | 989 |
///\brief \ref named-templ-param "Named parameter" |
990 | 990 |
///function for setting PredMap |
991 | 991 |
/// |
992 | 992 |
/// \ref named-templ-param "Named parameter" |
993 | 993 |
///function for setting PredMap |
994 | 994 |
/// |
995 | 995 |
template<class T> |
996 |
BfsWizard<DefPredMapBase<T> > predMap(const T &t) |
|
996 |
BfsWizard<DefPredMapBase<T> > predMap(const T &t) |
|
997 | 997 |
{ |
998 | 998 |
Base::_pred=reinterpret_cast<void*>(const_cast<T*>(&t)); |
999 | 999 |
return BfsWizard<DefPredMapBase<T> >(*this); |
1000 | 1000 |
} |
1001 |
|
|
1002 |
|
|
1001 |
|
|
1002 |
|
|
1003 | 1003 |
template<class T> |
1004 | 1004 |
struct DefReachedMapBase : public Base { |
1005 | 1005 |
typedef T ReachedMap; |
1006 | 1006 |
static ReachedMap *createReachedMap(const Digraph &) { return 0; }; |
1007 | 1007 |
DefReachedMapBase(const TR &b) : TR(b) {} |
1008 | 1008 |
}; |
1009 |
|
|
1009 |
|
|
1010 | 1010 |
///\brief \ref named-templ-param "Named parameter" |
1011 | 1011 |
///function for setting ReachedMap |
1012 | 1012 |
/// |
1013 | 1013 |
/// \ref named-templ-param "Named parameter" |
1014 | 1014 |
///function for setting ReachedMap |
1015 | 1015 |
/// |
1016 | 1016 |
template<class T> |
1017 |
BfsWizard<DefReachedMapBase<T> > reachedMap(const T &t) |
|
1017 |
BfsWizard<DefReachedMapBase<T> > reachedMap(const T &t) |
|
1018 | 1018 |
{ |
1019 | 1019 |
Base::_reached=reinterpret_cast<void*>(const_cast<T*>(&t)); |
1020 | 1020 |
return BfsWizard<DefReachedMapBase<T> >(*this); |
1021 | 1021 |
} |
1022 |
|
|
1022 |
|
|
1023 | 1023 |
|
1024 | 1024 |
template<class T> |
1025 | 1025 |
struct DefProcessedMapBase : public Base { |
1026 | 1026 |
typedef T ProcessedMap; |
1027 | 1027 |
static ProcessedMap *createProcessedMap(const Digraph &) { return 0; }; |
1028 | 1028 |
DefProcessedMapBase(const TR &b) : TR(b) {} |
1029 | 1029 |
}; |
1030 |
|
|
1030 |
|
|
1031 | 1031 |
///\brief \ref named-templ-param "Named parameter" |
1032 | 1032 |
///function for setting ProcessedMap |
1033 | 1033 |
/// |
1034 | 1034 |
/// \ref named-templ-param "Named parameter" |
1035 | 1035 |
///function for setting ProcessedMap |
1036 | 1036 |
/// |
1037 | 1037 |
template<class T> |
1038 |
BfsWizard<DefProcessedMapBase<T> > processedMap(const T &t) |
|
1038 |
BfsWizard<DefProcessedMapBase<T> > processedMap(const T &t) |
|
1039 | 1039 |
{ |
1040 | 1040 |
Base::_processed=reinterpret_cast<void*>(const_cast<T*>(&t)); |
1041 | 1041 |
return BfsWizard<DefProcessedMapBase<T> >(*this); |
1042 | 1042 |
} |
1043 |
|
|
1044 |
|
|
1043 |
|
|
1044 |
|
|
1045 | 1045 |
template<class T> |
1046 | 1046 |
struct DefDistMapBase : public Base { |
1047 | 1047 |
typedef T DistMap; |
1048 | 1048 |
static DistMap *createDistMap(const Digraph &) { return 0; }; |
1049 | 1049 |
DefDistMapBase(const TR &b) : TR(b) {} |
1050 | 1050 |
}; |
1051 |
|
|
1051 |
|
|
1052 | 1052 |
///\brief \ref named-templ-param "Named parameter" |
1053 | 1053 |
///function for setting DistMap type |
1054 | 1054 |
/// |
1055 | 1055 |
/// \ref named-templ-param "Named parameter" |
1056 | 1056 |
///function for setting DistMap type |
1057 | 1057 |
/// |
1058 | 1058 |
template<class T> |
1059 |
BfsWizard<DefDistMapBase<T> > distMap(const T &t) |
|
1059 |
BfsWizard<DefDistMapBase<T> > distMap(const T &t) |
|
1060 | 1060 |
{ |
1061 | 1061 |
Base::_dist=reinterpret_cast<void*>(const_cast<T*>(&t)); |
1062 | 1062 |
return BfsWizard<DefDistMapBase<T> >(*this); |
1063 | 1063 |
} |
1064 |
|
|
1064 |
|
|
1065 | 1065 |
/// Sets the source node, from which the Bfs algorithm runs. |
1066 | 1066 |
|
1067 | 1067 |
/// Sets the source node, from which the Bfs algorithm runs. |
1068 | 1068 |
/// \param s is the source node. |
1069 |
BfsWizard<TR> &source(Node s) |
|
1069 |
BfsWizard<TR> &source(Node s) |
|
1070 | 1070 |
{ |
1071 | 1071 |
Base::_source=s; |
1072 | 1072 |
return *this; |
1073 | 1073 |
} |
1074 |
|
|
1074 |
|
|
1075 | 1075 |
}; |
1076 |
|
|
1076 |
|
|
1077 | 1077 |
///Function type interface for Bfs algorithm. |
1078 | 1078 |
|
1079 | 1079 |
/// \ingroup search |
1080 | 1080 |
///Function type interface for Bfs algorithm. |
1081 | 1081 |
/// |
1082 | 1082 |
///This function also has several |
... | ... |
@@ -1097,41 +1097,41 @@ |
1097 | 1097 |
{ |
1098 | 1098 |
return BfsWizard<BfsWizardBase<GR> >(g,s); |
1099 | 1099 |
} |
1100 | 1100 |
|
1101 | 1101 |
#ifdef DOXYGEN |
1102 | 1102 |
/// \brief Visitor class for bfs. |
1103 |
/// |
|
1103 |
/// |
|
1104 | 1104 |
/// This class defines the interface of the BfsVisit events, and |
1105 | 1105 |
/// it could be the base of a real Visitor class. |
1106 | 1106 |
template <typename _Digraph> |
1107 | 1107 |
struct BfsVisitor { |
1108 | 1108 |
typedef _Digraph Digraph; |
1109 | 1109 |
typedef typename Digraph::Arc Arc; |
1110 | 1110 |
typedef typename Digraph::Node Node; |
1111 | 1111 |
/// \brief Called when the arc reach a node. |
1112 |
/// |
|
1112 |
/// |
|
1113 | 1113 |
/// It is called when the bfs find an arc which target is not |
1114 | 1114 |
/// reached yet. |
1115 | 1115 |
void discover(const Arc& arc) {} |
1116 | 1116 |
/// \brief Called when the node reached first time. |
1117 |
/// |
|
1117 |
/// |
|
1118 | 1118 |
/// It is Called when the node reached first time. |
1119 | 1119 |
void reach(const Node& node) {} |
1120 |
/// \brief Called when the arc examined but target of the arc |
|
1120 |
/// \brief Called when the arc examined but target of the arc |
|
1121 | 1121 |
/// already discovered. |
1122 |
/// |
|
1123 |
/// It called when the arc examined but the target of the arc |
|
1122 |
/// |
|
1123 |
/// It called when the arc examined but the target of the arc |
|
1124 | 1124 |
/// already discovered. |
1125 | 1125 |
void examine(const Arc& arc) {} |
1126 | 1126 |
/// \brief Called for the source node of the bfs. |
1127 |
/// |
|
1127 |
/// |
|
1128 | 1128 |
/// It is called for the source node of the bfs. |
1129 | 1129 |
void start(const Node& node) {} |
1130 | 1130 |
/// \brief Called when the node processed. |
1131 |
/// |
|
1131 |
/// |
|
1132 | 1132 |
/// It is Called when the node processed. |
1133 | 1133 |
void process(const Node& node) {} |
1134 | 1134 |
}; |
1135 | 1135 |
#else |
1136 | 1136 |
template <typename _Digraph> |
1137 | 1137 |
struct BfsVisitor { |
... | ... |
@@ -1144,18 +1144,18 @@ |
1144 | 1144 |
void start(const Node&) {} |
1145 | 1145 |
void process(const Node&) {} |
1146 | 1146 |
|
1147 | 1147 |
template <typename _Visitor> |
1148 | 1148 |
struct Constraints { |
1149 | 1149 |
void constraints() { |
1150 |
Arc arc; |
|
1151 |
Node node; |
|
1152 |
visitor.discover(arc); |
|
1153 |
visitor.reach(node); |
|
1154 |
visitor.examine(arc); |
|
1155 |
visitor.start(node); |
|
1150 |
Arc arc; |
|
1151 |
Node node; |
|
1152 |
visitor.discover(arc); |
|
1153 |
visitor.reach(node); |
|
1154 |
visitor.examine(arc); |
|
1155 |
visitor.start(node); |
|
1156 | 1156 |
visitor.process(node); |
1157 | 1157 |
} |
1158 | 1158 |
_Visitor& visitor; |
1159 | 1159 |
}; |
1160 | 1160 |
}; |
1161 | 1161 |
#endif |
... | ... |
@@ -1164,75 +1164,75 @@ |
1164 | 1164 |
/// |
1165 | 1165 |
/// Default traits class of BfsVisit class. |
1166 | 1166 |
/// \tparam _Digraph Digraph type. |
1167 | 1167 |
template<class _Digraph> |
1168 | 1168 |
struct BfsVisitDefaultTraits { |
1169 | 1169 |
|
1170 |
/// \brief The digraph type the algorithm runs on. |
|
1170 |
/// \brief The digraph type the algorithm runs on. |
|
1171 | 1171 |
typedef _Digraph Digraph; |
1172 | 1172 |
|
1173 | 1173 |
/// \brief The type of the map that indicates which nodes are reached. |
1174 |
/// |
|
1174 |
/// |
|
1175 | 1175 |
/// The type of the map that indicates which nodes are reached. |
1176 | 1176 |
/// It must meet the \ref concepts::WriteMap "WriteMap" concept. |
1177 | 1177 |
/// \todo named parameter to set this type, function to read and write. |
1178 | 1178 |
typedef typename Digraph::template NodeMap<bool> ReachedMap; |
1179 | 1179 |
|
1180 | 1180 |
/// \brief Instantiates a ReachedMap. |
1181 | 1181 |
/// |
1182 |
/// This function instantiates a \ref ReachedMap. |
|
1182 |
/// This function instantiates a \ref ReachedMap. |
|
1183 | 1183 |
/// \param digraph is the digraph, to which |
1184 | 1184 |
/// we would like to define the \ref ReachedMap. |
1185 | 1185 |
static ReachedMap *createReachedMap(const Digraph &digraph) { |
1186 | 1186 |
return new ReachedMap(digraph); |
1187 | 1187 |
} |
1188 | 1188 |
|
1189 | 1189 |
}; |
1190 | 1190 |
|
1191 | 1191 |
/// \ingroup search |
1192 |
/// |
|
1192 |
/// |
|
1193 | 1193 |
/// \brief %BFS Visit algorithm class. |
1194 |
/// |
|
1194 |
/// |
|
1195 | 1195 |
/// This class provides an efficient implementation of the %BFS algorithm |
1196 | 1196 |
/// with visitor interface. |
1197 | 1197 |
/// |
1198 | 1198 |
/// The %BfsVisit class provides an alternative interface to the Bfs |
1199 | 1199 |
/// class. It works with callback mechanism, the BfsVisit object calls |
1200 |
/// on every bfs event the \c Visitor class member functions. |
|
1200 |
/// on every bfs event the \c Visitor class member functions. |
|
1201 | 1201 |
/// |
1202 | 1202 |
/// \tparam _Digraph The digraph type the algorithm runs on. The default value is |
1203 | 1203 |
/// \ref ListDigraph. The value of _Digraph is not used directly by Bfs, it |
1204 | 1204 |
/// is only passed to \ref BfsDefaultTraits. |
1205 |
/// \tparam _Visitor The Visitor object for the algorithm. The |
|
1205 |
/// \tparam _Visitor The Visitor object for the algorithm. The |
|
1206 | 1206 |
/// \ref BfsVisitor "BfsVisitor<_Digraph>" is an empty Visitor which |
1207 | 1207 |
/// does not observe the Bfs events. If you want to observe the bfs |
1208 | 1208 |
/// events you should implement your own Visitor class. |
1209 |
/// \tparam _Traits Traits class to set various data types used by the |
|
1209 |
/// \tparam _Traits Traits class to set various data types used by the |
|
1210 | 1210 |
/// algorithm. The default traits class is |
1211 | 1211 |
/// \ref BfsVisitDefaultTraits "BfsVisitDefaultTraits<_Digraph>". |
1212 | 1212 |
/// See \ref BfsVisitDefaultTraits for the documentation of |
1213 | 1213 |
/// a Bfs visit traits class. |
1214 | 1214 |
#ifdef DOXYGEN |
1215 | 1215 |
template <typename _Digraph, typename _Visitor, typename _Traits> |
1216 | 1216 |
#else |
1217 | 1217 |
template <typename _Digraph = ListDigraph, |
1218 |
typename _Visitor = BfsVisitor<_Digraph>, |
|
1219 |
typename _Traits = BfsDefaultTraits<_Digraph> > |
|
1218 |
typename _Visitor = BfsVisitor<_Digraph>, |
|
1219 |
typename _Traits = BfsDefaultTraits<_Digraph> > |
|
1220 | 1220 |
#endif |
1221 | 1221 |
class BfsVisit { |
1222 | 1222 |
public: |
1223 |
|
|
1223 |
|
|
1224 | 1224 |
/// \brief \ref Exception for uninitialized parameters. |
1225 | 1225 |
/// |
1226 | 1226 |
/// This error represents problems in the initialization |
1227 | 1227 |
/// of the parameters of the algorithms. |
1228 | 1228 |
class UninitializedParameter : public lemon::UninitializedParameter { |
1229 | 1229 |
public: |
1230 |
virtual const char* what() const throw() |
|
1230 |
virtual const char* what() const throw() |
|
1231 | 1231 |
{ |
1232 |
|
|
1232 |
return "lemon::BfsVisit::UninitializedParameter"; |
|
1233 | 1233 |
} |
1234 | 1234 |
}; |
1235 | 1235 |
|
1236 | 1236 |
typedef _Traits Traits; |
1237 | 1237 |
|
1238 | 1238 |
typedef typename Traits::Digraph Digraph; |
... | ... |
@@ -1263,59 +1263,59 @@ |
1263 | 1263 |
|
1264 | 1264 |
/// \brief Creates the maps if necessary. |
1265 | 1265 |
/// |
1266 | 1266 |
/// Creates the maps if necessary. |
1267 | 1267 |
void create_maps() { |
1268 | 1268 |
if(!_reached) { |
1269 |
local_reached = true; |
|
1270 |
_reached = Traits::createReachedMap(*_digraph); |
|
1269 |
local_reached = true; |
|
1270 |
_reached = Traits::createReachedMap(*_digraph); |
|
1271 | 1271 |
} |
1272 | 1272 |
} |
1273 | 1273 |
|
1274 | 1274 |
protected: |
1275 | 1275 |
|
1276 | 1276 |
BfsVisit() {} |
1277 |
|
|
1277 |
|
|
1278 | 1278 |
public: |
1279 | 1279 |
|
1280 | 1280 |
typedef BfsVisit Create; |
1281 | 1281 |
|
1282 | 1282 |
/// \name Named template parameters |
1283 | 1283 |
|
1284 | 1284 |
///@{ |
1285 | 1285 |
template <class T> |
1286 | 1286 |
struct DefReachedMapTraits : public Traits { |
1287 | 1287 |
typedef T ReachedMap; |
1288 | 1288 |
static ReachedMap *createReachedMap(const Digraph &digraph) { |
1289 |
|
|
1289 |
throw UninitializedParameter(); |
|
1290 | 1290 |
} |
1291 | 1291 |
}; |
1292 |
/// \brief \ref named-templ-param "Named parameter" for setting |
|
1292 |
/// \brief \ref named-templ-param "Named parameter" for setting |
|
1293 | 1293 |
/// ReachedMap type |
1294 | 1294 |
/// |
1295 | 1295 |
/// \ref named-templ-param "Named parameter" for setting ReachedMap type |
1296 | 1296 |
template <class T> |
1297 | 1297 |
struct DefReachedMap : public BfsVisit< Digraph, Visitor, |
1298 |
|
|
1298 |
DefReachedMapTraits<T> > { |
|
1299 | 1299 |
typedef BfsVisit< Digraph, Visitor, DefReachedMapTraits<T> > Create; |
1300 | 1300 |
}; |
1301 | 1301 |
///@} |
1302 | 1302 |
|
1303 |
public: |
|
1304 |
|
|
1303 |
public: |
|
1304 |
|
|
1305 | 1305 |
/// \brief Constructor. |
1306 | 1306 |
/// |
1307 | 1307 |
/// Constructor. |
1308 | 1308 |
/// |
1309 | 1309 |
/// \param digraph the digraph the algorithm will run on. |
1310 | 1310 |
/// \param visitor The visitor of the algorithm. |
1311 | 1311 |
/// |
1312 |
BfsVisit(const Digraph& digraph, Visitor& visitor) |
|
1312 |
BfsVisit(const Digraph& digraph, Visitor& visitor) |
|
1313 | 1313 |
: _digraph(&digraph), _visitor(&visitor), |
1314 |
_reached(0), local_reached(false) {} |
|
1315 |
|
|
1314 |
_reached(0), local_reached(false) {} |
|
1315 |
|
|
1316 | 1316 |
/// \brief Destructor. |
1317 | 1317 |
/// |
1318 | 1318 |
/// Destructor. |
1319 | 1319 |
~BfsVisit() { |
1320 | 1320 |
if(local_reached) delete _reached; |
1321 | 1321 |
} |
... | ... |
@@ -1326,14 +1326,14 @@ |
1326 | 1326 |
/// If you don't use this function before calling \ref run(), |
1327 | 1327 |
/// it will allocate one. The destuctor deallocates this |
1328 | 1328 |
/// automatically allocated map, of course. |
1329 | 1329 |
/// \return <tt> (*this) </tt> |
1330 | 1330 |
BfsVisit &reachedMap(ReachedMap &m) { |
1331 | 1331 |
if(local_reached) { |
1332 |
delete _reached; |
|
1333 |
local_reached = false; |
|
1332 |
delete _reached; |
|
1333 |
local_reached = false; |
|
1334 | 1334 |
} |
1335 | 1335 |
_reached = &m; |
1336 | 1336 |
return *this; |
1337 | 1337 |
} |
1338 | 1338 |
|
1339 | 1339 |
public: |
... | ... |
@@ -1354,36 +1354,36 @@ |
1354 | 1354 |
/// |
1355 | 1355 |
void init() { |
1356 | 1356 |
create_maps(); |
1357 | 1357 |
_list.resize(countNodes(*_digraph)); |
1358 | 1358 |
_list_front = _list_back = -1; |
1359 | 1359 |
for (NodeIt u(*_digraph) ; u != INVALID ; ++u) { |
1360 |
|
|
1360 |
_reached->set(u, false); |
|
1361 | 1361 |
} |
1362 | 1362 |
} |
1363 |
|
|
1363 |
|
|
1364 | 1364 |
/// \brief Adds a new source node. |
1365 | 1365 |
/// |
1366 | 1366 |
/// Adds a new source node to the set of nodes to be processed. |
1367 | 1367 |
void addSource(Node s) { |
1368 | 1368 |
if(!(*_reached)[s]) { |
1369 |
_reached->set(s,true); |
|
1370 |
_visitor->start(s); |
|
1371 |
|
|
1369 |
_reached->set(s,true); |
|
1370 |
_visitor->start(s); |
|
1371 |
_visitor->reach(s); |
|
1372 | 1372 |
_list[++_list_back] = s; |
1373 |
|
|
1373 |
} |
|
1374 | 1374 |
} |
1375 |
|
|
1375 |
|
|
1376 | 1376 |
/// \brief Processes the next node. |
1377 | 1377 |
/// |
1378 | 1378 |
/// Processes the next node. |
1379 | 1379 |
/// |
1380 | 1380 |
/// \return The processed node. |
1381 | 1381 |
/// |
1382 | 1382 |
/// \pre The queue must not be empty! |
1383 |
Node processNextNode() { |
|
1383 |
Node processNextNode() { |
|
1384 | 1384 |
Node n = _list[++_list_front]; |
1385 | 1385 |
_visitor->process(n); |
1386 | 1386 |
Arc e; |
1387 | 1387 |
for (_digraph->firstOut(e, n); e != INVALID; _digraph->nextOut(e)) { |
1388 | 1388 |
Node m = _digraph->target(e); |
1389 | 1389 |
if (!(*_reached)[m]) { |
... | ... |
@@ -1464,13 +1464,13 @@ |
1464 | 1464 |
/// \brief Next node to be processed. |
1465 | 1465 |
/// |
1466 | 1466 |
/// Next node to be processed. |
1467 | 1467 |
/// |
1468 | 1468 |
/// \return The next node to be processed or INVALID if the stack is |
1469 | 1469 |
/// empty. |
1470 |
Node nextNode() { |
|
1470 |
Node nextNode() { |
|
1471 | 1471 |
return _list_front != _list_back ? _list[_list_front + 1] : INVALID; |
1472 | 1472 |
} |
1473 | 1473 |
|
1474 | 1474 |
/// \brief Returns \c false if there are nodes |
1475 | 1475 |
/// to be processed in the queue |
1476 | 1476 |
/// |
... | ... |
@@ -1479,34 +1479,34 @@ |
1479 | 1479 |
bool emptyQueue() { return _list_front == _list_back; } |
1480 | 1480 |
|
1481 | 1481 |
/// \brief Returns the number of the nodes to be processed. |
1482 | 1482 |
/// |
1483 | 1483 |
/// Returns the number of the nodes to be processed in the queue. |
1484 | 1484 |
int queueSize() { return _list_back - _list_front; } |
1485 |
|
|
1485 |
|
|
1486 | 1486 |
/// \brief Executes the algorithm. |
1487 | 1487 |
/// |
1488 | 1488 |
/// Executes the algorithm. |
1489 | 1489 |
/// |
1490 | 1490 |
/// \pre init() must be called and at least one node should be added |
1491 | 1491 |
/// with addSource() before using this function. |
1492 | 1492 |
void start() { |
1493 | 1493 |
while ( !emptyQueue() ) processNextNode(); |
1494 | 1494 |
} |
1495 |
|
|
1495 |
|
|
1496 | 1496 |
/// \brief Executes the algorithm until \c dest is reached. |
1497 | 1497 |
/// |
1498 | 1498 |
/// Executes the algorithm until \c dest is reached. |
1499 | 1499 |
/// |
1500 | 1500 |
/// \pre init() must be called and at least one node should be added |
1501 | 1501 |
/// with addSource() before using this function. |
1502 | 1502 |
void start(Node dest) { |
1503 | 1503 |
bool reach = false; |
1504 | 1504 |
while ( !emptyQueue() && !reach ) processNextNode(dest, reach); |
1505 | 1505 |
} |
1506 |
|
|
1506 |
|
|
1507 | 1507 |
/// \brief Executes the algorithm until a condition is met. |
1508 | 1508 |
/// |
1509 | 1509 |
/// Executes the algorithm until a condition is met. |
1510 | 1510 |
/// |
1511 | 1511 |
/// \pre init() must be called and at least one node should be added |
1512 | 1512 |
/// with addSource() before using this function. |
... | ... |
@@ -1518,13 +1518,13 @@ |
1518 | 1518 |
///\return The reached node \c v with <tt>nm[v]</tt> true or |
1519 | 1519 |
///\c INVALID if no such node was found. |
1520 | 1520 |
template <typename NM> |
1521 | 1521 |
Node start(const NM &nm) { |
1522 | 1522 |
Node rnode = INVALID; |
1523 | 1523 |
while ( !emptyQueue() && rnode == INVALID ) { |
1524 |
|
|
1524 |
processNextNode(nm, rnode); |
|
1525 | 1525 |
} |
1526 | 1526 |
return rnode; |
1527 | 1527 |
} |
1528 | 1528 |
|
1529 | 1529 |
/// \brief Runs %BFSVisit algorithm from node \c s. |
1530 | 1530 |
/// |
... | ... |
@@ -1539,13 +1539,13 @@ |
1539 | 1539 |
init(); |
1540 | 1540 |
addSource(s); |
1541 | 1541 |
start(); |
1542 | 1542 |
} |
1543 | 1543 |
|
1544 | 1544 |
/// \brief Runs %BFSVisit algorithm to visit all nodes in the digraph. |
1545 |
/// |
|
1545 |
/// |
|
1546 | 1546 |
/// This method runs the %BFS algorithm in order to |
1547 | 1547 |
/// compute the %BFS path to each node. The algorithm computes |
1548 | 1548 |
/// - The %BFS tree. |
1549 | 1549 |
/// - The distance of each node from the root in the %BFS tree. |
1550 | 1550 |
/// |
1551 | 1551 |
///\note b.run() is just a shortcut of the following code. |
1 |
/* -*- C++ -*- |
|
1 |
/* -*- mode: C++; indent-tabs-mode: nil; -*- |
|
2 | 2 |
* |
3 |
* This file is a part of LEMON, a generic C++ optimization library |
|
3 |
* This file is a part of LEMON, a generic C++ optimization library. |
|
4 | 4 |
* |
5 | 5 |
* Copyright (C) 2003-2008 |
6 | 6 |
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
7 | 7 |
* (Egervary Research Group on Combinatorial Optimization, EGRES). |
8 | 8 |
* |
9 | 9 |
* Permission to use, modify and distribute this software is granted |
... | ... |
@@ -45,13 +45,13 @@ |
45 | 45 |
///\tparam _Compare A class for the ordering of the priorities. The |
46 | 46 |
///default is \c std::less<_Prio>. |
47 | 47 |
/// |
48 | 48 |
///\sa FibHeap |
49 | 49 |
///\sa Dijkstra |
50 | 50 |
template <typename _Prio, typename _ItemIntMap, |
51 |
|
|
51 |
typename _Compare = std::less<_Prio> > |
|
52 | 52 |
class BinHeap { |
53 | 53 |
|
54 | 54 |
public: |
55 | 55 |
///\e |
56 | 56 |
typedef _ItemIntMap ItemIntMap; |
57 | 57 |
///\e |
... | ... |
@@ -87,43 +87,43 @@ |
87 | 87 |
/// |
88 | 88 |
/// The constructor. |
89 | 89 |
/// \param _iim should be given to the constructor, since it is used |
90 | 90 |
/// internally to handle the cross references. The value of the map |
91 | 91 |
/// should be PRE_HEAP (-1) for each element. |
92 | 92 |
explicit BinHeap(ItemIntMap &_iim) : iim(_iim) {} |
93 |
|
|
93 |
|
|
94 | 94 |
/// \brief The constructor. |
95 | 95 |
/// |
96 | 96 |
/// The constructor. |
97 | 97 |
/// \param _iim should be given to the constructor, since it is used |
98 | 98 |
/// internally to handle the cross references. The value of the map |
99 | 99 |
/// should be PRE_HEAP (-1) for each element. |
100 | 100 |
/// |
101 | 101 |
/// \param _comp The comparator function object. |
102 |
BinHeap(ItemIntMap &_iim, const Compare &_comp) |
|
102 |
BinHeap(ItemIntMap &_iim, const Compare &_comp) |
|
103 | 103 |
: iim(_iim), comp(_comp) {} |
104 | 104 |
|
105 | 105 |
|
106 | 106 |
/// The number of items stored in the heap. |
107 | 107 |
/// |
108 | 108 |
/// \brief Returns the number of items stored in the heap. |
109 | 109 |
int size() const { return data.size(); } |
110 |
|
|
110 |
|
|
111 | 111 |
/// \brief Checks if the heap stores no items. |
112 | 112 |
/// |
113 | 113 |
/// Returns \c true if and only if the heap stores no items. |
114 | 114 |
bool empty() const { return data.empty(); } |
115 | 115 |
|
116 | 116 |
/// \brief Make empty this heap. |
117 |
/// |
|
117 |
/// |
|
118 | 118 |
/// Make empty this heap. It does not change the cross reference map. |
119 | 119 |
/// If you want to reuse what is not surely empty you should first clear |
120 | 120 |
/// the heap and after that you should set the cross reference map for |
121 | 121 |
/// each item to \c PRE_HEAP. |
122 |
void clear() { |
|
123 |
data.clear(); |
|
122 |
void clear() { |
|
123 |
data.clear(); |
|
124 | 124 |
} |
125 | 125 |
|
126 | 126 |
private: |
127 | 127 |
static int parent(int i) { return (i-1)/2; } |
128 | 128 |
|
129 | 129 |
static int second_child(int i) { return 2*i+2; } |
... | ... |
@@ -131,36 +131,36 @@ |
131 | 131 |
return comp(p1.second, p2.second); |
132 | 132 |
} |
133 | 133 |
|
134 | 134 |
int bubble_up(int hole, Pair p) { |
135 | 135 |
int par = parent(hole); |
136 | 136 |
while( hole>0 && less(p,data[par]) ) { |
137 |
move(data[par],hole); |
|
138 |
hole = par; |
|
139 |
|
|
137 |
move(data[par],hole); |
|
138 |
hole = par; |
|
139 |
par = parent(hole); |
|
140 | 140 |
} |
141 | 141 |
move(p, hole); |
142 | 142 |
return hole; |
143 | 143 |
} |
144 | 144 |
|
145 | 145 |
int bubble_down(int hole, Pair p, int length) { |
146 | 146 |
int child = second_child(hole); |
147 | 147 |
while(child < length) { |
148 |
if( less(data[child-1], data[child]) ) { |
|
149 |
--child; |
|
150 |
} |
|
151 |
if( !less(data[child], p) ) |
|
152 |
goto ok; |
|
153 |
move(data[child], hole); |
|
154 |
hole = child; |
|
155 |
child = second_child(hole); |
|
148 |
if( less(data[child-1], data[child]) ) { |
|
149 |
--child; |
|
150 |
} |
|
151 |
if( !less(data[child], p) ) |
|
152 |
goto ok; |
|
153 |
move(data[child], hole); |
|
154 |
hole = child; |
|
155 |
child = second_child(hole); |
|
156 | 156 |
} |
157 | 157 |
child--; |
158 | 158 |
if( child<length && less(data[child], p) ) { |
159 |
move(data[child], hole); |
|
160 |
hole=child; |
|
159 |
move(data[child], hole); |
|
160 |
hole=child; |
|
161 | 161 |
} |
162 | 162 |
ok: |
163 | 163 |
move(p, hole); |
164 | 164 |
return hole; |
165 | 165 |
} |
166 | 166 |
|
... | ... |
@@ -178,23 +178,23 @@ |
178 | 178 |
int n = data.size(); |
179 | 179 |
data.resize(n+1); |
180 | 180 |
bubble_up(n, p); |
181 | 181 |
} |
182 | 182 |
|
183 | 183 |
/// \brief Insert an item into the heap with the given heap. |
184 |
/// |
|
185 |
/// Adds \c i to the heap with priority \c p. |
|
184 |
/// |
|
185 |
/// Adds \c i to the heap with priority \c p. |
|
186 | 186 |
/// \param i The item to insert. |
187 | 187 |
/// \param p The priority of the item. |
188 | 188 |
void push(const Item &i, const Prio &p) { push(Pair(i,p)); } |
189 | 189 |
|
190 | 190 |
/// \brief Returns the item with minimum priority relative to \c Compare. |
191 | 191 |
/// |
192 | 192 |
/// This method returns the item with minimum priority relative to \c |
193 |
/// Compare. |
|
194 |
/// \pre The heap must be nonempty. |
|
193 |
/// Compare. |
|
194 |
/// \pre The heap must be nonempty. |
|
195 | 195 |
Item top() const { |
196 | 196 |
return data[0].first; |
197 | 197 |
} |
198 | 198 |
|
199 | 199 |
/// \brief Returns the minimum priority relative to \c Compare. |
200 | 200 |
/// |
... | ... |
@@ -204,19 +204,19 @@ |
204 | 204 |
return data[0].second; |
205 | 205 |
} |
206 | 206 |
|
207 | 207 |
/// \brief Deletes the item with minimum priority relative to \c Compare. |
208 | 208 |
/// |
209 | 209 |
/// This method deletes the item with minimum priority relative to \c |
210 |
/// Compare from the heap. |
|
211 |
/// \pre The heap must be non-empty. |
|
210 |
/// Compare from the heap. |
|
211 |
/// \pre The heap must be non-empty. |
|
212 | 212 |
void pop() { |
213 | 213 |
int n = data.size()-1; |
214 | 214 |
iim.set(data[0].first, POST_HEAP); |
215 | 215 |
if (n > 0) { |
216 |
|
|
216 |
bubble_down(0, data[n], n); |
|
217 | 217 |
} |
218 | 218 |
data.pop_back(); |
219 | 219 |
} |
220 | 220 |
|
221 | 221 |
/// \brief Deletes \c i from the heap. |
222 | 222 |
/// |
... | ... |
@@ -225,47 +225,47 @@ |
225 | 225 |
/// \pre The item should be in the heap. |
226 | 226 |
void erase(const Item &i) { |
227 | 227 |
int h = iim[i]; |
228 | 228 |
int n = data.size()-1; |
229 | 229 |
iim.set(data[h].first, POST_HEAP); |
230 | 230 |
if( h < n ) { |
231 |
if ( bubble_up(h, data[n]) == h) { |
|
232 |
bubble_down(h, data[n], n); |
|
233 |
|
|
231 |
if ( bubble_up(h, data[n]) == h) { |
|
232 |
bubble_down(h, data[n], n); |
|
233 |
} |
|
234 | 234 |
} |
235 | 235 |
data.pop_back(); |
236 | 236 |
} |
237 | 237 |
|
238 |
|
|
238 |
|
|
239 | 239 |
/// \brief Returns the priority of \c i. |
240 | 240 |
/// |
241 |
/// This function returns the priority of item \c i. |
|
241 |
/// This function returns the priority of item \c i. |
|
242 | 242 |
/// \pre \c i must be in the heap. |
243 | 243 |
/// \param i The item. |
244 | 244 |
Prio operator[](const Item &i) const { |
245 | 245 |
int idx = iim[i]; |
246 | 246 |
return data[idx].second; |
247 | 247 |
} |
248 | 248 |
|
249 |
/// \brief \c i gets to the heap with priority \c p independently |
|
249 |
/// \brief \c i gets to the heap with priority \c p independently |
|
250 | 250 |
/// if \c i was already there. |
251 | 251 |
/// |
252 | 252 |
/// This method calls \ref push(\c i, \c p) if \c i is not stored |
253 | 253 |
/// in the heap and sets the priority of \c i to \c p otherwise. |
254 | 254 |
/// \param i The item. |
255 | 255 |
/// \param p The priority. |
256 | 256 |
void set(const Item &i, const Prio &p) { |
257 | 257 |
int idx = iim[i]; |
258 | 258 |
if( idx < 0 ) { |
259 |
|
|
259 |
push(i,p); |
|
260 | 260 |
} |
261 | 261 |
else if( comp(p, data[idx].second) ) { |
262 |
|
|
262 |
bubble_up(idx, Pair(i,p)); |
|
263 | 263 |
} |
264 | 264 |
else { |
265 |
|
|
265 |
bubble_down(idx, Pair(i,p), data.size()); |
|
266 | 266 |
} |
267 | 267 |
} |
268 | 268 |
|
269 | 269 |
/// \brief Decreases the priority of \c i to \c p. |
270 | 270 |
/// |
271 | 271 |
/// This method decreases the priority of item \c i to \c p. |
... | ... |
@@ -274,47 +274,47 @@ |
274 | 274 |
/// \param i The item. |
275 | 275 |
/// \param p The priority. |
276 | 276 |
void decrease(const Item &i, const Prio &p) { |
277 | 277 |
int idx = iim[i]; |
278 | 278 |
bubble_up(idx, Pair(i,p)); |
279 | 279 |
} |
280 |
|
|
280 |
|
|
281 | 281 |
/// \brief Increases the priority of \c i to \c p. |
282 | 282 |
/// |
283 |
/// This method sets the priority of item \c i to \c p. |
|
283 |
/// This method sets the priority of item \c i to \c p. |
|
284 | 284 |
/// \pre \c i must be stored in the heap with priority at most \c |
285 | 285 |
/// p relative to \c Compare. |
286 | 286 |
/// \param i The item. |
287 | 287 |
/// \param p The priority. |
288 | 288 |
void increase(const Item &i, const Prio &p) { |
289 | 289 |
int idx = iim[i]; |
290 | 290 |
bubble_down(idx, Pair(i,p), data.size()); |
291 | 291 |
} |
292 | 292 |
|
293 |
/// \brief Returns if \c item is in, has already been in, or has |
|
293 |
/// \brief Returns if \c item is in, has already been in, or has |
|
294 | 294 |
/// never been in the heap. |
295 | 295 |
/// |
296 | 296 |
/// This method returns PRE_HEAP if \c item has never been in the |
297 | 297 |
/// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP |
298 | 298 |
/// otherwise. In the latter case it is possible that \c item will |
299 | 299 |
/// get back to the heap again. |
300 | 300 |
/// \param i The item. |
301 | 301 |
State state(const Item &i) const { |
302 | 302 |
int s = iim[i]; |
303 | 303 |
if( s>=0 ) |
304 |
|
|
304 |
s=0; |
|
305 | 305 |
return State(s); |
306 | 306 |
} |
307 | 307 |
|
308 | 308 |
/// \brief Sets the state of the \c item in the heap. |
309 | 309 |
/// |
310 | 310 |
/// Sets the state of the \c item in the heap. It can be used to |
311 | 311 |
/// manually clear the heap when it is important to achive the |
312 | 312 |
/// better time complexity. |
313 | 313 |
/// \param i The item. |
314 |
/// \param st The state. It should not be \c IN_HEAP. |
|
314 |
/// \param st The state. It should not be \c IN_HEAP. |
|
315 | 315 |
void state(const Item& i, State st) { |
316 | 316 |
switch (st) { |
317 | 317 |
case POST_HEAP: |
318 | 318 |
case PRE_HEAP: |
319 | 319 |
if (state(i) == IN_HEAP) { |
320 | 320 |
erase(i); |
... | ... |
@@ -337,10 +337,10 @@ |
337 | 337 |
iim.set(i, iim[j]); |
338 | 338 |
iim.set(j, idx); |
339 | 339 |
data[idx].first = j; |
340 | 340 |
} |
341 | 341 |
|
342 | 342 |
}; // class BinHeap |
343 |
|
|
343 |
|
|
344 | 344 |
} // namespace lemon |
345 | 345 |
|
346 | 346 |
#endif // LEMON_BIN_HEAP_H |
1 |
/* -*- C++ -*- |
|
1 |
/* -*- mode: C++; indent-tabs-mode: nil; -*- |
|
2 | 2 |
* |
3 |
* This file is a part of LEMON, a generic C++ optimization library |
|
3 |
* This file is a part of LEMON, a generic C++ optimization library. |
|
4 | 4 |
* |
5 | 5 |
* Copyright (C) 2003-2008 |
6 | 6 |
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
7 | 7 |
* (Egervary Research Group on Combinatorial Optimization, EGRES). |
8 | 8 |
* |
9 | 9 |
* Permission to use, modify and distribute this software is granted |
... | ... |
@@ -29,13 +29,13 @@ |
29 | 29 |
///\brief Observer notifier for graph alteration observers. |
30 | 30 |
|
31 | 31 |
namespace lemon { |
32 | 32 |
|
33 | 33 |
/// \ingroup graphbits |
34 | 34 |
/// |
35 |
/// \brief Notifier class to notify observes about alterations in |
|
35 |
/// \brief Notifier class to notify observes about alterations in |
|
36 | 36 |
/// a container. |
37 | 37 |
/// |
38 | 38 |
/// The simple graph's can be refered as two containers, one node container |
39 | 39 |
/// and one edge container. But they are not standard containers they |
40 | 40 |
/// does not store values directly they are just key continars for more |
41 | 41 |
/// value containers which are the node and edge maps. |
... | ... |
@@ -46,49 +46,49 @@ |
46 | 46 |
/// edges. If we want to check on every indicing if the map contains |
47 | 47 |
/// the current indicing key that cause a drawback in the performance |
48 | 48 |
/// in the library. We use another solution we notify all maps about |
49 | 49 |
/// an alteration in the graph, which cause only drawback on the |
50 | 50 |
/// alteration of the graph. |
51 | 51 |
/// |
52 |
/// This class provides an interface to the container. The \e first() and \e |
|
52 |
/// This class provides an interface to the container. The \e first() and \e |
|
53 | 53 |
/// next() member functions make possible to iterate on the keys of the |
54 | 54 |
/// container. The \e id() function returns an integer id for each key. |
55 | 55 |
/// The \e maxId() function gives back an upper bound of the ids. |
56 | 56 |
/// |
57 | 57 |
/// For the proper functonality of this class, we should notify it |
58 | 58 |
/// about each alteration in the container. The alterations have four type |
59 | 59 |
/// as \e add(), \e erase(), \e build() and \e clear(). The \e add() and |
60 | 60 |
/// \e erase() signals that only one or few items added or erased to or |
61 | 61 |
/// from the graph. If all items are erased from the graph or from an empty |
62 | 62 |
/// graph a new graph is builded then it can be signaled with the |
63 |
/// clear() and build() members. Important rule that if we erase items |
|
63 |
/// clear() and build() members. Important rule that if we erase items |
|
64 | 64 |
/// from graph we should first signal the alteration and after that erase |
65 | 65 |
/// them from the container, on the other way on item addition we should |
66 | 66 |
/// first extend the container and just after that signal the alteration. |
67 | 67 |
/// |
68 | 68 |
/// The alteration can be observed with a class inherited from the |
69 | 69 |
/// \e ObserverBase nested class. The signals can be handled with |
70 | 70 |
/// overriding the virtual functions defined in the base class. The |
71 |
/// observer base can be attached to the notifier with the |
|
71 |
/// observer base can be attached to the notifier with the |
|
72 | 72 |
/// \e attach() member and can be detached with detach() function. The |
73 | 73 |
/// alteration handlers should not call any function which signals |
74 | 74 |
/// an other alteration in the same notifier and should not |
75 | 75 |
/// detach any observer from the notifier. |
76 | 76 |
/// |
77 | 77 |
/// Alteration observers try to be exception safe. If an \e add() or |
78 | 78 |
/// a \e clear() function throws an exception then the remaining |
79 | 79 |
/// observeres will not be notified and the fulfilled additions will |
80 | 80 |
/// be rolled back by calling the \e erase() or \e clear() |
81 | 81 |
/// functions. Thence the \e erase() and \e clear() should not throw |
82 |
/// exception. Actullay, it can be throw only |
|
82 |
/// exception. Actullay, it can be throw only |
|
83 | 83 |
/// \ref AlterationObserver::ImmediateDetach ImmediateDetach |
84 | 84 |
/// exception which detach the observer from the notifier. |
85 | 85 |
/// |
86 | 86 |
/// There are some place when the alteration observing is not completly |
87 | 87 |
/// reliable. If we want to carry out the node degree in the graph |
88 |
/// as in the \ref InDegMap and we use the reverseEdge that cause |
|
88 |
/// as in the \ref InDegMap and we use the reverseEdge that cause |
|
89 | 89 |
/// unreliable functionality. Because the alteration observing signals |
90 | 90 |
/// only erasing and adding but not the reversing it will stores bad |
91 | 91 |
/// degrees. The sub graph adaptors cannot signal the alterations because |
92 | 92 |
/// just a setting in the filter map can modify the graph and this cannot |
93 | 93 |
/// be watched in any way. |
94 | 94 |
/// |
... | ... |
@@ -101,13 +101,13 @@ |
101 | 101 |
|
102 | 102 |
typedef True Notifier; |
103 | 103 |
|
104 | 104 |
typedef _Container Container; |
105 | 105 |
typedef _Item Item; |
106 | 106 |
|
107 |
/// \brief Exception which can be called from \e clear() and |
|
107 |
/// \brief Exception which can be called from \e clear() and |
|
108 | 108 |
/// \e erase(). |
109 | 109 |
/// |
110 | 110 |
/// From the \e clear() and \e erase() function only this |
111 | 111 |
/// exception is allowed to throw. The exception immediatly |
112 | 112 |
/// detaches the current observer from the notifier. Because the |
113 | 113 |
/// \e clear() and \e erase() should not throw other exceptions |
... | ... |
@@ -124,111 +124,111 @@ |
124 | 124 |
/// to override. The add() and erase() functions are |
125 | 125 |
/// to notify the oberver when one item is added or |
126 | 126 |
/// erased. |
127 | 127 |
/// |
128 | 128 |
/// The build() and clear() members are to notify the observer |
129 | 129 |
/// about the container is built from an empty container or |
130 |
/// is cleared to an empty container. |
|
130 |
/// is cleared to an empty container. |
|
131 | 131 |
|
132 | 132 |
class ObserverBase { |
133 | 133 |
protected: |
134 | 134 |
typedef AlterationNotifier Notifier; |
135 | 135 |
|
136 | 136 |
friend class AlterationNotifier; |
137 | 137 |
|
138 | 138 |
/// \brief Default constructor. |
139 | 139 |
/// |
140 | 140 |
/// Default constructor for ObserverBase. |
141 |
/// |
|
141 |
/// |
|
142 | 142 |
ObserverBase() : _notifier(0) {} |
143 | 143 |
|
144 | 144 |
/// \brief Constructor which attach the observer into notifier. |
145 | 145 |
/// |
146 | 146 |
/// Constructor which attach the observer into notifier. |
147 | 147 |
ObserverBase(AlterationNotifier& nf) { |
148 | 148 |
attach(nf); |
149 | 149 |
} |
150 | 150 |
|
151 | 151 |
/// \brief Constructor which attach the obserever to the same notifier. |
152 | 152 |
/// |
153 | 153 |
/// Constructor which attach the obserever to the same notifier as |
154 |
/// the other observer is attached to. |
|
154 |
/// the other observer is attached to. |
|
155 | 155 |
ObserverBase(const ObserverBase& copy) { |
156 |
|
|
156 |
if (copy.attached()) { |
|
157 | 157 |
attach(*copy.notifier()); |
158 |
|
|
158 |
} |
|
159 | 159 |
} |
160 |
|
|
160 |
|
|
161 | 161 |
/// \brief Destructor |
162 | 162 |
virtual ~ObserverBase() { |
163 | 163 |
if (attached()) { |
164 | 164 |
detach(); |
165 | 165 |
} |
166 | 166 |
} |
167 | 167 |
|
168 | 168 |
/// \brief Attaches the observer into an AlterationNotifier. |
169 | 169 |
/// |
170 | 170 |
/// This member attaches the observer into an AlterationNotifier. |
171 | 171 |
/// |
172 | 172 |
void attach(AlterationNotifier& nf) { |
173 |
|
|
173 |
nf.attach(*this); |
|
174 | 174 |
} |
175 |
|
|
175 |
|
|
176 | 176 |
/// \brief Detaches the observer into an AlterationNotifier. |
177 | 177 |
/// |
178 | 178 |
/// This member detaches the observer from an AlterationNotifier. |
179 | 179 |
/// |
180 | 180 |
void detach() { |
181 | 181 |
_notifier->detach(*this); |
182 | 182 |
} |
183 |
|
|
184 |
/// \brief Gives back a pointer to the notifier which the map |
|
183 |
|
|
184 |
/// \brief Gives back a pointer to the notifier which the map |
|
185 | 185 |
/// attached into. |
186 | 186 |
/// |
187 | 187 |
/// This function gives back a pointer to the notifier which the map |
188 | 188 |
/// attached into. |
189 | 189 |
/// |
190 | 190 |
Notifier* notifier() const { return const_cast<Notifier*>(_notifier); } |
191 |
|
|
191 |
|
|
192 | 192 |
/// Gives back true when the observer is attached into a notifier. |
193 | 193 |
bool attached() const { return _notifier != 0; } |
194 | 194 |
|
195 | 195 |
private: |
196 | 196 |
|
197 | 197 |
ObserverBase& operator=(const ObserverBase& copy); |
198 | 198 |
|
199 | 199 |
protected: |
200 |
|
|
200 |
|
|
201 | 201 |
Notifier* _notifier; |
202 | 202 |
typename std::list<ObserverBase*>::iterator _index; |
203 | 203 |
|
204 | 204 |
/// \brief The member function to notificate the observer about an |
205 | 205 |
/// item is added to the container. |
206 | 206 |
/// |
207 | 207 |
/// The add() member function notificates the observer about an item |
208 | 208 |
/// is added to the container. It have to be overrided in the |
209 | 209 |
/// subclasses. |
210 | 210 |
virtual void add(const Item&) = 0; |
211 | 211 |
|
212 |
/// \brief The member function to notificate the observer about |
|
212 |
/// \brief The member function to notificate the observer about |
|
213 | 213 |
/// more item is added to the container. |
214 | 214 |
/// |
215 | 215 |
/// The add() member function notificates the observer about more item |
216 | 216 |
/// is added to the container. It have to be overrided in the |
217 | 217 |
/// subclasses. |
218 | 218 |
virtual void add(const std::vector<Item>& items) = 0; |
219 | 219 |
|
220 | 220 |
/// \brief The member function to notificate the observer about an |
221 | 221 |
/// item is erased from the container. |
222 | 222 |
/// |
223 | 223 |
/// The erase() member function notificates the observer about an |
224 | 224 |
/// item is erased from the container. It have to be overrided in |
225 |
/// the subclasses. |
|
225 |
/// the subclasses. |
|
226 | 226 |
virtual void erase(const Item&) = 0; |
227 | 227 |
|
228 |
/// \brief The member function to notificate the observer about |
|
228 |
/// \brief The member function to notificate the observer about |
|
229 | 229 |
/// more item is erased from the container. |
230 | 230 |
/// |
231 | 231 |
/// The erase() member function notificates the observer about more item |
232 | 232 |
/// is erased from the container. It have to be overrided in the |
233 | 233 |
/// subclasses. |
234 | 234 |
virtual void erase(const std::vector<Item>& items) = 0; |
... | ... |
@@ -244,56 +244,56 @@ |
244 | 244 |
|
245 | 245 |
/// \brief The member function to notificate the observer about all |
246 | 246 |
/// items are erased from the container. |
247 | 247 |
/// |
248 | 248 |
/// The clear() member function notificates the observer about all |
249 | 249 |
/// items are erased from the container. It have to be overrided in |
250 |
/// the subclasses. |
|
250 |
/// the subclasses. |
|
251 | 251 |
virtual void clear() = 0; |
252 | 252 |
|
253 | 253 |
}; |
254 |
|
|
254 |
|
|
255 | 255 |
protected: |
256 | 256 |
|
257 | 257 |
const Container* container; |
258 | 258 |
|
259 |
typedef std::list<ObserverBase*> Observers; |
|
259 |
typedef std::list<ObserverBase*> Observers; |
|
260 | 260 |
Observers _observers; |
261 | 261 |
|
262 |
|
|
262 |
|
|
263 | 263 |
public: |
264 | 264 |
|
265 | 265 |
/// \brief Default constructor. |
266 | 266 |
/// |
267 |
/// The default constructor of the AlterationNotifier. |
|
267 |
/// The default constructor of the AlterationNotifier. |
|
268 | 268 |
/// It creates an empty notifier. |
269 |
AlterationNotifier() |
|
269 |
AlterationNotifier() |
|
270 | 270 |
: container(0) {} |
271 | 271 |
|
272 | 272 |
/// \brief Constructor. |
273 | 273 |
/// |
274 | 274 |
/// Constructor with the observed container parameter. |
275 |
AlterationNotifier(const Container& _container) |
|
275 |
AlterationNotifier(const Container& _container) |
|
276 | 276 |
: container(&_container) {} |
277 | 277 |
|
278 |
/// \brief Copy Constructor of the AlterationNotifier. |
|
278 |
/// \brief Copy Constructor of the AlterationNotifier. |
|
279 | 279 |
/// |
280 |
/// Copy constructor of the AlterationNotifier. |
|
280 |
/// Copy constructor of the AlterationNotifier. |
|
281 | 281 |
/// It creates only an empty notifier because the copiable |
282 | 282 |
/// notifier's observers have to be registered still into that notifier. |
283 |
AlterationNotifier(const AlterationNotifier& _notifier) |
|
283 |
AlterationNotifier(const AlterationNotifier& _notifier) |
|
284 | 284 |
: container(_notifier.container) {} |
285 | 285 |
|
286 | 286 |
/// \brief Destructor. |
287 |
/// |
|
287 |
/// |
|
288 | 288 |
/// Destructor of the AlterationNotifier. |
289 | 289 |
/// |
290 | 290 |
~AlterationNotifier() { |
291 | 291 |
typename Observers::iterator it; |
292 | 292 |
for (it = _observers.begin(); it != _observers.end(); ++it) { |
293 |
|
|
293 |
(*it)->_notifier = 0; |
|
294 | 294 |
} |
295 | 295 |
} |
296 | 296 |
|
297 | 297 |
/// \brief Sets the container. |
298 | 298 |
/// |
299 | 299 |
/// Sets the container. |
... | ... |
@@ -335,34 +335,34 @@ |
335 | 335 |
/// \brief Returns the maximum id of the container. |
336 | 336 |
/// |
337 | 337 |
/// Returns the maximum id of the container. |
338 | 338 |
int maxId() const { |
339 | 339 |
return container->maxId(Item()); |
340 | 340 |
} |
341 |
|
|
341 |
|
|
342 | 342 |
protected: |
343 | 343 |
|
344 | 344 |
void attach(ObserverBase& observer) { |
345 | 345 |
observer._index = _observers.insert(_observers.begin(), &observer); |
346 | 346 |
observer._notifier = this; |
347 |
} |
|
347 |
} |
|
348 | 348 |
|
349 | 349 |
void detach(ObserverBase& observer) { |
350 | 350 |
_observers.erase(observer._index); |
351 | 351 |
observer._index = _observers.end(); |
352 | 352 |
observer._notifier = 0; |
353 | 353 |
} |
354 | 354 |
|
355 | 355 |
public: |
356 |
|
|
357 |
/// \brief Notifies all the registed observers about an item added to |
|
356 |
|
|
357 |
/// \brief Notifies all the registed observers about an item added to |
|
358 | 358 |
/// the container. |
359 | 359 |
/// |
360 |
/// It notifies all the registed observers about an item added to |
|
360 |
/// It notifies all the registed observers about an item added to |
|
361 | 361 |
/// the container. |
362 |
/// |
|
362 |
/// |
|
363 | 363 |
void add(const Item& item) { |
364 | 364 |
typename Observers::reverse_iterator it; |
365 | 365 |
try { |
366 | 366 |
for (it = _observers.rbegin(); it != _observers.rend(); ++it) { |
367 | 367 |
(*it)->add(item); |
368 | 368 |
} |
... | ... |
@@ -370,20 +370,20 @@ |
370 | 370 |
typename Observers::iterator jt; |
371 | 371 |
for (jt = it.base(); jt != _observers.end(); ++jt) { |
372 | 372 |
(*jt)->erase(item); |
373 | 373 |
} |
374 | 374 |
throw; |
375 | 375 |
} |
376 |
} |
|
376 |
} |
|
377 | 377 |
|
378 |
/// \brief Notifies all the registed observers about more item added to |
|
378 |
/// \brief Notifies all the registed observers about more item added to |
|
379 | 379 |
/// the container. |
380 | 380 |
/// |
381 |
/// It notifies all the registed observers about more item added to |
|
381 |
/// It notifies all the registed observers about more item added to |
|
382 | 382 |
/// the container. |
383 |
/// |
|
383 |
/// |
|
384 | 384 |
void add(const std::vector<Item>& items) { |
385 | 385 |
typename Observers::reverse_iterator it; |
386 | 386 |
try { |
387 | 387 |
for (it = _observers.rbegin(); it != _observers.rend(); ++it) { |
388 | 388 |
(*it)->add(items); |
389 | 389 |
} |
... | ... |
@@ -391,20 +391,20 @@ |
391 | 391 |
typename Observers::iterator jt; |
392 | 392 |
for (jt = it.base(); jt != _observers.end(); ++jt) { |
393 | 393 |
(*jt)->erase(items); |
394 | 394 |
} |
395 | 395 |
throw; |
396 | 396 |
} |
397 |
} |
|
397 |
} |
|
398 | 398 |
|
399 |
/// \brief Notifies all the registed observers about an item erased from |
|
399 |
/// \brief Notifies all the registed observers about an item erased from |
|
400 | 400 |
/// the container. |
401 |
/// |
|
402 |
/// It notifies all the registed observers about an item erased from |
|
401 |
/// |
|
402 |
/// It notifies all the registed observers about an item erased from |
|
403 | 403 |
/// the container. |
404 |
/// |
|
404 |
/// |
|
405 | 405 |
void erase(const Item& item) throw() { |
406 | 406 |
typename Observers::iterator it = _observers.begin(); |
407 | 407 |
while (it != _observers.end()) { |
408 | 408 |
try { |
409 | 409 |
(*it)->erase(item); |
410 | 410 |
++it; |
... | ... |
@@ -413,18 +413,18 @@ |
413 | 413 |
(*it)->_index = _observers.end(); |
414 | 414 |
(*it)->_notifier = 0; |
415 | 415 |
} |
416 | 416 |
} |
417 | 417 |
} |
418 | 418 |
|
419 |
/// \brief Notifies all the registed observers about more item erased |
|
419 |
/// \brief Notifies all the registed observers about more item erased |
|
420 | 420 |
/// from the container. |
421 |
/// |
|
422 |
/// It notifies all the registed observers about more item erased from |
|
421 |
/// |
|
422 |
/// It notifies all the registed observers about more item erased from |
|
423 | 423 |
/// the container. |
424 |
/// |
|
424 |
/// |
|
425 | 425 |
void erase(const std::vector<Item>& items) { |
426 | 426 |
typename Observers::iterator it = _observers.begin(); |
427 | 427 |
while (it != _observers.end()) { |
428 | 428 |
try { |
429 | 429 |
(*it)->erase(items); |
430 | 430 |
++it; |
... | ... |
@@ -433,15 +433,15 @@ |
433 | 433 |
(*it)->_index = _observers.end(); |
434 | 434 |
(*it)->_notifier = 0; |
435 | 435 |
} |
436 | 436 |
} |
437 | 437 |
} |
438 | 438 |
|
439 |
/// \brief Notifies all the registed observers about the container is |
|
439 |
/// \brief Notifies all the registed observers about the container is |
|
440 | 440 |
/// built. |
441 |
/// |
|
441 |
/// |
|
442 | 442 |
/// Notifies all the registed observers about the container is built |
443 | 443 |
/// from an empty container. |
444 | 444 |
void build() { |
445 | 445 |
typename Observers::reverse_iterator it; |
446 | 446 |
try { |
447 | 447 |
for (it = _observers.rbegin(); it != _observers.rend(); ++it) { |
... | ... |
@@ -453,13 +453,13 @@ |
453 | 453 |
(*jt)->clear(); |
454 | 454 |
} |
455 | 455 |
throw; |
456 | 456 |
} |
457 | 457 |
} |
458 | 458 |
|
459 |
/// \brief Notifies all the registed observers about all items are |
|
459 |
/// \brief Notifies all the registed observers about all items are |
|
460 | 460 |
/// erased. |
461 | 461 |
/// |
462 | 462 |
/// Notifies all the registed observers about all items are erased |
463 | 463 |
/// from the container. |
464 | 464 |
void clear() { |
465 | 465 |
typename Observers::iterator it = _observers.begin(); |
1 |
/* -*- C++ -*- |
|
1 |
/* -*- mode: C++; indent-tabs-mode: nil; -*- |
|
2 | 2 |
* |
3 |
* This file is a part of LEMON, a generic C++ optimization library |
|
3 |
* This file is a part of LEMON, a generic C++ optimization library. |
|
4 | 4 |
* |
5 | 5 |
* Copyright (C) 2003-2008 |
6 | 6 |
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
7 | 7 |
* (Egervary Research Group on Combinatorial Optimization, EGRES). |
8 | 8 |
* |
9 | 9 |
* Permission to use, modify and distribute this software is granted |
... | ... |
@@ -35,22 +35,22 @@ |
35 | 35 |
/// \ingroup graphbits |
36 | 36 |
/// |
37 | 37 |
/// \brief Graph map based on the array storage. |
38 | 38 |
/// |
39 | 39 |
/// The ArrayMap template class is graph map structure what |
40 | 40 |
/// automatically updates the map when a key is added to or erased from |
41 |
/// the map. This map uses the allocators to implement |
|
41 |
/// the map. This map uses the allocators to implement |
|
42 | 42 |
/// the container functionality. |
43 | 43 |
/// |
44 | 44 |
/// The template parameters are the Graph the current Item type and |
45 | 45 |
/// the Value type of the map. |
46 | 46 |
template <typename _Graph, typename _Item, typename _Value> |
47 |
class ArrayMap |
|
47 |
class ArrayMap |
|
48 | 48 |
: public ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase { |
49 | 49 |
public: |
50 |
/// The graph type of the maps. |
|
50 |
/// The graph type of the maps. |
|
51 | 51 |
typedef _Graph Graph; |
52 | 52 |
/// The item type of the map. |
53 | 53 |
typedef _Item Item; |
54 | 54 |
/// The reference map tag. |
55 | 55 |
typedef True ReferenceMapTag; |
56 | 56 |
|
... | ... |
@@ -66,13 +66,13 @@ |
66 | 66 |
|
67 | 67 |
/// The notifier type. |
68 | 68 |
typedef typename ItemSetTraits<_Graph, _Item>::ItemNotifier Notifier; |
69 | 69 |
|
70 | 70 |
/// The MapBase of the Map which imlements the core regisitry function. |
71 | 71 |
typedef typename Notifier::ObserverBase Parent; |
72 |
|
|
72 |
|
|
73 | 73 |
private: |
74 | 74 |
typedef std::allocator<Value> Allocator; |
75 | 75 |
|
76 | 76 |
public: |
77 | 77 |
|
78 | 78 |
/// \brief Graph initialized map constructor. |
... | ... |
@@ -81,266 +81,266 @@ |
81 | 81 |
explicit ArrayMap(const Graph& graph) { |
82 | 82 |
Parent::attach(graph.notifier(Item())); |
83 | 83 |
allocate_memory(); |
84 | 84 |
Notifier* nf = Parent::notifier(); |
85 | 85 |
Item it; |
86 | 86 |
for (nf->first(it); it != INVALID; nf->next(it)) { |
87 |
int id = nf->id(it);; |
|
88 |
allocator.construct(&(values[id]), Value()); |
|
89 |
|
|
87 |
int id = nf->id(it);; |
|
88 |
allocator.construct(&(values[id]), Value()); |
|
89 |
} |
|
90 | 90 |
} |
91 | 91 |
|
92 |
/// \brief Constructor to use default value to initialize the map. |
|
92 |
/// \brief Constructor to use default value to initialize the map. |
|
93 | 93 |
/// |
94 |
/// It constructs a map and initialize all of the the map. |
|
94 |
/// It constructs a map and initialize all of the the map. |
|
95 | 95 |
ArrayMap(const Graph& graph, const Value& value) { |
96 | 96 |
Parent::attach(graph.notifier(Item())); |
97 | 97 |
allocate_memory(); |
98 | 98 |
Notifier* nf = Parent::notifier(); |
99 | 99 |
Item it; |
100 | 100 |
for (nf->first(it); it != INVALID; nf->next(it)) { |
101 |
int id = nf->id(it);; |
|
102 |
allocator.construct(&(values[id]), value); |
|
103 |
|
|
101 |
int id = nf->id(it);; |
|
102 |
allocator.construct(&(values[id]), value); |
|
103 |
} |
|
104 | 104 |
} |
105 | 105 |
|
106 | 106 |
/// \brief Constructor to copy a map of the same map type. |
107 | 107 |
/// |
108 |
/// Constructor to copy a map of the same map type. |
|
108 |
/// Constructor to copy a map of the same map type. |
|
109 | 109 |
ArrayMap(const ArrayMap& copy) : Parent() { |
110 | 110 |
if (copy.attached()) { |
111 |
|
|
111 |
attach(*copy.notifier()); |
|
112 | 112 |
} |
113 | 113 |
capacity = copy.capacity; |
114 | 114 |
if (capacity == 0) return; |
115 | 115 |
values = allocator.allocate(capacity); |
116 | 116 |
Notifier* nf = Parent::notifier(); |
117 | 117 |
Item it; |
118 | 118 |
for (nf->first(it); it != INVALID; nf->next(it)) { |
119 |
int id = nf->id(it);; |
|
120 |
allocator.construct(&(values[id]), copy.values[id]); |
|
119 |
int id = nf->id(it);; |
|
120 |
allocator.construct(&(values[id]), copy.values[id]); |
|
121 | 121 |
} |
122 | 122 |
} |
123 | 123 |
|
124 | 124 |
/// \brief Assign operator. |
125 | 125 |
/// |
126 | 126 |
/// This operator assigns for each item in the map the |
127 |
/// value mapped to the same item in the copied map. |
|
127 |
/// value mapped to the same item in the copied map. |
|
128 | 128 |
/// The parameter map should be indiced with the same |
129 | 129 |
/// itemset because this assign operator does not change |
130 |
/// the container of the map. |
|
130 |
/// the container of the map. |
|
131 | 131 |
ArrayMap& operator=(const ArrayMap& cmap) { |
132 | 132 |
return operator=<ArrayMap>(cmap); |
133 | 133 |
} |
134 | 134 |
|
135 | 135 |
|
136 | 136 |
/// \brief Template assign operator. |
137 | 137 |
/// |
138 | 138 |
/// The given parameter should be conform to the ReadMap |
139 | 139 |
/// concecpt and could be indiced by the current item set of |
140 | 140 |
/// the NodeMap. In this case the value for each item |
141 |
/// is assigned by the value of the given ReadMap. |
|
141 |
/// is assigned by the value of the given ReadMap. |
|
142 | 142 |
template <typename CMap> |
143 | 143 |
ArrayMap& operator=(const CMap& cmap) { |
144 | 144 |
checkConcept<concepts::ReadMap<Key, _Value>, CMap>(); |
145 | 145 |
const typename Parent::Notifier* nf = Parent::notifier(); |
146 | 146 |
Item it; |
147 | 147 |
for (nf->first(it); it != INVALID; nf->next(it)) { |
148 | 148 |
set(it, cmap[it]); |
149 | 149 |
} |
150 | 150 |
return *this; |
151 | 151 |
} |
152 | 152 |
|
153 | 153 |
/// \brief The destructor of the map. |
154 |
/// |
|
154 |
/// |
|
155 | 155 |
/// The destructor of the map. |
156 |
virtual ~ArrayMap() { |
|
156 |
virtual ~ArrayMap() { |
|
157 | 157 |
if (attached()) { |
158 |
clear(); |
|
159 |
detach(); |
|
158 |
clear(); |
|
159 |
detach(); |
|
160 | 160 |
} |
161 | 161 |
} |
162 |
|
|
162 |
|
|
163 | 163 |
protected: |
164 | 164 |
|
165 | 165 |
using Parent::attach; |
166 | 166 |
using Parent::detach; |
167 | 167 |
using Parent::attached; |
168 | 168 |
|
169 | 169 |
public: |
170 | 170 |
|
171 |
/// \brief The subscript operator. |
|
171 |
/// \brief The subscript operator. |
|
172 | 172 |
/// |
173 | 173 |
/// The subscript operator. The map can be subscripted by the |
174 |
/// actual keys of the graph. |
|
174 |
/// actual keys of the graph. |
|
175 | 175 |
Value& operator[](const Key& key) { |
176 | 176 |
int id = Parent::notifier()->id(key); |
177 | 177 |
return values[id]; |
178 |
} |
|
179 |
|
|
178 |
} |
|
179 |
|
|
180 | 180 |
/// \brief The const subscript operator. |
181 | 181 |
/// |
182 | 182 |
/// The const subscript operator. The map can be subscripted by the |
183 |
/// actual keys of the graph. |
|
183 |
/// actual keys of the graph. |
|
184 | 184 |
const Value& operator[](const Key& key) const { |
185 | 185 |
int id = Parent::notifier()->id(key); |
186 | 186 |
return values[id]; |
187 | 187 |
} |
188 | 188 |
|
189 | 189 |
/// \brief Setter function of the map. |
190 |
/// |
|
190 |
/// |
|
191 | 191 |
/// Setter function of the map. Equivalent with map[key] = val. |
192 | 192 |
/// This is a compatibility feature with the not dereferable maps. |
193 | 193 |
void set(const Key& key, const Value& val) { |
194 | 194 |
(*this)[key] = val; |
195 | 195 |
} |
196 | 196 |
|
197 | 197 |
protected: |
198 | 198 |
|
199 | 199 |
/// \brief Adds a new key to the map. |
200 |
/// |
|
200 |
/// |
|
201 | 201 |
/// It adds a new key to the map. It called by the observer notifier |
202 |
/// and it overrides the add() member function of the observer base. |
|
202 |
/// and it overrides the add() member function of the observer base. |
|
203 | 203 |
virtual void add(const Key& key) { |
204 | 204 |
Notifier* nf = Parent::notifier(); |
205 | 205 |
int id = nf->id(key); |
206 | 206 |
if (id >= capacity) { |
207 |
int new_capacity = (capacity == 0 ? 1 : capacity); |
|
208 |
while (new_capacity <= id) { |
|
209 |
new_capacity <<= 1; |
|
210 |
} |
|
211 |
Value* new_values = allocator.allocate(new_capacity); |
|
212 |
Item it; |
|
213 |
for (nf->first(it); it != INVALID; nf->next(it)) { |
|
214 |
int jd = nf->id(it);; |
|
215 |
if (id != jd) { |
|
216 |
allocator.construct(&(new_values[jd]), values[jd]); |
|
217 |
allocator.destroy(&(values[jd])); |
|
218 |
} |
|
219 |
} |
|
220 |
if (capacity != 0) allocator.deallocate(values, capacity); |
|
221 |
values = new_values; |
|
222 |
capacity = new_capacity; |
|
207 |
int new_capacity = (capacity == 0 ? 1 : capacity); |
|
208 |
while (new_capacity <= id) { |
|
209 |
new_capacity <<= 1; |
|
210 |
} |
|
211 |
Value* new_values = allocator.allocate(new_capacity); |
|
212 |
Item it; |
|
213 |
for (nf->first(it); it != INVALID; nf->next(it)) { |
|
214 |
int jd = nf->id(it);; |
|
215 |
if (id != jd) { |
|
216 |
allocator.construct(&(new_values[jd]), values[jd]); |
|
217 |
allocator.destroy(&(values[jd])); |
|
218 |
} |
|
219 |
} |
|
220 |
if (capacity != 0) allocator.deallocate(values, capacity); |
|
221 |
values = new_values; |
|
222 |
capacity = new_capacity; |
|
223 | 223 |
} |
224 | 224 |
allocator.construct(&(values[id]), Value()); |
225 | 225 |
} |
226 | 226 |
|
227 | 227 |
/// \brief Adds more new keys to the map. |
228 |
/// |
|
228 |
/// |
|
229 | 229 |
/// It adds more new keys to the map. It called by the observer notifier |
230 |
/// and it overrides the add() member function of the observer base. |
|
230 |
/// and it overrides the add() member function of the observer base. |
|
231 | 231 |
virtual void add(const std::vector<Key>& keys) { |
232 | 232 |
Notifier* nf = Parent::notifier(); |
233 | 233 |
int max_id = -1; |
234 | 234 |
for (int i = 0; i < int(keys.size()); ++i) { |
235 |
int id = nf->id(keys[i]); |
|
236 |
if (id > max_id) { |
|
237 |
max_id = id; |
|
238 |
} |
|
235 |
int id = nf->id(keys[i]); |
|
236 |
if (id > max_id) { |
|
237 |
max_id = id; |
|
238 |
} |
|
239 | 239 |
} |
240 | 240 |
if (max_id >= capacity) { |
241 |
int new_capacity = (capacity == 0 ? 1 : capacity); |
|
242 |
while (new_capacity <= max_id) { |
|
243 |
new_capacity <<= 1; |
|
244 |
} |
|
245 |
Value* new_values = allocator.allocate(new_capacity); |
|
246 |
Item it; |
|
247 |
for (nf->first(it); it != INVALID; nf->next(it)) { |
|
248 |
int id = nf->id(it); |
|
249 |
bool found = false; |
|
250 |
for (int i = 0; i < int(keys.size()); ++i) { |
|
251 |
int jd = nf->id(keys[i]); |
|
252 |
if (id == jd) { |
|
253 |
found = true; |
|
254 |
break; |
|
255 |
} |
|
256 |
} |
|
257 |
if (found) continue; |
|
258 |
allocator.construct(&(new_values[id]), values[id]); |
|
259 |
allocator.destroy(&(values[id])); |
|
260 |
} |
|
261 |
if (capacity != 0) allocator.deallocate(values, capacity); |
|
262 |
values = new_values; |
|
263 |
|
|
241 |
int new_capacity = (capacity == 0 ? 1 : capacity); |
|
242 |
while (new_capacity <= max_id) { |
|
243 |
new_capacity <<= 1; |
|
244 |
} |
|
245 |
Value* new_values = allocator.allocate(new_capacity); |
|
246 |
Item it; |
|
247 |
for (nf->first(it); it != INVALID; nf->next(it)) { |
|
248 |
int id = nf->id(it); |
|
249 |
bool found = false; |
|
250 |
for (int i = 0; i < int(keys.size()); ++i) { |
|
251 |
int jd = nf->id(keys[i]); |
|
252 |
if (id == jd) { |
|
253 |
found = true; |
|
254 |
break; |
|
255 |
} |
|
256 |
} |
|
257 |
if (found) continue; |
|
258 |
allocator.construct(&(new_values[id]), values[id]); |
|
259 |
allocator.destroy(&(values[id])); |
|
260 |
} |
|
261 |
if (capacity != 0) allocator.deallocate(values, capacity); |
|
262 |
values = new_values; |
|
263 |
capacity = new_capacity; |
|
264 | 264 |
} |
265 | 265 |
for (int i = 0; i < int(keys.size()); ++i) { |
266 |
int id = nf->id(keys[i]); |
|
267 |
allocator.construct(&(values[id]), Value()); |
|
266 |
int id = nf->id(keys[i]); |
|
267 |
allocator.construct(&(values[id]), Value()); |
|
268 | 268 |
} |
269 | 269 |
} |
270 |
|
|
270 |
|
|
271 | 271 |
/// \brief Erase a key from the map. |
272 | 272 |
/// |
273 | 273 |
/// Erase a key from the map. It called by the observer notifier |
274 |
/// and it overrides the erase() member function of the observer base. |
|
274 |
/// and it overrides the erase() member function of the observer base. |
|
275 | 275 |
virtual void erase(const Key& key) { |
276 | 276 |
int id = Parent::notifier()->id(key); |
277 | 277 |
allocator.destroy(&(values[id])); |
278 | 278 |
} |
279 | 279 |
|
280 | 280 |
/// \brief Erase more keys from the map. |
281 | 281 |
/// |
282 | 282 |
/// Erase more keys from the map. It called by the observer notifier |
283 |
/// and it overrides the erase() member function of the observer base. |
|
283 |
/// and it overrides the erase() member function of the observer base. |
|
284 | 284 |
virtual void erase(const std::vector<Key>& keys) { |
285 | 285 |
for (int i = 0; i < int(keys.size()); ++i) { |
286 |
int id = Parent::notifier()->id(keys[i]); |
|
287 |
allocator.destroy(&(values[id])); |
|
286 |
int id = Parent::notifier()->id(keys[i]); |
|
287 |
allocator.destroy(&(values[id])); |
|
288 | 288 |
} |
289 | 289 |
} |
290 | 290 |
|
291 | 291 |
/// \brief Buildes the map. |
292 |
/// |
|
292 |
/// |
|
293 | 293 |
/// It buildes the map. It called by the observer notifier |
294 |
/// and it overrides the build() member function of the observer base. |
|
294 |
/// and it overrides the build() member function of the observer base. |
|
295 | 295 |
virtual void build() { |
296 | 296 |
Notifier* nf = Parent::notifier(); |
297 | 297 |
allocate_memory(); |
298 | 298 |
Item it; |
299 | 299 |
for (nf->first(it); it != INVALID; nf->next(it)) { |
300 |
int id = nf->id(it);; |
|
301 |
allocator.construct(&(values[id]), Value()); |
|
302 |
|
|
300 |
int id = nf->id(it);; |
|
301 |
allocator.construct(&(values[id]), Value()); |
|
302 |
} |
|
303 | 303 |
} |
304 | 304 |
|
305 | 305 |
/// \brief Clear the map. |
306 | 306 |
/// |
307 | 307 |
/// It erase all items from the map. It called by the observer notifier |
308 |
/// and it overrides the clear() member function of the observer base. |
|
309 |
virtual void clear() { |
|
308 |
/// and it overrides the clear() member function of the observer base. |
|
309 |
virtual void clear() { |
|
310 | 310 |
Notifier* nf = Parent::notifier(); |
311 | 311 |
if (capacity != 0) { |
312 |
Item it; |
|
313 |
for (nf->first(it); it != INVALID; nf->next(it)) { |
|
314 |
int id = nf->id(it); |
|
315 |
allocator.destroy(&(values[id])); |
|
316 |
} |
|
317 |
allocator.deallocate(values, capacity); |
|
318 |
|
|
312 |
Item it; |
|
313 |
for (nf->first(it); it != INVALID; nf->next(it)) { |
|
314 |
int id = nf->id(it); |
|
315 |
allocator.destroy(&(values[id])); |
|
316 |
} |
|
317 |
allocator.deallocate(values, capacity); |
|
318 |
capacity = 0; |
|
319 | 319 |
} |
320 | 320 |
} |
321 | 321 |
|
322 | 322 |
private: |
323 |
|
|
323 |
|
|
324 | 324 |
void allocate_memory() { |
325 | 325 |
int max_id = Parent::notifier()->maxId(); |
326 | 326 |
if (max_id == -1) { |
327 |
capacity = 0; |
|
328 |
values = 0; |
|
329 |
|
|
327 |
capacity = 0; |
|
328 |
values = 0; |
|
329 |
return; |
|
330 | 330 |
} |
331 | 331 |
capacity = 1; |
332 | 332 |
while (capacity <= max_id) { |
333 |
|
|
333 |
capacity <<= 1; |
|
334 | 334 |
} |
335 |
values = allocator.allocate(capacity); |
|
336 |
} |
|
335 |
values = allocator.allocate(capacity); |
|
336 |
} |
|
337 | 337 |
|
338 | 338 |
int capacity; |
339 | 339 |
Value* values; |
340 | 340 |
Allocator allocator; |
341 | 341 |
|
342 |
}; |
|
342 |
}; |
|
343 | 343 |
|
344 | 344 |
} |
345 | 345 |
|
346 |
#endif |
|
346 |
#endif |
1 |
/* -*- C++ -*- |
|
1 |
/* -*- mode: C++; indent-tabs-mode: nil; -*- |
|
2 | 2 |
* |
3 |
* This file is a part of LEMON, a generic C++ optimization library |
|
3 |
* This file is a part of LEMON, a generic C++ optimization library. |
|
4 | 4 |
* |
5 | 5 |
* Copyright (C) 2003-2008 |
6 | 6 |
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
7 | 7 |
* (Egervary Research Group on Combinatorial Optimization, EGRES). |
8 | 8 |
* |
9 | 9 |
* Permission to use, modify and distribute this software is granted |
... | ... |
@@ -60,20 +60,20 @@ |
60 | 60 |
Arc() {} |
61 | 61 |
|
62 | 62 |
/// Invalid arc constructor |
63 | 63 |
Arc(Invalid i) : Edge(i), forward(true) {} |
64 | 64 |
|
65 | 65 |
bool operator==(const Arc &that) const { |
66 |
|
|
66 |
return forward==that.forward && Edge(*this)==Edge(that); |
|
67 | 67 |
} |
68 | 68 |
bool operator!=(const Arc &that) const { |
69 |
|
|
69 |
return forward!=that.forward || Edge(*this)!=Edge(that); |
|
70 | 70 |
} |
71 | 71 |
bool operator<(const Arc &that) const { |
72 |
return forward<that.forward || |
|
73 |
(!(that.forward<forward) && Edge(*this)<Edge(that)); |
|
72 |
return forward<that.forward || |
|
73 |
(!(that.forward<forward) && Edge(*this)<Edge(that)); |
|
74 | 74 |
} |
75 | 75 |
}; |
76 | 76 |
|
77 | 77 |
|
78 | 78 |
|
79 | 79 |
using Parent::source; |
... | ... |
@@ -114,65 +114,65 @@ |
114 | 114 |
Parent::first(e); |
115 | 115 |
e.forward=true; |
116 | 116 |
} |
117 | 117 |
|
118 | 118 |
void next(Arc &e) const { |
119 | 119 |
if( e.forward ) { |
120 |
|
|
120 |
e.forward = false; |
|
121 | 121 |
} |
122 | 122 |
else { |
123 |
Parent::next(e); |
|
124 |
e.forward = true; |
|
123 |
Parent::next(e); |
|
124 |
e.forward = true; |
|
125 | 125 |
} |
126 | 126 |
} |
127 | 127 |
|
128 | 128 |
void firstOut(Arc &e, const Node &n) const { |
129 | 129 |
Parent::firstIn(e,n); |
130 | 130 |
if( Edge(e) != INVALID ) { |
131 |
|
|
131 |
e.forward = false; |
|
132 | 132 |
} |
133 | 133 |
else { |
134 |
Parent::firstOut(e,n); |
|
135 |
e.forward = true; |
|
134 |
Parent::firstOut(e,n); |
|
135 |
e.forward = true; |
|
136 | 136 |
} |
137 | 137 |
} |
138 | 138 |
void nextOut(Arc &e) const { |
139 | 139 |
if( ! e.forward ) { |
140 |
Node n = Parent::target(e); |
|
141 |
Parent::nextIn(e); |
|
142 |
if( Edge(e) == INVALID ) { |
|
143 |
Parent::firstOut(e, n); |
|
144 |
e.forward = true; |
|
145 |
} |
|
140 |
Node n = Parent::target(e); |
|
141 |
Parent::nextIn(e); |
|
142 |
if( Edge(e) == INVALID ) { |
|
143 |
Parent::firstOut(e, n); |
|
144 |
e.forward = true; |
|
145 |
} |
|
146 | 146 |
} |
147 | 147 |
else { |
148 |
|
|
148 |
Parent::nextOut(e); |
|
149 | 149 |
} |
150 | 150 |
} |
151 | 151 |
|
152 | 152 |
void firstIn(Arc &e, const Node &n) const { |
153 | 153 |
Parent::firstOut(e,n); |
154 | 154 |
if( Edge(e) != INVALID ) { |
155 |
|
|
155 |
e.forward = false; |
|
156 | 156 |
} |
157 | 157 |
else { |
158 |
Parent::firstIn(e,n); |
|
159 |
e.forward = true; |
|
158 |
Parent::firstIn(e,n); |
|
159 |
e.forward = true; |
|
160 | 160 |
} |
161 | 161 |
} |
162 | 162 |
void nextIn(Arc &e) const { |
163 | 163 |
if( ! e.forward ) { |
164 |
Node n = Parent::source(e); |
|
165 |
Parent::nextOut(e); |
|
166 |
if( Edge(e) == INVALID ) { |
|
167 |
Parent::firstIn(e, n); |
|
168 |
e.forward = true; |
|
169 |
} |
|
164 |
Node n = Parent::source(e); |
|
165 |
Parent::nextOut(e); |
|
166 |
if( Edge(e) == INVALID ) { |
|
167 |
Parent::firstIn(e, n); |
|
168 |
e.forward = true; |
|
169 |
} |
|
170 | 170 |
} |
171 | 171 |
else { |
172 |
|
|
172 |
Parent::nextIn(e); |
|
173 | 173 |
} |
174 | 174 |
} |
175 | 175 |
|
176 | 176 |
void firstInc(Edge &e, bool &d, const Node &n) const { |
177 | 177 |
d = true; |
178 | 178 |
Parent::firstOut(e, n); |
... | ... |
@@ -180,19 +180,19 @@ |
180 | 180 |
d = false; |
181 | 181 |
Parent::firstIn(e, n); |
182 | 182 |
} |
183 | 183 |
|
184 | 184 |
void nextInc(Edge &e, bool &d) const { |
185 | 185 |
if (d) { |
186 |
Node s = Parent::source(e); |
|
187 |
Parent::nextOut(e); |
|
188 |
if (e != INVALID) return; |
|
189 |
d = false; |
|
190 |
|
|
186 |
Node s = Parent::source(e); |
|
187 |
Parent::nextOut(e); |
|
188 |
if (e != INVALID) return; |
|
189 |
d = false; |
|
190 |
Parent::firstIn(e, s); |
|
191 | 191 |
} else { |
192 |
|
|
192 |
Parent::nextIn(e); |
|
193 | 193 |
} |
194 | 194 |
} |
195 | 195 |
|
196 | 196 |
Node nodeFromId(int ix) const { |
197 | 197 |
return Parent::nodeFromId(ix); |
198 | 198 |
} |
... | ... |
@@ -237,24 +237,24 @@ |
237 | 237 |
int edgeNum() const { |
238 | 238 |
return Parent::arcNum(); |
239 | 239 |
} |
240 | 240 |
|
241 | 241 |
Arc findArc(Node s, Node t, Arc p = INVALID) const { |
242 | 242 |
if (p == INVALID) { |
243 |
Edge arc = Parent::findArc(s, t); |
|
244 |
if (arc != INVALID) return direct(arc, true); |
|
245 |
arc = Parent::findArc(t, s); |
|
246 |
if (arc != INVALID) return direct(arc, false); |
|
243 |
Edge arc = Parent::findArc(s, t); |
|
244 |
if (arc != INVALID) return direct(arc, true); |
|
245 |
arc = Parent::findArc(t, s); |
|
246 |
if (arc != INVALID) return direct(arc, false); |
|
247 | 247 |
} else if (direction(p)) { |
248 |
Edge arc = Parent::findArc(s, t, p); |
|
249 |
if (arc != INVALID) return direct(arc, true); |
|
250 |
arc = Parent::findArc(t, s); |
|
251 |
if (arc != INVALID) return direct(arc, false); |
|
248 |
Edge arc = Parent::findArc(s, t, p); |
|
249 |
if (arc != INVALID) return direct(arc, true); |
|
250 |
arc = Parent::findArc(t, s); |
|
251 |
if (arc != INVALID) return direct(arc, false); |
|
252 | 252 |
} else { |
253 |
Edge arc = Parent::findArc(t, s, p); |
|
254 |
if (arc != INVALID) return direct(arc, false); |
|
253 |
Edge arc = Parent::findArc(t, s, p); |
|
254 |
if (arc != INVALID) return direct(arc, false); |
|
255 | 255 |
} |
256 | 256 |
return INVALID; |
257 | 257 |
} |
258 | 258 |
|
259 | 259 |
Edge findEdge(Node s, Node t, Edge p = INVALID) const { |
260 | 260 |
if (s != t) { |
... | ... |
@@ -264,16 +264,16 @@ |
264 | 264 |
arc = Parent::findArc(t, s); |
265 | 265 |
if (arc != INVALID) return arc; |
266 | 266 |
} else if (Parent::s(p) == s) { |
267 | 267 |
Edge arc = Parent::findArc(s, t, p); |
268 | 268 |
if (arc != INVALID) return arc; |
269 | 269 |
arc = Parent::findArc(t, s); |
270 |
if (arc != INVALID) return arc; |
|
270 |
if (arc != INVALID) return arc; |
|
271 | 271 |
} else { |
272 | 272 |
Edge arc = Parent::findArc(t, s, p); |
273 |
if (arc != INVALID) return arc; |
|
273 |
if (arc != INVALID) return arc; |
|
274 | 274 |
} |
275 | 275 |
} else { |
276 | 276 |
return Parent::findArc(s, t, p); |
277 | 277 |
} |
278 | 278 |
return INVALID; |
279 | 279 |
} |
... | ... |
@@ -296,18 +296,18 @@ |
296 | 296 |
|
297 | 297 |
class Red : public Node { |
298 | 298 |
friend class BidirBpGraphExtender; |
299 | 299 |
public: |
300 | 300 |
Red() {} |
301 | 301 |
Red(const Node& node) : Node(node) { |
302 |
LEMON_ASSERT(Parent::red(node) || node == INVALID, |
|
303 |
typename Parent::NodeSetError()); |
|
302 |
LEMON_ASSERT(Parent::red(node) || node == INVALID, |
|
303 |
typename Parent::NodeSetError()); |
|
304 | 304 |
} |
305 | 305 |
Red& operator=(const Node& node) { |
306 |
LEMON_ASSERT(Parent::red(node) || node == INVALID, |
|
307 |
typename Parent::NodeSetError()); |
|
306 |
LEMON_ASSERT(Parent::red(node) || node == INVALID, |
|
307 |
typename Parent::NodeSetError()); |
|
308 | 308 |
Node::operator=(node); |
309 | 309 |
return *this; |
310 | 310 |
} |
311 | 311 |
Red(Invalid) : Node(INVALID) {} |
312 | 312 |
Red& operator=(Invalid) { |
313 | 313 |
Node::operator=(INVALID); |
... | ... |
@@ -328,18 +328,18 @@ |
328 | 328 |
|
329 | 329 |
class Blue : public Node { |
330 | 330 |
friend class BidirBpGraphExtender; |
331 | 331 |
public: |
332 | 332 |
Blue() {} |
333 | 333 |
Blue(const Node& node) : Node(node) { |
334 |
LEMON_ASSERT(Parent::blue(node) || node == INVALID, |
|
335 |
typename Parent::NodeSetError()); |
|
334 |
LEMON_ASSERT(Parent::blue(node) || node == INVALID, |
|
335 |
typename Parent::NodeSetError()); |
|
336 | 336 |
} |
337 | 337 |
Blue& operator=(const Node& node) { |
338 |
LEMON_ASSERT(Parent::blue(node) || node == INVALID, |
|
339 |
typename Parent::NodeSetError()); |
|
338 |
LEMON_ASSERT(Parent::blue(node) || node == INVALID, |
|
339 |
typename Parent::NodeSetError()); |
|
340 | 340 |
Node::operator=(node); |
341 | 341 |
return *this; |
342 | 342 |
} |
343 | 343 |
Blue(Invalid) : Node(INVALID) {} |
344 | 344 |
Blue& operator=(Invalid) { |
345 | 345 |
Node::operator=(INVALID); |
... | ... |
@@ -350,13 +350,13 @@ |
350 | 350 |
void first(Blue& node) const { |
351 | 351 |
Parent::firstBlue(static_cast<Node&>(node)); |
352 | 352 |
} |
353 | 353 |
void next(Blue& node) const { |
354 | 354 |
Parent::nextBlue(static_cast<Node&>(node)); |
355 | 355 |
} |
356 |
|
|
356 |
|
|
357 | 357 |
int id(const Blue& node) const { |
358 | 358 |
return Parent::redId(node); |
359 | 359 |
} |
360 | 360 |
|
361 | 361 |
Node source(const Edge& arc) const { |
362 | 362 |
return red(arc); |
... | ... |
@@ -364,108 +364,108 @@ |
364 | 364 |
Node target(const Edge& arc) const { |
365 | 365 |
return blue(arc); |
366 | 366 |
} |
367 | 367 |
|
368 | 368 |
void firstInc(Edge& arc, bool& dir, const Node& node) const { |
369 | 369 |
if (Parent::red(node)) { |
370 |
Parent::firstFromRed(arc, node); |
|
371 |
dir = true; |
|
370 |
Parent::firstFromRed(arc, node); |
|
371 |
dir = true; |
|
372 | 372 |
} else { |
373 |
Parent::firstFromBlue(arc, node); |
|
374 |
dir = static_cast<Edge&>(arc) == INVALID; |
|
373 |
Parent::firstFromBlue(arc, node); |
|
374 |
dir = static_cast<Edge&>(arc) == INVALID; |
|
375 | 375 |
} |
376 | 376 |
} |
377 | 377 |
void nextInc(Edge& arc, bool& dir) const { |
378 | 378 |
if (dir) { |
379 |
|
|
379 |
Parent::nextFromRed(arc); |
|
380 | 380 |
} else { |
381 |
Parent::nextFromBlue(arc); |
|
382 |
if (arc == INVALID) dir = true; |
|
381 |
Parent::nextFromBlue(arc); |
|
382 |
if (arc == INVALID) dir = true; |
|
383 | 383 |
} |
384 | 384 |
} |
385 | 385 |
|
386 | 386 |
class Arc : public Edge { |
387 | 387 |
friend class BidirBpGraphExtender; |
388 | 388 |
protected: |
389 | 389 |
bool forward; |
390 | 390 |
|
391 | 391 |
Arc(const Edge& arc, bool _forward) |
392 |
|
|
392 |
: Edge(arc), forward(_forward) {} |
|
393 | 393 |
|
394 | 394 |
public: |
395 | 395 |
Arc() {} |
396 | 396 |
Arc (Invalid) : Edge(INVALID), forward(true) {} |
397 | 397 |
bool operator==(const Arc& i) const { |
398 |
|
|
398 |
return Edge::operator==(i) && forward == i.forward; |
|
399 | 399 |
} |
400 | 400 |
bool operator!=(const Arc& i) const { |
401 |
|
|
401 |
return Edge::operator!=(i) || forward != i.forward; |
|
402 | 402 |
} |
403 | 403 |
bool operator<(const Arc& i) const { |
404 |
return Edge::operator<(i) || |
|
405 |
(!(i.forward<forward) && Edge(*this)<Edge(i)); |
|
404 |
return Edge::operator<(i) || |
|
405 |
(!(i.forward<forward) && Edge(*this)<Edge(i)); |
|
406 | 406 |
} |
407 | 407 |
}; |
408 | 408 |
|
409 | 409 |
void first(Arc& arc) const { |
410 | 410 |
Parent::first(static_cast<Edge&>(arc)); |
411 | 411 |
arc.forward = true; |
412 | 412 |
} |
413 | 413 |
|
414 | 414 |
void next(Arc& arc) const { |
415 | 415 |
if (!arc.forward) { |
416 |
|
|
416 |
Parent::next(static_cast<Edge&>(arc)); |
|
417 | 417 |
} |
418 | 418 |
arc.forward = !arc.forward; |
419 | 419 |
} |
420 | 420 |
|
421 | 421 |
void firstOut(Arc& arc, const Node& node) const { |
422 | 422 |
if (Parent::red(node)) { |
423 |
Parent::firstFromRed(arc, node); |
|
424 |
arc.forward = true; |
|
423 |
Parent::firstFromRed(arc, node); |
|
424 |
arc.forward = true; |
|
425 | 425 |
} else { |
426 |
Parent::firstFromBlue(arc, node); |
|
427 |
arc.forward = static_cast<Edge&>(arc) == INVALID; |
|
426 |
Parent::firstFromBlue(arc, node); |
|
427 |
arc.forward = static_cast<Edge&>(arc) == INVALID; |
|
428 | 428 |
} |
429 | 429 |
} |
430 | 430 |
void nextOut(Arc& arc) const { |
431 | 431 |
if (arc.forward) { |
432 |
|
|
432 |
Parent::nextFromRed(arc); |
|
433 | 433 |
} else { |
434 |
|
|
434 |
Parent::nextFromBlue(arc); |
|
435 | 435 |
arc.forward = static_cast<Edge&>(arc) == INVALID; |
436 | 436 |
} |
437 | 437 |
} |
438 | 438 |
|
439 | 439 |
void firstIn(Arc& arc, const Node& node) const { |
440 | 440 |
if (Parent::blue(node)) { |
441 |
Parent::firstFromBlue(arc, node); |
|
442 |
arc.forward = true; |
|
441 |
Parent::firstFromBlue(arc, node); |
|
442 |
arc.forward = true; |
|
443 | 443 |
} else { |
444 |
Parent::firstFromRed(arc, node); |
|
445 |
arc.forward = static_cast<Edge&>(arc) == INVALID; |
|
444 |
Parent::firstFromRed(arc, node); |
|
445 |
arc.forward = static_cast<Edge&>(arc) == INVALID; |
|
446 | 446 |
} |
447 | 447 |
} |
448 | 448 |
void nextIn(Arc& arc) const { |
449 | 449 |
if (arc.forward) { |
450 |
|
|
450 |
Parent::nextFromBlue(arc); |
|
451 | 451 |
} else { |
452 |
Parent::nextFromRed(arc); |
|
453 |
arc.forward = static_cast<Edge&>(arc) == INVALID; |
|
452 |
Parent::nextFromRed(arc); |
|
453 |
arc.forward = static_cast<Edge&>(arc) == INVALID; |
|
454 | 454 |
} |
455 | 455 |
} |
456 | 456 |
|
457 | 457 |
Node source(const Arc& arc) const { |
458 | 458 |
return arc.forward ? Parent::red(arc) : Parent::blue(arc); |
459 | 459 |
} |
460 | 460 |
Node target(const Arc& arc) const { |
461 | 461 |
return arc.forward ? Parent::blue(arc) : Parent::red(arc); |
462 | 462 |
} |
463 | 463 |
|
464 | 464 |
int id(const Arc& arc) const { |
465 |
return (Parent::id(static_cast<const Edge&>(arc)) << 1) + |
|
465 |
return (Parent::id(static_cast<const Edge&>(arc)) << 1) + |
|
466 | 466 |
(arc.forward ? 0 : 1); |
467 | 467 |
} |
468 | 468 |
Arc arcFromId(int ix) const { |
469 | 469 |
return Arc(Parent::fromEdgeId(ix >> 1), (ix & 1) == 0); |
470 | 470 |
} |
471 | 471 |
int maxArcId() const { |
1 |
/* -*- C++ -*- |
|
1 |
/* -*- mode: C++; indent-tabs-mode: nil; -*- |
|
2 | 2 |
* |
3 |
* This file is a part of LEMON, a generic C++ optimization library |
|
3 |
* This file is a part of LEMON, a generic C++ optimization library. |
|
4 | 4 |
* |
5 | 5 |
* Copyright (C) 2003-2008 |
6 | 6 |
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
7 | 7 |
* (Egervary Research Group on Combinatorial Optimization, EGRES). |
8 | 8 |
* |
9 | 9 |
* Permission to use, modify and distribute this software is granted |
... | ... |
@@ -41,23 +41,23 @@ |
41 | 41 |
{ |
42 | 42 |
public: |
43 | 43 |
Point p1,p2; |
44 | 44 |
|
45 | 45 |
Bezier1() {} |
46 | 46 |
Bezier1(Point _p1, Point _p2) :p1(_p1), p2(_p2) {} |
47 |
|
|
47 |
|
|
48 | 48 |
Point operator()(double t) const |
49 | 49 |
{ |
50 | 50 |
// return conv(conv(p1,p2,t),conv(p2,p3,t),t); |
51 | 51 |
return conv(p1,p2,t); |
52 | 52 |
} |
53 | 53 |
Bezier1 before(double t) const |
54 | 54 |
{ |
55 | 55 |
return Bezier1(p1,conv(p1,p2,t)); |
56 | 56 |
} |
57 |
|
|
57 |
|
|
58 | 58 |
Bezier1 after(double t) const |
59 | 59 |
{ |
60 | 60 |
return Bezier1(conv(p1,p2,t),p2); |
61 | 61 |
} |
62 | 62 |
|
63 | 63 |
Bezier1 revert() const { return Bezier1(p2,p1);} |
... | ... |
@@ -84,13 +84,13 @@ |
84 | 84 |
Bezier2 before(double t) const |
85 | 85 |
{ |
86 | 86 |
Point q(conv(p1,p2,t)); |
87 | 87 |
Point r(conv(p2,p3,t)); |
88 | 88 |
return Bezier2(p1,q,conv(q,r,t)); |
89 | 89 |
} |
90 |
|
|
90 |
|
|
91 | 91 |
Bezier2 after(double t) const |
92 | 92 |
{ |
93 | 93 |
Point q(conv(p1,p2,t)); |
94 | 94 |
Point r(conv(p2,p3,t)); |
95 | 95 |
return Bezier2(conv(q,r,t),r,p3); |
96 | 96 |
} |
... | ... |
@@ -107,34 +107,34 @@ |
107 | 107 |
public: |
108 | 108 |
Point p1,p2,p3,p4; |
109 | 109 |
|
110 | 110 |
Bezier3() {} |
111 | 111 |
Bezier3(Point _p1, Point _p2, Point _p3, Point _p4) |
112 | 112 |
: p1(_p1), p2(_p2), p3(_p3), p4(_p4) {} |
113 |
Bezier3(const Bezier1 &b) : p1(b.p1), p2(conv(b.p1,b.p2,1.0/3.0)), |
|
114 |
p3(conv(b.p1,b.p2,2.0/3.0)), p4(b.p2) {} |
|
113 |
Bezier3(const Bezier1 &b) : p1(b.p1), p2(conv(b.p1,b.p2,1.0/3.0)), |
|
114 |
p3(conv(b.p1,b.p2,2.0/3.0)), p4(b.p2) {} |
|
115 | 115 |
Bezier3(const Bezier2 &b) : p1(b.p1), p2(conv(b.p1,b.p2,2.0/3.0)), |
116 |
p3(conv(b.p2,b.p3,1.0/3.0)), p4(b.p3) {} |
|
117 |
|
|
118 |
|
|
116 |
p3(conv(b.p2,b.p3,1.0/3.0)), p4(b.p3) {} |
|
117 |
|
|
118 |
Point operator()(double t) const |
|
119 | 119 |
{ |
120 | 120 |
// return Bezier2(conv(p1,p2,t),conv(p2,p3,t),conv(p3,p4,t))(t); |
121 | 121 |
return ((1-t)*(1-t)*(1-t))*p1+(3*t*(1-t)*(1-t))*p2+ |
122 |
|
|
122 |
(3*t*t*(1-t))*p3+(t*t*t)*p4; |
|
123 | 123 |
} |
124 | 124 |
Bezier3 before(double t) const |
125 | 125 |
{ |
126 | 126 |
Point p(conv(p1,p2,t)); |
127 | 127 |
Point q(conv(p2,p3,t)); |
128 | 128 |
Point r(conv(p3,p4,t)); |
129 | 129 |
Point a(conv(p,q,t)); |
130 | 130 |
Point b(conv(q,r,t)); |
131 | 131 |
Point c(conv(a,b,t)); |
132 | 132 |
return Bezier3(p1,p,a,c); |
133 | 133 |
} |
134 |
|
|
134 |
|
|
135 | 135 |
Bezier3 after(double t) const |
136 | 136 |
{ |
137 | 137 |
Point p(conv(p1,p2,t)); |
138 | 138 |
Point q(conv(p2,p3,t)); |
139 | 139 |
Point r(conv(p3,p4,t)); |
140 | 140 |
Point a(conv(p,q,t)); |
... | ... |
@@ -143,31 +143,31 @@ |
143 | 143 |
return Bezier3(c,b,r,p4); |
144 | 144 |
} |
145 | 145 |
Bezier3 revert() const { return Bezier3(p4,p3,p2,p1);} |
146 | 146 |
Bezier3 operator()(double a,double b) const { return before(b).after(a/b); } |
147 | 147 |
Bezier2 grad() const { return Bezier2(3.0*(p2-p1),3.0*(p3-p2),3.0*(p4-p3)); } |
148 | 148 |
Bezier2 norm() const { return Bezier2(3.0*rot90(p2-p1), |
149 |
3.0*rot90(p3-p2), |
|
150 |
3.0*rot90(p4-p3)); } |
|
149 |
3.0*rot90(p3-p2), |
|
150 |
3.0*rot90(p4-p3)); } |
|
151 | 151 |
Point grad(double t) const { return grad()(t); } |
152 | 152 |
Point norm(double t) const { return rot90(grad(t)); } |
153 | 153 |
|
154 | 154 |
template<class R,class F,class S,class D> |
155 |
R recSplit(F &_f,const S &_s,D _d) const |
|
155 |
R recSplit(F &_f,const S &_s,D _d) const |
|
156 | 156 |
{ |
157 | 157 |
const Point a=(p1+p2)/2; |
158 | 158 |
const Point b=(p2+p3)/2; |
159 | 159 |
const Point c=(p3+p4)/2; |
160 | 160 |
const Point d=(a+b)/2; |
161 | 161 |
const Point e=(b+c)/2; |
162 | 162 |
const Point f=(d+e)/2; |
163 | 163 |
R f1=_f(Bezier3(p1,a,d,e),_d); |
164 | 164 |
R f2=_f(Bezier3(e,d,c,p4),_d); |
165 | 165 |
return _s(f1,f2); |
166 | 166 |
} |
167 |
|
|
167 |
|
|
168 | 168 |
}; |
169 | 169 |
|
170 | 170 |
|
171 | 171 |
} //END OF NAMESPACE dim2 |
172 | 172 |
} //END OF NAMESPACE lemon |
173 | 173 |
1 |
/* -*- C++ -*- |
|
1 |
/* -*- mode: C++; indent-tabs-mode: nil; -*- |
|
2 | 2 |
* |
3 |
* This file is a part of LEMON, a generic C++ optimization library |
|
3 |
* This file is a part of LEMON, a generic C++ optimization library. |
|
4 | 4 |
* |
5 | 5 |
* Copyright (C) 2003-2008 |
6 | 6 |
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
7 | 7 |
* (Egervary Research Group on Combinatorial Optimization, EGRES). |
8 | 8 |
* |
9 | 9 |
* Permission to use, modify and distribute this software is granted |
... | ... |
@@ -26,14 +26,14 @@ |
26 | 26 |
|
27 | 27 |
///\ingroup graphbits |
28 | 28 |
///\file |
29 | 29 |
///\brief Graph maps that construct and destruct their elements dynamically. |
30 | 30 |
|
31 | 31 |
namespace lemon { |
32 |
|
|
33 |
|
|
32 |
|
|
33 |
|
|
34 | 34 |
//#ifndef LEMON_USE_DEBUG_MAP |
35 | 35 |
|
36 | 36 |
template <typename _Graph, typename _Item, typename _Value> |
37 | 37 |
struct DefaultMapSelector { |
38 | 38 |
typedef ArrayMap<_Graph, _Item, _Value> Map; |
39 | 39 |
}; |
... | ... |
@@ -137,34 +137,34 @@ |
137 | 137 |
// pointer |
138 | 138 |
template <typename _Graph, typename _Item, typename _Ptr> |
139 | 139 |
struct DefaultMapSelector<_Graph, _Item, _Ptr*> { |
140 | 140 |
typedef VectorMap<_Graph, _Item, _Ptr*> Map; |
141 | 141 |
}; |
142 | 142 |
|
143 |
// #else |
|
143 |
// #else |
|
144 | 144 |
|
145 | 145 |
// template <typename _Graph, typename _Item, typename _Value> |
146 | 146 |
// struct DefaultMapSelector { |
147 | 147 |
// typedef DebugMap<_Graph, _Item, _Value> Map; |
148 | 148 |
// }; |
149 | 149 |
|
150 |
// #endif |
|
150 |
// #endif |
|
151 | 151 |
|
152 | 152 |
/// \e |
153 | 153 |
template <typename _Graph, typename _Item, typename _Value> |
154 |
class DefaultMap |
|
154 |
class DefaultMap |
|
155 | 155 |
: public DefaultMapSelector<_Graph, _Item, _Value>::Map { |
156 | 156 |
public: |
157 | 157 |
typedef typename DefaultMapSelector<_Graph, _Item, _Value>::Map Parent; |
158 | 158 |
typedef DefaultMap<_Graph, _Item, _Value> Map; |
159 |
|
|
159 |
|
|
160 | 160 |
typedef typename Parent::Graph Graph; |
161 | 161 |
typedef typename Parent::Value Value; |
162 | 162 |
|
163 | 163 |
explicit DefaultMap(const Graph& graph) : Parent(graph) {} |
164 |
DefaultMap(const Graph& graph, const Value& value) |
|
164 |
DefaultMap(const Graph& graph, const Value& value) |
|
165 | 165 |
: Parent(graph, value) {} |
166 | 166 |
|
167 | 167 |
DefaultMap& operator=(const DefaultMap& cmap) { |
168 | 168 |
return operator=<DefaultMap>(cmap); |
169 | 169 |
} |
170 | 170 |
1 |
/* -*- C++ -*- |
|
1 |
/* -*- mode: C++; indent-tabs-mode: nil; -*- |
|
2 | 2 |
* |
3 |
* This file is a part of LEMON, a generic C++ optimization library |
|
3 |
* This file is a part of LEMON, a generic C++ optimization library. |
|
4 | 4 |
* |
5 | 5 |
* Copyright (C) 2003-2008 |
6 | 6 |
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
7 | 7 |
* (Egervary Research Group on Combinatorial Optimization, EGRES). |
8 | 8 |
* |
9 | 9 |
* Permission to use, modify and distribute this software is granted |
... | ... |
@@ -63,17 +63,17 @@ |
63 | 63 |
Arc fromId(int id, Arc) const { |
64 | 64 |
return Parent::arcFromId(id); |
65 | 65 |
} |
66 | 66 |
|
67 | 67 |
Node oppositeNode(const Node &node, const Arc &arc) const { |
68 | 68 |
if (node == Parent::source(arc)) |
69 |
|
|
69 |
return Parent::target(arc); |
|
70 | 70 |
else if(node == Parent::target(arc)) |
71 |
|
|
71 |
return Parent::source(arc); |
|
72 | 72 |
else |
73 |
|
|
73 |
return INVALID; |
|
74 | 74 |
} |
75 | 75 |
|
76 | 76 |
// Alterable extension |
77 | 77 |
|
78 | 78 |
typedef AlterationNotifier<DigraphExtender, Node> NodeNotifier; |
79 | 79 |
typedef AlterationNotifier<DigraphExtender, Arc> ArcNotifier; |
... | ... |
@@ -86,106 +86,106 @@ |
86 | 86 |
|
87 | 87 |
public: |
88 | 88 |
|
89 | 89 |
NodeNotifier& notifier(Node) const { |
90 | 90 |
return node_notifier; |
91 | 91 |
} |
92 |
|
|
92 |
|
|
93 | 93 |
ArcNotifier& notifier(Arc) const { |
94 | 94 |
return arc_notifier; |
95 | 95 |
} |
96 | 96 |
|
97 |
class NodeIt : public Node { |
|
97 |
class NodeIt : public Node { |
|
98 | 98 |
const Digraph* _digraph; |
99 | 99 |
public: |
100 | 100 |
|
101 | 101 |
NodeIt() {} |
102 | 102 |
|
103 | 103 |
NodeIt(Invalid i) : Node(i) { } |
104 | 104 |
|
105 | 105 |
explicit NodeIt(const Digraph& digraph) : _digraph(&digraph) { |
106 |
|
|
106 |
_digraph->first(static_cast<Node&>(*this)); |
|
107 | 107 |
} |
108 | 108 |
|
109 |
NodeIt(const Digraph& digraph, const Node& node) |
|
110 |
: Node(node), _digraph(&digraph) {} |
|
109 |
NodeIt(const Digraph& digraph, const Node& node) |
|
110 |
: Node(node), _digraph(&digraph) {} |
|
111 | 111 |
|
112 |
NodeIt& operator++() { |
|
113 |
_digraph->next(*this); |
|
114 |
|
|
112 |
NodeIt& operator++() { |
|
113 |
_digraph->next(*this); |
|
114 |
return *this; |
|
115 | 115 |
} |
116 | 116 |
|
117 | 117 |
}; |
118 | 118 |
|
119 | 119 |
|
120 |
class ArcIt : public Arc { |
|
120 |
class ArcIt : public Arc { |
|
121 | 121 |
const Digraph* _digraph; |
122 | 122 |
public: |
123 | 123 |
|
124 | 124 |
ArcIt() { } |
125 | 125 |
|
126 | 126 |
ArcIt(Invalid i) : Arc(i) { } |
127 | 127 |
|
128 | 128 |
explicit ArcIt(const Digraph& digraph) : _digraph(&digraph) { |
129 |
|
|
129 |
_digraph->first(static_cast<Arc&>(*this)); |
|
130 | 130 |
} |
131 | 131 |
|
132 |
ArcIt(const Digraph& digraph, const Arc& arc) : |
|
133 |
Arc(arc), _digraph(&digraph) { } |
|
132 |
ArcIt(const Digraph& digraph, const Arc& arc) : |
|
133 |
Arc(arc), _digraph(&digraph) { } |
|
134 | 134 |
|
135 |
ArcIt& operator++() { |
|
136 |
_digraph->next(*this); |
|
137 |
|
|
135 |
ArcIt& operator++() { |
|
136 |
_digraph->next(*this); |
|
137 |
return *this; |
|
138 | 138 |
} |
139 | 139 |
|
140 | 140 |
}; |
141 | 141 |
|
142 | 142 |
|
143 |
class OutArcIt : public Arc { |
|
143 |
class OutArcIt : public Arc { |
|
144 | 144 |
const Digraph* _digraph; |
145 | 145 |
public: |
146 | 146 |
|
147 | 147 |
OutArcIt() { } |
148 | 148 |
|
149 | 149 |
OutArcIt(Invalid i) : Arc(i) { } |
150 | 150 |
|
151 |
OutArcIt(const Digraph& digraph, const Node& node) |
|
152 |
: _digraph(&digraph) { |
|
153 |
|
|
151 |
OutArcIt(const Digraph& digraph, const Node& node) |
|
152 |
: _digraph(&digraph) { |
|
153 |
_digraph->firstOut(*this, node); |
|
154 | 154 |
} |
155 | 155 |
|
156 |
OutArcIt(const Digraph& digraph, const Arc& arc) |
|
157 |
: Arc(arc), _digraph(&digraph) {} |
|
156 |
OutArcIt(const Digraph& digraph, const Arc& arc) |
|
157 |
: Arc(arc), _digraph(&digraph) {} |
|
158 | 158 |
|
159 |
OutArcIt& operator++() { |
|
160 |
_digraph->nextOut(*this); |
|
161 |
|
|
159 |
OutArcIt& operator++() { |
|
160 |
_digraph->nextOut(*this); |
|
161 |
return *this; |
|
162 | 162 |
} |
163 | 163 |
|
164 | 164 |
}; |
165 | 165 |
|
166 | 166 |
|
167 |
class InArcIt : public Arc { |
|
167 |
class InArcIt : public Arc { |
|
168 | 168 |
const Digraph* _digraph; |
169 | 169 |
public: |
170 | 170 |
|
171 | 171 |
InArcIt() { } |
172 | 172 |
|
173 | 173 |
InArcIt(Invalid i) : Arc(i) { } |
174 | 174 |
|
175 |
InArcIt(const Digraph& digraph, const Node& node) |
|
176 |
: _digraph(&digraph) { |
|
177 |
|
|
175 |
InArcIt(const Digraph& digraph, const Node& node) |
|
176 |
: _digraph(&digraph) { |
|
177 |
_digraph->firstIn(*this, node); |
|
178 | 178 |
} |
179 | 179 |
|
180 |
InArcIt(const Digraph& digraph, const Arc& arc) : |
|
181 |
Arc(arc), _digraph(&digraph) {} |
|
180 |
InArcIt(const Digraph& digraph, const Arc& arc) : |
|
181 |
Arc(arc), _digraph(&digraph) {} |
|
182 | 182 |
|
183 |
InArcIt& operator++() { |
|
184 |
_digraph->nextIn(*this); |
|
185 |
|
|
183 |
InArcIt& operator++() { |
|
184 |
_digraph->nextIn(*this); |
|
185 |
return *this; |
|
186 | 186 |
} |
187 | 187 |
|
188 | 188 |
}; |
189 | 189 |
|
190 | 190 |
/// \brief Base node of the iterator |
191 | 191 |
/// |
... | ... |
@@ -212,67 +212,67 @@ |
212 | 212 |
/// Returns the running node (i.e. the source in this case) of the |
213 | 213 |
/// iterator |
214 | 214 |
Node runningNode(const InArcIt &arc) const { |
215 | 215 |
return Parent::source(arc); |
216 | 216 |
} |
217 | 217 |
|
218 |
|
|
218 |
|
|
219 | 219 |
template <typename _Value> |
220 |
class NodeMap |
|
220 |
class NodeMap |
|
221 | 221 |
: public MapExtender<DefaultMap<Digraph, Node, _Value> > { |
222 | 222 |
public: |
223 | 223 |
typedef DigraphExtender Digraph; |
224 | 224 |
typedef MapExtender<DefaultMap<Digraph, Node, _Value> > Parent; |
225 | 225 |
|
226 |
explicit NodeMap(const Digraph& digraph) |
|
227 |
: Parent(digraph) {} |
|
228 |
NodeMap(const Digraph& digraph, const _Value& value) |
|
229 |
: Parent(digraph, value) {} |
|
226 |
explicit NodeMap(const Digraph& digraph) |
|
227 |
: Parent(digraph) {} |
|
228 |
NodeMap(const Digraph& digraph, const _Value& value) |
|
229 |
: Parent(digraph, value) {} |
|
230 | 230 |
|
231 | 231 |
NodeMap& operator=(const NodeMap& cmap) { |
232 |
|
|
232 |
return operator=<NodeMap>(cmap); |
|
233 | 233 |
} |
234 | 234 |
|
235 | 235 |
template <typename CMap> |
236 | 236 |
NodeMap& operator=(const CMap& cmap) { |
237 | 237 |
Parent::operator=(cmap); |
238 |
|
|
238 |
return *this; |
|
239 | 239 |
} |
240 | 240 |
|
241 | 241 |
}; |
242 | 242 |
|
243 | 243 |
template <typename _Value> |
244 |
class ArcMap |
|
244 |
class ArcMap |
|
245 | 245 |
: public MapExtender<DefaultMap<Digraph, Arc, _Value> > { |
246 | 246 |
public: |
247 | 247 |
typedef DigraphExtender Digraph; |
248 | 248 |
typedef MapExtender<DefaultMap<Digraph, Arc, _Value> > Parent; |
249 | 249 |
|
250 |
explicit ArcMap(const Digraph& digraph) |
|
251 |
: Parent(digraph) {} |
|
252 |
ArcMap(const Digraph& digraph, const _Value& value) |
|
253 |
: Parent(digraph, value) {} |
|
250 |
explicit ArcMap(const Digraph& digraph) |
|
251 |
: Parent(digraph) {} |
|
252 |
ArcMap(const Digraph& digraph, const _Value& value) |
|
253 |
: Parent(digraph, value) {} |
|
254 | 254 |
|
255 | 255 |
ArcMap& operator=(const ArcMap& cmap) { |
256 |
|
|
256 |
return operator=<ArcMap>(cmap); |
|
257 | 257 |
} |
258 | 258 |
|
259 | 259 |
template <typename CMap> |
260 | 260 |
ArcMap& operator=(const CMap& cmap) { |
261 | 261 |
Parent::operator=(cmap); |
262 |
|
|
262 |
return *this; |
|
263 | 263 |
} |
264 | 264 |
}; |
265 | 265 |
|
266 | 266 |
|
267 | 267 |
Node addNode() { |
268 | 268 |
Node node = Parent::addNode(); |
269 | 269 |
notifier(Node()).add(node); |
270 | 270 |
return node; |
271 | 271 |
} |
272 |
|
|
272 |
|
|
273 | 273 |
Arc addArc(const Node& from, const Node& to) { |
274 | 274 |
Arc arc = Parent::addArc(from, to); |
275 | 275 |
notifier(Arc()).add(arc); |
276 | 276 |
return arc; |
277 | 277 |
} |
278 | 278 |
|
... | ... |
@@ -290,60 +290,60 @@ |
290 | 290 |
} |
291 | 291 |
|
292 | 292 |
void erase(const Node& node) { |
293 | 293 |
Arc arc; |
294 | 294 |
Parent::firstOut(arc, node); |
295 | 295 |
while (arc != INVALID ) { |
296 |
erase(arc); |
|
297 |
Parent::firstOut(arc, node); |
|
298 |
|
|
296 |
erase(arc); |
|
297 |
Parent::firstOut(arc, node); |
|
298 |
} |
|
299 | 299 |
|
300 | 300 |
Parent::firstIn(arc, node); |
301 | 301 |
while (arc != INVALID ) { |
302 |
erase(arc); |
|
303 |
Parent::firstIn(arc, node); |
|
302 |
erase(arc); |
|
303 |
Parent::firstIn(arc, node); |
|
304 | 304 |
} |
305 | 305 |
|
306 | 306 |
notifier(Node()).erase(node); |
307 | 307 |
Parent::erase(node); |
308 | 308 |
} |
309 |
|
|
309 |
|
|
310 | 310 |
void erase(const Arc& arc) { |
311 | 311 |
notifier(Arc()).erase(arc); |
312 | 312 |
Parent::erase(arc); |
313 | 313 |
} |
314 | 314 |
|
315 | 315 |
DigraphExtender() { |
316 | 316 |
node_notifier.setContainer(*this); |
317 | 317 |
arc_notifier.setContainer(*this); |
318 |
} |
|
319 |
|
|
318 |
} |
|
319 |
|
|
320 | 320 |
|
321 | 321 |
~DigraphExtender() { |
322 | 322 |
arc_notifier.clear(); |
323 | 323 |
node_notifier.clear(); |
324 | 324 |
} |
325 | 325 |
}; |
326 | 326 |
|
327 | 327 |
/// \ingroup _graphbits |
328 | 328 |
/// |
329 | 329 |
/// \brief Extender for the Graphs |
330 |
template <typename Base> |
|
330 |
template <typename Base> |
|
331 | 331 |
class GraphExtender : public Base { |
332 | 332 |
public: |
333 |
|
|
333 |
|
|
334 | 334 |
typedef Base Parent; |
335 | 335 |
typedef GraphExtender Graph; |
336 | 336 |
|
337 | 337 |
typedef True UndirectedTag; |
338 | 338 |
|
339 | 339 |
typedef typename Parent::Node Node; |
340 | 340 |
typedef typename Parent::Arc Arc; |
341 | 341 |
typedef typename Parent::Edge Edge; |
342 | 342 |
|
343 |
// Graph extension |
|
343 |
// Graph extension |
|
344 | 344 |
|
345 | 345 |
int maxId(Node) const { |
346 | 346 |
return Parent::maxNodeId(); |
347 | 347 |
} |
348 | 348 |
|
349 | 349 |
int maxId(Arc) const { |
... | ... |
@@ -365,17 +365,17 @@ |
365 | 365 |
Edge fromId(int id, Edge) const { |
366 | 366 |
return Parent::edgeFromId(id); |
367 | 367 |
} |
368 | 368 |
|
369 | 369 |
Node oppositeNode(const Node &n, const Edge &e) const { |
370 | 370 |
if( n == Parent::u(e)) |
371 |
|
|
371 |
return Parent::v(e); |
|
372 | 372 |
else if( n == Parent::v(e)) |
373 |
|
|
373 |
return Parent::u(e); |
|
374 | 374 |
else |
375 |
|
|
375 |
return INVALID; |
|
376 | 376 |
} |
377 | 377 |
|
378 | 378 |
Arc oppositeArc(const Arc &arc) const { |
379 | 379 |
return Parent::direct(arc, !Parent::direction(arc)); |
380 | 380 |
} |
381 | 381 |
|
... | ... |
@@ -399,135 +399,135 @@ |
399 | 399 |
|
400 | 400 |
public: |
401 | 401 |
|
402 | 402 |
NodeNotifier& notifier(Node) const { |
403 | 403 |
return node_notifier; |
404 | 404 |
} |
405 |
|
|
405 |
|
|
406 | 406 |
ArcNotifier& notifier(Arc) const { |
407 | 407 |
return arc_notifier; |
408 | 408 |
} |
409 | 409 |
|
410 | 410 |
EdgeNotifier& notifier(Edge) const { |
411 | 411 |
return edge_notifier; |
412 | 412 |
} |
413 | 413 |
|
414 | 414 |
|
415 | 415 |
|
416 |
class NodeIt : public Node { |
|
416 |
class NodeIt : public Node { |
|
417 | 417 |
const Graph* _graph; |
418 | 418 |
public: |
419 | 419 |
|
420 | 420 |
NodeIt() {} |
421 | 421 |
|
422 | 422 |
NodeIt(Invalid i) : Node(i) { } |
423 | 423 |
|
424 | 424 |
explicit NodeIt(const Graph& graph) : _graph(&graph) { |
425 |
|
|
425 |
_graph->first(static_cast<Node&>(*this)); |
|
426 | 426 |
} |
427 | 427 |
|
428 |
NodeIt(const Graph& graph, const Node& node) |
|
429 |
: Node(node), _graph(&graph) {} |
|
428 |
NodeIt(const Graph& graph, const Node& node) |
|
429 |
: Node(node), _graph(&graph) {} |
|
430 | 430 |
|
431 |
NodeIt& operator++() { |
|
432 |
_graph->next(*this); |
|
433 |
|
|
431 |
NodeIt& operator++() { |
|
432 |
_graph->next(*this); |
|
433 |
return *this; |
|
434 | 434 |
} |
435 | 435 |
|
436 | 436 |
}; |
437 | 437 |
|
438 | 438 |
|
439 |
class ArcIt : public Arc { |
|
439 |
class ArcIt : public Arc { |
|
440 | 440 |
const Graph* _graph; |
441 | 441 |
public: |
442 | 442 |
|
443 | 443 |
ArcIt() { } |
444 | 444 |
|
445 | 445 |
ArcIt(Invalid i) : Arc(i) { } |
446 | 446 |
|
447 | 447 |
explicit ArcIt(const Graph& graph) : _graph(&graph) { |
448 |
|
|
448 |
_graph->first(static_cast<Arc&>(*this)); |
|
449 | 449 |
} |
450 | 450 |
|
451 |
ArcIt(const Graph& graph, const Arc& arc) : |
|
452 |
Arc(arc), _graph(&graph) { } |
|
451 |
ArcIt(const Graph& graph, const Arc& arc) : |
|
452 |
Arc(arc), _graph(&graph) { } |
|
453 | 453 |
|
454 |
ArcIt& operator++() { |
|
455 |
_graph->next(*this); |
|
456 |
|
|
454 |
ArcIt& operator++() { |
|
455 |
_graph->next(*this); |
|
456 |
return *this; |
|
457 | 457 |
} |
458 | 458 |
|
459 | 459 |
}; |
460 | 460 |
|
461 | 461 |
|
462 |
class OutArcIt : public Arc { |
|
462 |
class OutArcIt : public Arc { |
|
463 | 463 |
const Graph* _graph; |
464 | 464 |
public: |
465 | 465 |
|
466 | 466 |
OutArcIt() { } |
467 | 467 |
|
468 | 468 |
OutArcIt(Invalid i) : Arc(i) { } |
469 | 469 |
|
470 |
OutArcIt(const Graph& graph, const Node& node) |
|
471 |
: _graph(&graph) { |
|
472 |
|
|
470 |
OutArcIt(const Graph& graph, const Node& node) |
|
471 |
: _graph(&graph) { |
|
472 |
_graph->firstOut(*this, node); |
|
473 | 473 |
} |
474 | 474 |
|
475 |
OutArcIt(const Graph& graph, const Arc& arc) |
|
476 |
: Arc(arc), _graph(&graph) {} |
|
475 |
OutArcIt(const Graph& graph, const Arc& arc) |
|
476 |
: Arc(arc), _graph(&graph) {} |
|
477 | 477 |
|
478 |
OutArcIt& operator++() { |
|
479 |
_graph->nextOut(*this); |
|
480 |
|
|
478 |
OutArcIt& operator++() { |
|
479 |
_graph->nextOut(*this); |
|
480 |
return *this; |
|
481 | 481 |
} |
482 | 482 |
|
483 | 483 |
}; |
484 | 484 |
|
485 | 485 |
|
486 |
class InArcIt : public Arc { |
|
486 |
class InArcIt : public Arc { |
|
487 | 487 |
const Graph* _graph; |
488 | 488 |
public: |
489 | 489 |
|
490 | 490 |
InArcIt() { } |
491 | 491 |
|
492 | 492 |
InArcIt(Invalid i) : Arc(i) { } |
493 | 493 |
|
494 |
InArcIt(const Graph& graph, const Node& node) |
|
495 |
: _graph(&graph) { |
|
496 |
|
|
494 |
InArcIt(const Graph& graph, const Node& node) |
|
495 |
: _graph(&graph) { |
|
496 |
_graph->firstIn(*this, node); |
|
497 | 497 |
} |
498 | 498 |
|
499 |
InArcIt(const Graph& graph, const Arc& arc) : |
|
500 |
Arc(arc), _graph(&graph) {} |
|
499 |
InArcIt(const Graph& graph, const Arc& arc) : |
|
500 |
Arc(arc), _graph(&graph) {} |
|
501 | 501 |
|
502 |
InArcIt& operator++() { |
|
503 |
_graph->nextIn(*this); |
|
504 |
|
|
502 |
InArcIt& operator++() { |
|
503 |
_graph->nextIn(*this); |
|
504 |
return *this; |
|
505 | 505 |
} |
506 | 506 |
|
507 | 507 |
}; |
508 | 508 |
|
509 | 509 |
|
510 |
class EdgeIt : public Parent::Edge { |
|
510 |
class EdgeIt : public Parent::Edge { |
|
511 | 511 |
const Graph* _graph; |
512 | 512 |
public: |
513 | 513 |
|
514 | 514 |
EdgeIt() { } |
515 | 515 |
|
516 | 516 |
EdgeIt(Invalid i) : Edge(i) { } |
517 | 517 |
|
518 | 518 |
explicit EdgeIt(const Graph& graph) : _graph(&graph) { |
519 |
|
|
519 |
_graph->first(static_cast<Edge&>(*this)); |
|
520 | 520 |
} |
521 | 521 |
|
522 |
EdgeIt(const Graph& graph, const Edge& edge) : |
|
523 |
Edge(edge), _graph(&graph) { } |
|
522 |
EdgeIt(const Graph& graph, const Edge& edge) : |
|
523 |
Edge(edge), _graph(&graph) { } |
|
524 | 524 |
|
525 |
EdgeIt& operator++() { |
|
526 |
_graph->next(*this); |
|
527 |
|
|
525 |
EdgeIt& operator++() { |
|
526 |
_graph->next(*this); |
|
527 |
return *this; |
|
528 | 528 |
} |
529 | 529 |
|
530 | 530 |
}; |
531 | 531 |
|
532 | 532 |
class IncEdgeIt : public Parent::Edge { |
533 | 533 |
friend class GraphExtender; |
... | ... |
@@ -537,23 +537,23 @@ |
537 | 537 |
|
538 | 538 |
IncEdgeIt() { } |
539 | 539 |
|
540 | 540 |
IncEdgeIt(Invalid i) : Edge(i), _direction(false) { } |
541 | 541 |
|
542 | 542 |
IncEdgeIt(const Graph& graph, const Node &node) : _graph(&graph) { |
543 |
|
|
543 |
_graph->firstInc(*this, _direction, node); |
|
544 | 544 |
} |
545 | 545 |
|
546 | 546 |
IncEdgeIt(const Graph& graph, const Edge &edge, const Node &node) |
547 |
: _graph(&graph), Edge(edge) { |
|
548 |
_direction = (_graph->source(edge) == node); |
|
547 |
: _graph(&graph), Edge(edge) { |
|
548 |
_direction = (_graph->source(edge) == node); |
|
549 | 549 |
} |
550 | 550 |
|
551 | 551 |
IncEdgeIt& operator++() { |
552 |
_graph->nextInc(*this, _direction); |
|
553 |
return *this; |
|
552 |
_graph->nextInc(*this, _direction); |
|
553 |
return *this; |
|
554 | 554 |
} |
555 | 555 |
}; |
556 | 556 |
|
557 | 557 |
/// \brief Base node of the iterator |
558 | 558 |
/// |
559 | 559 |
/// Returns the base node (ie. the source in this case) of the iterator |
... | ... |
@@ -595,80 +595,80 @@ |
595 | 595 |
return edge._direction ? v(edge) : u(edge); |
596 | 596 |
} |
597 | 597 |
|
598 | 598 |
// Mappable extension |
599 | 599 |
|
600 | 600 |
template <typename _Value> |
601 |
class NodeMap |
|
601 |
class NodeMap |
|
602 | 602 |
: public MapExtender<DefaultMap<Graph, Node, _Value> > { |
603 | 603 |
public: |
604 | 604 |
typedef GraphExtender Graph; |
605 | 605 |
typedef MapExtender<DefaultMap<Graph, Node, _Value> > Parent; |
606 | 606 |
|
607 |
NodeMap(const Graph& graph) |
|
608 |
: Parent(graph) {} |
|
609 |
NodeMap(const Graph& graph, const _Value& value) |
|
610 |
: Parent(graph, value) {} |
|
607 |
NodeMap(const Graph& graph) |
|
608 |
: Parent(graph) {} |
|
609 |
NodeMap(const Graph& graph, const _Value& value) |
|
610 |
: Parent(graph, value) {} |
|
611 | 611 |
|
612 | 612 |
NodeMap& operator=(const NodeMap& cmap) { |
613 |
|
|
613 |
return operator=<NodeMap>(cmap); |
|
614 | 614 |
} |
615 | 615 |
|
616 | 616 |
template <typename CMap> |
617 | 617 |
NodeMap& operator=(const CMap& cmap) { |
618 | 618 |
Parent::operator=(cmap); |
619 |
|
|
619 |
return *this; |
|
620 | 620 |
} |
621 | 621 |
|
622 | 622 |
}; |
623 | 623 |
|
624 | 624 |
template <typename _Value> |
625 |
class ArcMap |
|
625 |
class ArcMap |
|
626 | 626 |
: public MapExtender<DefaultMap<Graph, Arc, _Value> > { |
627 | 627 |
public: |
628 | 628 |
typedef GraphExtender Graph; |
629 | 629 |
typedef MapExtender<DefaultMap<Graph, Arc, _Value> > Parent; |
630 | 630 |
|
631 |
ArcMap(const Graph& graph) |
|
632 |
: Parent(graph) {} |
|
633 |
ArcMap(const Graph& graph, const _Value& value) |
|
634 |
: Parent(graph, value) {} |
|
631 |
ArcMap(const Graph& graph) |
|
632 |
: Parent(graph) {} |
|
633 |
ArcMap(const Graph& graph, const _Value& value) |
|
634 |
: Parent(graph, value) {} |
|
635 | 635 |
|
636 | 636 |
ArcMap& operator=(const ArcMap& cmap) { |
637 |
|
|
637 |
return operator=<ArcMap>(cmap); |
|
638 | 638 |
} |
639 | 639 |
|
640 | 640 |
template <typename CMap> |
641 | 641 |
ArcMap& operator=(const CMap& cmap) { |
642 | 642 |
Parent::operator=(cmap); |
643 |
|
|
643 |
return *this; |
|
644 | 644 |
} |
645 | 645 |
}; |
646 | 646 |
|
647 | 647 |
|
648 | 648 |
template <typename _Value> |
649 |
class EdgeMap |
|
649 |
class EdgeMap |
|
650 | 650 |
: public MapExtender<DefaultMap<Graph, Edge, _Value> > { |
651 | 651 |
public: |
652 | 652 |
typedef GraphExtender Graph; |
653 | 653 |
typedef MapExtender<DefaultMap<Graph, Edge, _Value> > Parent; |
654 | 654 |
|
655 |
EdgeMap(const Graph& graph) |
|
656 |
: Parent(graph) {} |
|
655 |
EdgeMap(const Graph& graph) |
|
656 |
: Parent(graph) {} |
|
657 | 657 |
|
658 |
EdgeMap(const Graph& graph, const _Value& value) |
|
659 |
: Parent(graph, value) {} |
|
658 |
EdgeMap(const Graph& graph, const _Value& value) |
|
659 |
: Parent(graph, value) {} |
|
660 | 660 |
|
661 | 661 |
EdgeMap& operator=(const EdgeMap& cmap) { |
662 |
|
|
662 |
return operator=<EdgeMap>(cmap); |
|
663 | 663 |
} |
664 | 664 |
|
665 | 665 |
template <typename CMap> |
666 | 666 |
EdgeMap& operator=(const CMap& cmap) { |
667 | 667 |
Parent::operator=(cmap); |
668 |
|
|
668 |
return *this; |
|
669 | 669 |
} |
670 | 670 |
|
671 | 671 |
}; |
672 | 672 |
|
673 | 673 |
// Alteration extension |
674 | 674 |
|
... | ... |
@@ -680,71 +680,71 @@ |
680 | 680 |
|
681 | 681 |
Edge addEdge(const Node& from, const Node& to) { |
682 | 682 |
Edge edge = Parent::addEdge(from, to); |
683 | 683 |
notifier(Edge()).add(edge); |
684 | 684 |
std::vector<Arc> ev; |
685 | 685 |
ev.push_back(Parent::direct(edge, true)); |
686 |
ev.push_back(Parent::direct(edge, false)); |
|
686 |
ev.push_back(Parent::direct(edge, false)); |
|
687 | 687 |
notifier(Arc()).add(ev); |
688 | 688 |
return edge; |
689 | 689 |
} |
690 |
|
|
690 |
|
|
691 | 691 |
void clear() { |
692 | 692 |
notifier(Arc()).clear(); |
693 | 693 |
notifier(Edge()).clear(); |
694 | 694 |
notifier(Node()).clear(); |
695 | 695 |
Parent::clear(); |
696 | 696 |
} |
697 | 697 |
|
698 | 698 |
template <typename Graph, typename NodeRefMap, typename EdgeRefMap> |
699 |
void build(const Graph& graph, NodeRefMap& nodeRef, |
|
699 |
void build(const Graph& graph, NodeRefMap& nodeRef, |
|
700 | 700 |
EdgeRefMap& edgeRef) { |
701 | 701 |
Parent::build(graph, nodeRef, edgeRef); |
702 | 702 |
notifier(Node()).build(); |
703 | 703 |
notifier(Edge()).build(); |
704 | 704 |
notifier(Arc()).build(); |
705 | 705 |
} |
706 | 706 |
|
707 | 707 |
void erase(const Node& node) { |
708 | 708 |
Arc arc; |
709 | 709 |
Parent::firstOut(arc, node); |
710 | 710 |
while (arc != INVALID ) { |
711 |
erase(arc); |
|
712 |
Parent::firstOut(arc, node); |
|
713 |
|
|
711 |
erase(arc); |
|
712 |
Parent::firstOut(arc, node); |
|
713 |
} |
|
714 | 714 |
|
715 | 715 |
Parent::firstIn(arc, node); |
716 | 716 |
while (arc != INVALID ) { |
717 |
erase(arc); |
|
718 |
Parent::firstIn(arc, node); |
|
717 |
erase(arc); |
|
718 |
Parent::firstIn(arc, node); |
|
719 | 719 |
} |
720 | 720 |
|
721 | 721 |
notifier(Node()).erase(node); |
722 | 722 |
Parent::erase(node); |
723 | 723 |
} |
724 | 724 |
|
725 | 725 |
void erase(const Edge& edge) { |
726 | 726 |
std::vector<Arc> av; |
727 | 727 |
av.push_back(Parent::direct(edge, true)); |
728 |
av.push_back(Parent::direct(edge, false)); |
|
728 |
av.push_back(Parent::direct(edge, false)); |
|
729 | 729 |
notifier(Arc()).erase(av); |
730 | 730 |
notifier(Edge()).erase(edge); |
731 | 731 |
Parent::erase(edge); |
732 | 732 |
} |
733 | 733 |
|
734 | 734 |
GraphExtender() { |
735 |
node_notifier.setContainer(*this); |
|
735 |
node_notifier.setContainer(*this); |
|
736 | 736 |
arc_notifier.setContainer(*this); |
737 | 737 |
edge_notifier.setContainer(*this); |
738 |
} |
|
738 |
} |
|
739 | 739 |
|
740 | 740 |
~GraphExtender() { |
741 | 741 |
edge_notifier.clear(); |
742 | 742 |
arc_notifier.clear(); |
743 |
node_notifier.clear(); |
|
744 |
} |
|
743 |
node_notifier.clear(); |
|
744 |
} |
|
745 | 745 |
|
746 | 746 |
}; |
747 | 747 |
|
748 | 748 |
} |
749 | 749 |
|
750 | 750 |
#endif |
1 |
/* -*- C++ -*- |
|
1 |
/* -*- mode: C++; indent-tabs-mode: nil; -*- |
|
2 | 2 |
* |
3 |
* This file is a part of LEMON, a generic C++ optimization library |
|
3 |
* This file is a part of LEMON, a generic C++ optimization library. |
|
4 | 4 |
* |
5 | 5 |
* Copyright (C) 2003-2008 |
6 | 6 |
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
7 | 7 |
* (Egervary Research Group on Combinatorial Optimization, EGRES). |
8 | 8 |
* |
9 | 9 |
* Permission to use, modify and distribute this software is granted |
... | ... |
@@ -31,13 +31,13 @@ |
31 | 31 |
struct Invalid { |
32 | 32 |
public: |
33 | 33 |
bool operator==(Invalid) { return true; } |
34 | 34 |
bool operator!=(Invalid) { return false; } |
35 | 35 |
bool operator< (Invalid) { return false; } |
36 | 36 |
}; |
37 |
|
|
37 |
|
|
38 | 38 |
/// \brief Invalid iterators. |
39 | 39 |
/// |
40 | 40 |
/// \ref Invalid is a global type that converts to each iterator |
41 | 41 |
/// in such a way that the value of the target iterator will be invalid. |
42 | 42 |
|
43 | 43 |
//Some people didn't like this: |
... | ... |
@@ -49,7 +49,7 @@ |
49 | 49 |
extern const Invalid INVALID; |
50 | 50 |
#endif |
51 | 51 |
|
52 | 52 |
} //namespace lemon |
53 | 53 |
|
54 | 54 |
#endif |
55 |
|
|
55 |
1 |
/* -*- C++ -*- |
|
1 |
/* -*- mode: C++; indent-tabs-mode: nil; -*- |
|
2 | 2 |
* |
3 |
* This file is a part of LEMON, a generic C++ optimization library |
|
3 |
* This file is a part of LEMON, a generic C++ optimization library. |
|
4 | 4 |
* |
5 | 5 |
* Copyright (C) 2003-2008 |
6 | 6 |
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
7 | 7 |
* (Egervary Research Group on Combinatorial Optimization, EGRES). |
8 | 8 |
* |
9 | 9 |
* Permission to use, modify and distribute this software is granted |
... | ... |
@@ -29,13 +29,13 @@ |
29 | 29 |
///\file |
30 | 30 |
///\brief Extenders for iterable maps. |
31 | 31 |
|
32 | 32 |
namespace lemon { |
33 | 33 |
|
34 | 34 |
/// \ingroup graphbits |
35 |
/// |
|
35 |
/// |
|
36 | 36 |
/// \brief Extender for maps |
37 | 37 |
template <typename _Map> |
38 | 38 |
class MapExtender : public _Map { |
39 | 39 |
public: |
40 | 40 |
|
41 | 41 |
typedef _Map Parent; |
... | ... |
@@ -53,127 +53,127 @@ |
53 | 53 |
|
54 | 54 |
friend class MapIt; |
55 | 55 |
friend class ConstMapIt; |
56 | 56 |
|
57 | 57 |
public: |
58 | 58 |
|
59 |
MapExtender(const Graph& graph) |
|
59 |
MapExtender(const Graph& graph) |
|
60 | 60 |
: Parent(graph) {} |
61 | 61 |
|
62 |
MapExtender(const Graph& graph, const Value& value) |
|
62 |
MapExtender(const Graph& graph, const Value& value) |
|
63 | 63 |
: Parent(graph, value) {} |
64 | 64 |
|
65 | 65 |
MapExtender& operator=(const MapExtender& cmap) { |
66 | 66 |
return operator=<MapExtender>(cmap); |
67 | 67 |
} |
68 | 68 |
|
69 | 69 |
template <typename CMap> |
70 | 70 |
MapExtender& operator=(const CMap& cmap) { |
71 | 71 |
Parent::operator=(cmap); |
72 | 72 |
return *this; |
73 |
} |
|
73 |
} |
|
74 | 74 |
|
75 | 75 |
class MapIt : public Item { |
76 | 76 |
public: |
77 |
|
|
77 |
|
|
78 | 78 |
typedef Item Parent; |
79 | 79 |
typedef typename Map::Value Value; |
80 |
|
|
80 |
|
|
81 | 81 |
MapIt() {} |
82 | 82 |
|
83 | 83 |
MapIt(Invalid i) : Parent(i) { } |
84 | 84 |
|
85 | 85 |
explicit MapIt(Map& _map) : map(_map) { |
86 | 86 |
map.notifier()->first(*this); |
87 | 87 |
} |
88 | 88 |
|
89 |
MapIt(const Map& _map, const Item& item) |
|
90 |
: Parent(item), map(_map) {} |
|
89 |
MapIt(const Map& _map, const Item& item) |
|
90 |
: Parent(item), map(_map) {} |
|
91 | 91 |
|
92 |
MapIt& operator++() { |
|
93 |
map.notifier()->next(*this); |
|
94 |
|
|
92 |
MapIt& operator++() { |
|
93 |
map.notifier()->next(*this); |
|
94 |
return *this; |
|
95 | 95 |
} |
96 |
|
|
96 |
|
|
97 | 97 |
typename MapTraits<Map>::ConstReturnValue operator*() const { |
98 |
|
|
98 |
return map[*this]; |
|
99 | 99 |
} |
100 | 100 |
|
101 | 101 |
typename MapTraits<Map>::ReturnValue operator*() { |
102 |
|
|
102 |
return map[*this]; |
|
103 | 103 |
} |
104 |
|
|
104 |
|
|
105 | 105 |
void set(const Value& value) { |
106 |
|
|
106 |
map.set(*this, value); |
|
107 | 107 |
} |
108 |
|
|
108 |
|
|
109 | 109 |
protected: |
110 | 110 |
Map& map; |
111 |
|
|
111 |
|
|
112 | 112 |
}; |
113 | 113 |
|
114 | 114 |
class ConstMapIt : public Item { |
115 | 115 |
public: |
116 | 116 |
|
117 | 117 |
typedef Item Parent; |
118 | 118 |
|
119 | 119 |
typedef typename Map::Value Value; |
120 |
|
|
120 |
|
|
121 | 121 |
ConstMapIt() {} |
122 | 122 |
|
123 | 123 |
ConstMapIt(Invalid i) : Parent(i) { } |
124 | 124 |
|
125 | 125 |
explicit ConstMapIt(Map& _map) : map(_map) { |
126 | 126 |
map.notifier()->first(*this); |
127 | 127 |
} |
128 | 128 |
|
129 |
ConstMapIt(const Map& _map, const Item& item) |
|
130 |
: Parent(item), map(_map) {} |
|
129 |
ConstMapIt(const Map& _map, const Item& item) |
|
130 |
: Parent(item), map(_map) {} |
|
131 | 131 |
|
132 |
ConstMapIt& operator++() { |
|
133 |
map.notifier()->next(*this); |
|
134 |
|
|
132 |
ConstMapIt& operator++() { |
|
133 |
map.notifier()->next(*this); |
|
134 |
return *this; |
|
135 | 135 |
} |
136 | 136 |
|
137 | 137 |
typename MapTraits<Map>::ConstReturnValue operator*() const { |
138 |
|
|
138 |
return map[*this]; |
|
139 | 139 |
} |
140 | 140 |
|
141 | 141 |
protected: |
142 | 142 |
const Map& map; |
143 | 143 |
}; |
144 | 144 |
|
145 | 145 |
class ItemIt : public Item { |
146 | 146 |
public: |
147 |
|
|
147 |
|
|
148 | 148 |
typedef Item Parent; |
149 |
|
|
149 |
|
|
150 | 150 |
ItemIt() {} |
151 | 151 |
|
152 | 152 |
ItemIt(Invalid i) : Parent(i) { } |
153 | 153 |
|
154 | 154 |
explicit ItemIt(Map& _map) : map(_map) { |
155 | 155 |
map.notifier()->first(*this); |
156 | 156 |
} |
157 | 157 |
|
158 |
ItemIt(const Map& _map, const Item& item) |
|
159 |
: Parent(item), map(_map) {} |
|
158 |
ItemIt(const Map& _map, const Item& item) |
|
159 |
: Parent(item), map(_map) {} |
|
160 | 160 |
|
161 |
ItemIt& operator++() { |
|
162 |
map.notifier()->next(*this); |
|
163 |
|
|
161 |
ItemIt& operator++() { |
|
162 |
map.notifier()->next(*this); |
|
163 |
return *this; |
|
164 | 164 |
} |
165 | 165 |
|
166 | 166 |
protected: |
167 | 167 |
const Map& map; |
168 |
|
|
168 |
|
|
169 | 169 |
}; |
170 | 170 |
}; |
171 | 171 |
|
172 | 172 |
/// \ingroup graphbits |
173 |
/// |
|
173 |
/// |
|
174 | 174 |
/// \brief Extender for maps which use a subset of the items. |
175 | 175 |
template <typename _Graph, typename _Map> |
176 | 176 |
class SubMapExtender : public _Map { |
177 | 177 |
public: |
178 | 178 |
|
179 | 179 |
typedef _Map Parent; |
... | ... |
@@ -191,16 +191,16 @@ |
191 | 191 |
|
192 | 192 |
friend class MapIt; |
193 | 193 |
friend class ConstMapIt; |
194 | 194 |
|
195 | 195 |
public: |
196 | 196 |
|
197 |
SubMapExtender(const Graph& _graph) |
|
197 |
SubMapExtender(const Graph& _graph) |
|
198 | 198 |
: Parent(_graph), graph(_graph) {} |
199 | 199 |
|
200 |
SubMapExtender(const Graph& _graph, const Value& _value) |
|
200 |
SubMapExtender(const Graph& _graph, const Value& _value) |
|
201 | 201 |
: Parent(_graph, _value), graph(_graph) {} |
202 | 202 |
|
203 | 203 |
SubMapExtender& operator=(const SubMapExtender& cmap) { |
204 | 204 |
return operator=<MapExtender>(cmap); |
205 | 205 |
} |
206 | 206 |
|
... | ... |
@@ -209,113 +209,113 @@ |
209 | 209 |
checkConcept<concepts::ReadMap<Key, Value>, CMap>(); |
210 | 210 |
Item it; |
211 | 211 |
for (graph.first(it); it != INVALID; graph.next(it)) { |
212 | 212 |
Parent::set(it, cmap[it]); |
213 | 213 |
} |
214 | 214 |
return *this; |
215 |
} |
|
215 |
} |
|
216 | 216 |
|
217 | 217 |
class MapIt : public Item { |
218 | 218 |
public: |
219 |
|
|
219 |
|
|
220 | 220 |
typedef Item Parent; |
221 | 221 |
typedef typename Map::Value Value; |
222 |
|
|
222 |
|
|
223 | 223 |
MapIt() {} |
224 | 224 |
|
225 | 225 |
MapIt(Invalid i) : Parent(i) { } |
226 | 226 |
|
227 | 227 |
explicit MapIt(Map& _map) : map(_map) { |
228 | 228 |
map.graph.first(*this); |
229 | 229 |
} |
230 | 230 |
|
231 |
MapIt(const Map& _map, const Item& item) |
|
232 |
: Parent(item), map(_map) {} |
|
231 |
MapIt(const Map& _map, const Item& item) |
|
232 |
: Parent(item), map(_map) {} |
|
233 | 233 |
|
234 |
MapIt& operator++() { |
|
235 |
map.graph.next(*this); |
|
236 |
|
|
234 |
MapIt& operator++() { |
|
235 |
map.graph.next(*this); |
|
236 |
return *this; |
|
237 | 237 |
} |
238 |
|
|
238 |
|
|
239 | 239 |
typename MapTraits<Map>::ConstReturnValue operator*() const { |
240 |
|
|
240 |
return map[*this]; |
|
241 | 241 |
} |
242 | 242 |
|
243 | 243 |
typename MapTraits<Map>::ReturnValue operator*() { |
244 |
|
|
244 |
return map[*this]; |
|
245 | 245 |
} |
246 |
|
|
246 |
|
|
247 | 247 |
void set(const Value& value) { |
248 |
|
|
248 |
map.set(*this, value); |
|
249 | 249 |
} |
250 |
|
|
250 |
|
|
251 | 251 |
protected: |
252 | 252 |
Map& map; |
253 |
|
|
253 |
|
|
254 | 254 |
}; |
255 | 255 |
|
256 | 256 |
class ConstMapIt : public Item { |
257 | 257 |
public: |
258 | 258 |
|
259 | 259 |
typedef Item Parent; |
260 | 260 |
|
261 | 261 |
typedef typename Map::Value Value; |
262 |
|
|
262 |
|
|
263 | 263 |
ConstMapIt() {} |
264 | 264 |
|
265 | 265 |
ConstMapIt(Invalid i) : Parent(i) { } |
266 | 266 |
|
267 | 267 |
explicit ConstMapIt(Map& _map) : map(_map) { |
268 | 268 |
map.graph.first(*this); |
269 | 269 |
} |
270 | 270 |
|
271 |
ConstMapIt(const Map& _map, const Item& item) |
|
272 |
: Parent(item), map(_map) {} |
|
271 |
ConstMapIt(const Map& _map, const Item& item) |
|
272 |
: Parent(item), map(_map) {} |
|
273 | 273 |
|
274 |
ConstMapIt& operator++() { |
|
275 |
map.graph.next(*this); |
|
276 |
|
|
274 |
ConstMapIt& operator++() { |
|
275 |
map.graph.next(*this); |
|
276 |
return *this; |
|
277 | 277 |
} |
278 | 278 |
|
279 | 279 |
typename MapTraits<Map>::ConstReturnValue operator*() const { |
280 |
|
|
280 |
return map[*this]; |
|
281 | 281 |
} |
282 | 282 |
|
283 | 283 |
protected: |
284 | 284 |
const Map& map; |
285 | 285 |
}; |
286 | 286 |
|
287 | 287 |
class ItemIt : public Item { |
288 | 288 |
public: |
289 |
|
|
289 |
|
|
290 | 290 |
typedef Item Parent; |
291 |
|
|
291 |
|
|
292 | 292 |
ItemIt() {} |
293 | 293 |
|
294 | 294 |
ItemIt(Invalid i) : Parent(i) { } |
295 | 295 |
|
296 | 296 |
explicit ItemIt(Map& _map) : map(_map) { |
297 | 297 |
map.graph.first(*this); |
298 | 298 |
} |
299 | 299 |
|
300 |
ItemIt(const Map& _map, const Item& item) |
|
301 |
: Parent(item), map(_map) {} |
|
300 |
ItemIt(const Map& _map, const Item& item) |
|
301 |
: Parent(item), map(_map) {} |
|
302 | 302 |
|
303 |
ItemIt& operator++() { |
|
304 |
map.graph.next(*this); |
|
305 |
|
|
303 |
ItemIt& operator++() { |
|
304 |
map.graph.next(*this); |
|
305 |
return *this; |
|
306 | 306 |
} |
307 | 307 |
|
308 | 308 |
protected: |
309 | 309 |
const Map& map; |
310 |
|
|
310 |
|
|
311 | 311 |
}; |
312 |
|
|
312 |
|
|
313 | 313 |
private: |
314 | 314 |
|
315 | 315 |
const Graph& graph; |
316 |
|
|
316 |
|
|
317 | 317 |
}; |
318 | 318 |
|
319 | 319 |
} |
320 | 320 |
|
321 | 321 |
#endif |
1 |
/* -*- C++ -*- |
|
1 |
/* -*- mode: C++; indent-tabs-mode: nil; -*- |
|
2 | 2 |
* |
3 |
* This file is a part of LEMON, a generic C++ optimization library |
|
3 |
* This file is a part of LEMON, a generic C++ optimization library. |
|
4 | 4 |
* |
5 | 5 |
* Copyright (C) 2003-2008 |
6 | 6 |
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
7 | 7 |
* (Egervary Research Group on Combinatorial Optimization, EGRES). |
8 | 8 |
* |
9 | 9 |
* Permission to use, modify and distribute this software is granted |
... | ... |
@@ -50,13 +50,13 @@ |
50 | 50 |
} |
51 | 51 |
|
52 | 52 |
class RevArcIt { |
53 | 53 |
public: |
54 | 54 |
RevArcIt() {} |
55 | 55 |
RevArcIt(Invalid) : path(0), current(INVALID) {} |
56 |
RevArcIt(const PredMapPath& _path) |
|
56 |
RevArcIt(const PredMapPath& _path) |
|
57 | 57 |
: path(&_path), current(_path.target) { |
58 | 58 |
if (path->predMap[current] == INVALID) current = INVALID; |
59 | 59 |
} |
60 | 60 |
|
61 | 61 |
operator const typename Digraph::Arc() const { |
62 | 62 |
return path->predMap[current]; |
... | ... |
@@ -65,24 +65,24 @@ |
65 | 65 |
RevArcIt& operator++() { |
66 | 66 |
current = path->digraph.source(path->predMap[current]); |
67 | 67 |
if (path->predMap[current] == INVALID) current = INVALID; |
68 | 68 |
return *this; |
69 | 69 |
} |
70 | 70 |
|
71 |
bool operator==(const RevArcIt& e) const { |
|
72 |
return current == e.current; |
|
71 |
bool operator==(const RevArcIt& e) const { |
|
72 |
return current == e.current; |
|
73 | 73 |
} |
74 | 74 |
|
75 | 75 |
bool operator!=(const RevArcIt& e) const { |
76 |
return current != e.current; |
|
76 |
return current != e.current; |
|
77 | 77 |
} |
78 | 78 |
|
79 |
bool operator<(const RevArcIt& e) const { |
|
80 |
return current < e.current; |
|
79 |
bool operator<(const RevArcIt& e) const { |
|
80 |
return current < e.current; |
|
81 | 81 |
} |
82 |
|
|
82 |
|
|
83 | 83 |
private: |
84 | 84 |
const PredMapPath* path; |
85 | 85 |
typename Digraph::Node current; |
86 | 86 |
}; |
87 | 87 |
|
88 | 88 |
private: |
... | ... |
@@ -98,17 +98,17 @@ |
98 | 98 |
typedef True RevPathTag; |
99 | 99 |
|
100 | 100 |
typedef _Digraph Digraph; |
101 | 101 |
typedef typename Digraph::Arc Arc; |
102 | 102 |
typedef _PredMatrixMap PredMatrixMap; |
103 | 103 |
|
104 |
PredMatrixMapPath(const Digraph& _digraph, |
|
104 |
PredMatrixMapPath(const Digraph& _digraph, |
|
105 | 105 |
const PredMatrixMap& _predMatrixMap, |
106 |
typename Digraph::Node _source, |
|
106 |
typename Digraph::Node _source, |
|
107 | 107 |
typename Digraph::Node _target) |
108 |
: digraph(_digraph), predMatrixMap(_predMatrixMap), |
|
108 |
: digraph(_digraph), predMatrixMap(_predMatrixMap), |
|
109 | 109 |
source(_source), target(_target) {} |
110 | 110 |
|
111 | 111 |
int length() const { |
112 | 112 |
int len = 0; |
113 | 113 |
typename Digraph::Node node = target; |
114 | 114 |
typename Digraph::Arc arc; |
... | ... |
@@ -124,42 +124,42 @@ |
124 | 124 |
} |
125 | 125 |
|
126 | 126 |
class RevArcIt { |
127 | 127 |
public: |
128 | 128 |
RevArcIt() {} |
129 | 129 |
RevArcIt(Invalid) : path(0), current(INVALID) {} |
130 |
RevArcIt(const PredMatrixMapPath& _path) |
|
130 |
RevArcIt(const PredMatrixMapPath& _path) |
|
131 | 131 |
: path(&_path), current(_path.target) { |
132 |
if (path->predMatrixMap(path->source, current) == INVALID) |
|
132 |
if (path->predMatrixMap(path->source, current) == INVALID) |
|
133 | 133 |
current = INVALID; |
134 | 134 |
} |
135 | 135 |
|
136 | 136 |
operator const typename Digraph::Arc() const { |
137 | 137 |
return path->predMatrixMap(path->source, current); |
138 | 138 |
} |
139 | 139 |
|
140 | 140 |
RevArcIt& operator++() { |
141 |
current = |
|
141 |
current = |
|
142 | 142 |
path->digraph.source(path->predMatrixMap(path->source, current)); |
143 |
if (path->predMatrixMap(path->source, current) == INVALID) |
|
143 |
if (path->predMatrixMap(path->source, current) == INVALID) |
|
144 | 144 |
current = INVALID; |
145 | 145 |
return *this; |
146 | 146 |
} |
147 | 147 |
|
148 |
bool operator==(const RevArcIt& e) const { |
|
149 |
return current == e.current; |
|
148 |
bool operator==(const RevArcIt& e) const { |
|
149 |
return current == e.current; |
|
150 | 150 |
} |
151 | 151 |
|
152 | 152 |
bool operator!=(const RevArcIt& e) const { |
153 |
return current != e.current; |
|
153 |
return current != e.current; |
|
154 | 154 |
} |
155 | 155 |
|
156 |
bool operator<(const RevArcIt& e) const { |
|
157 |
return current < e.current; |
|
156 |
bool operator<(const RevArcIt& e) const { |
|
157 |
return current < e.current; |
|
158 | 158 |
} |
159 |
|
|
159 |
|
|
160 | 160 |
private: |
161 | 161 |
const PredMatrixMapPath* path; |
162 | 162 |
typename Digraph::Node current; |
163 | 163 |
}; |
164 | 164 |
|
165 | 165 |
private: |
1 |
|
|
2 |
/* -*- C++ -*- |
|
1 |
/* -*- mode: C++; indent-tabs-mode: nil; -*- |
|
3 | 2 |
* |
4 |
* This file is a part of LEMON, a generic C++ optimization library |
|
3 |
* This file is a part of LEMON, a generic C++ optimization library. |
|
5 | 4 |
* |
6 | 5 |
* Copyright (C) 2003-2008 |
7 | 6 |
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
8 | 7 |
* (Egervary Research Group on Combinatorial Optimization, EGRES). |
9 | 8 |
* |
10 | 9 |
* Permission to use, modify and distribute this software is granted |
... | ... |
@@ -26,122 +25,122 @@ |
26 | 25 |
///\brief Traits for graphs and maps |
27 | 26 |
/// |
28 | 27 |
|
29 | 28 |
namespace lemon { |
30 | 29 |
template <typename _Graph, typename _Item> |
31 | 30 |
class ItemSetTraits {}; |
32 |
|
|
31 |
|
|
33 | 32 |
|
34 | 33 |
template <typename Graph, typename Enable = void> |
35 | 34 |
struct NodeNotifierIndicator { |
36 | 35 |
typedef InvalidType Type; |
37 | 36 |
}; |
38 | 37 |
template <typename Graph> |
39 | 38 |
struct NodeNotifierIndicator< |
40 |
Graph, |
|
39 |
Graph, |
|
41 | 40 |
typename enable_if<typename Graph::NodeNotifier::Notifier, void>::type |
42 |
> { |
|
41 |
> { |
|
43 | 42 |
typedef typename Graph::NodeNotifier Type; |
44 | 43 |
}; |
45 | 44 |
|
46 | 45 |
template <typename _Graph> |
47 | 46 |
class ItemSetTraits<_Graph, typename _Graph::Node> { |
48 | 47 |
public: |
49 |
|
|
48 |
|
|
50 | 49 |
typedef _Graph Graph; |
51 | 50 |
|
52 | 51 |
typedef typename Graph::Node Item; |
53 | 52 |
typedef typename Graph::NodeIt ItemIt; |
54 | 53 |
|
55 | 54 |
typedef typename NodeNotifierIndicator<Graph>::Type ItemNotifier; |
56 | 55 |
|
57 | 56 |
template <typename _Value> |
58 | 57 |
class Map : public Graph::template NodeMap<_Value> { |
59 | 58 |
public: |
60 |
typedef typename Graph::template NodeMap<_Value> Parent; |
|
61 |
typedef typename Graph::template NodeMap<_Value> Type; |
|
59 |
typedef typename Graph::template NodeMap<_Value> Parent; |
|
60 |
typedef typename Graph::template NodeMap<_Value> Type; |
|
62 | 61 |
typedef typename Parent::Value Value; |
63 | 62 |
|
64 | 63 |
Map(const Graph& _digraph) : Parent(_digraph) {} |
65 |
Map(const Graph& _digraph, const Value& _value) |
|
66 |
: Parent(_digraph, _value) {} |
|
64 |
Map(const Graph& _digraph, const Value& _value) |
|
65 |
: Parent(_digraph, _value) {} |
|
67 | 66 |
|
68 | 67 |
}; |
69 | 68 |
|
70 | 69 |
}; |
71 | 70 |
|
72 | 71 |
template <typename Graph, typename Enable = void> |
73 | 72 |
struct ArcNotifierIndicator { |
74 | 73 |
typedef InvalidType Type; |
75 | 74 |
}; |
76 | 75 |
template <typename Graph> |
77 | 76 |
struct ArcNotifierIndicator< |
78 |
Graph, |
|
77 |
Graph, |
|
79 | 78 |
typename enable_if<typename Graph::ArcNotifier::Notifier, void>::type |
80 |
> { |
|
79 |
> { |
|
81 | 80 |
typedef typename Graph::ArcNotifier Type; |
82 | 81 |
}; |
83 | 82 |
|
84 | 83 |
template <typename _Graph> |
85 | 84 |
class ItemSetTraits<_Graph, typename _Graph::Arc> { |
86 | 85 |
public: |
87 |
|
|
86 |
|
|
88 | 87 |
typedef _Graph Graph; |
89 | 88 |
|
90 | 89 |
typedef typename Graph::Arc Item; |
91 | 90 |
typedef typename Graph::ArcIt ItemIt; |
92 | 91 |
|
93 | 92 |
typedef typename ArcNotifierIndicator<Graph>::Type ItemNotifier; |
94 | 93 |
|
95 | 94 |
template <typename _Value> |
96 | 95 |
class Map : public Graph::template ArcMap<_Value> { |
97 | 96 |
public: |
98 |
typedef typename Graph::template ArcMap<_Value> Parent; |
|
99 |
typedef typename Graph::template ArcMap<_Value> Type; |
|
97 |
typedef typename Graph::template ArcMap<_Value> Parent; |
|
98 |
typedef typename Graph::template ArcMap<_Value> Type; |
|
100 | 99 |
typedef typename Parent::Value Value; |
101 | 100 |
|
102 | 101 |
Map(const Graph& _digraph) : Parent(_digraph) {} |
103 |
Map(const Graph& _digraph, const Value& _value) |
|
104 |
: Parent(_digraph, _value) {} |
|
102 |
Map(const Graph& _digraph, const Value& _value) |
|
103 |
: Parent(_digraph, _value) {} |
|
105 | 104 |
}; |
106 | 105 |
|
107 | 106 |
}; |
108 | 107 |
|
109 | 108 |
template <typename Graph, typename Enable = void> |
110 | 109 |
struct EdgeNotifierIndicator { |
111 | 110 |
typedef InvalidType Type; |
112 | 111 |
}; |
113 | 112 |
template <typename Graph> |
114 | 113 |
struct EdgeNotifierIndicator< |
115 |
Graph, |
|
114 |
Graph, |
|
116 | 115 |
typename enable_if<typename Graph::EdgeNotifier::Notifier, void>::type |
117 |
> { |
|
116 |
> { |
|
118 | 117 |
typedef typename Graph::EdgeNotifier Type; |
119 | 118 |
}; |
120 | 119 |
|
121 | 120 |
template <typename _Graph> |
122 | 121 |
class ItemSetTraits<_Graph, typename _Graph::Edge> { |
123 | 122 |
public: |
124 |
|
|
123 |
|
|
125 | 124 |
typedef _Graph Graph; |
126 | 125 |
|
127 | 126 |
typedef typename Graph::Edge Item; |
128 | 127 |
typedef typename Graph::EdgeIt ItemIt; |
129 | 128 |
|
130 | 129 |
typedef typename EdgeNotifierIndicator<Graph>::Type ItemNotifier; |
131 | 130 |
|
132 | 131 |
template <typename _Value> |
133 | 132 |
class Map : public Graph::template EdgeMap<_Value> { |
134 | 133 |
public: |
135 |
typedef typename Graph::template EdgeMap<_Value> Parent; |
|
136 |
typedef typename Graph::template EdgeMap<_Value> Type; |
|
134 |
typedef typename Graph::template EdgeMap<_Value> Parent; |
|
135 |
typedef typename Graph::template EdgeMap<_Value> Type; |
|
137 | 136 |
typedef typename Parent::Value Value; |
138 | 137 |
|
139 | 138 |
Map(const Graph& _digraph) : Parent(_digraph) {} |
140 |
Map(const Graph& _digraph, const Value& _value) |
|
141 |
: Parent(_digraph, _value) {} |
|
139 |
Map(const Graph& _digraph, const Value& _value) |
|
140 |
: Parent(_digraph, _value) {} |
|
142 | 141 |
}; |
143 | 142 |
|
144 | 143 |
}; |
145 | 144 |
|
146 | 145 |
template <typename Map, typename Enable = void> |
147 | 146 |
struct MapTraits { |
... | ... |
@@ -153,23 +152,23 @@ |
153 | 152 |
typedef Value ConstReturnValue; |
154 | 153 |
typedef Value ReturnValue; |
155 | 154 |
}; |
156 | 155 |
|
157 | 156 |
template <typename Map> |
158 | 157 |
struct MapTraits< |
159 |
Map, typename enable_if<typename Map::ReferenceMapTag, void>::type > |
|
158 |
Map, typename enable_if<typename Map::ReferenceMapTag, void>::type > |
|
160 | 159 |
{ |
161 | 160 |
typedef True ReferenceMapTag; |
162 |
|
|
161 |
|
|
163 | 162 |
typedef typename Map::Key Key; |
164 | 163 |
typedef typename Map::Value Value; |
165 | 164 |
|
166 | 165 |
typedef typename Map::ConstReference ConstReturnValue; |
167 | 166 |
typedef typename Map::Reference ReturnValue; |
168 | 167 |
|
169 |
typedef typename Map::ConstReference ConstReference; |
|
168 |
typedef typename Map::ConstReference ConstReference; |
|
170 | 169 |
typedef typename Map::Reference Reference; |
171 | 170 |
}; |
172 | 171 |
|
173 | 172 |
template <typename MatrixMap, typename Enable = void> |
174 | 173 |
struct MatrixMapTraits { |
175 | 174 |
typedef False ReferenceMapTag; |
... | ... |
@@ -181,90 +180,90 @@ |
181 | 180 |
typedef Value ConstReturnValue; |
182 | 181 |
typedef Value ReturnValue; |
183 | 182 |
}; |
184 | 183 |
|
185 | 184 |
template <typename MatrixMap> |
186 | 185 |
struct MatrixMapTraits< |
187 |
MatrixMap, typename enable_if<typename MatrixMap::ReferenceMapTag, |
|
188 |
void>::type > |
|
186 |
MatrixMap, typename enable_if<typename MatrixMap::ReferenceMapTag, |
|
187 |
void>::type > |
|
189 | 188 |
{ |
190 | 189 |
typedef True ReferenceMapTag; |
191 |
|
|
190 |
|
|
192 | 191 |
typedef typename MatrixMap::FirstKey FirstKey; |
193 | 192 |
typedef typename MatrixMap::SecondKey SecondKey; |
194 | 193 |
typedef typename MatrixMap::Value Value; |
195 | 194 |
|
196 | 195 |
typedef typename MatrixMap::ConstReference ConstReturnValue; |
197 | 196 |
typedef typename MatrixMap::Reference ReturnValue; |
198 | 197 |
|
199 |
typedef typename MatrixMap::ConstReference ConstReference; |
|
198 |
typedef typename MatrixMap::ConstReference ConstReference; |
|
200 | 199 |
typedef typename MatrixMap::Reference Reference; |
201 | 200 |
}; |
202 | 201 |
|
203 | 202 |
// Indicators for the tags |
204 | 203 |
|
205 | 204 |
template <typename Graph, typename Enable = void> |
206 | 205 |
struct NodeNumTagIndicator { |
207 | 206 |
static const bool value = false; |
208 | 207 |
}; |
209 | 208 |
|
210 | 209 |
template <typename Graph> |
211 | 210 |
struct NodeNumTagIndicator< |
212 |
Graph, |
|
211 |
Graph, |
|
213 | 212 |
typename enable_if<typename Graph::NodeNumTag, void>::type |
214 | 213 |
> { |
215 | 214 |
static const bool value = true; |
216 | 215 |
}; |
217 | 216 |
|
218 | 217 |
template <typename Graph, typename Enable = void> |
219 | 218 |
struct EdgeNumTagIndicator { |
220 | 219 |
static const bool value = false; |
221 | 220 |
}; |
222 | 221 |
|
223 | 222 |
template <typename Graph> |
224 | 223 |
struct EdgeNumTagIndicator< |
225 |
Graph, |
|
224 |
Graph, |
|
226 | 225 |
typename enable_if<typename Graph::EdgeNumTag, void>::type |
227 | 226 |
> { |
228 | 227 |
static const bool value = true; |
229 | 228 |
}; |
230 | 229 |
|
231 | 230 |
template <typename Graph, typename Enable = void> |
232 | 231 |
struct FindEdgeTagIndicator { |
233 | 232 |
static const bool value = false; |
234 | 233 |
}; |
235 | 234 |
|
236 | 235 |
template <typename Graph> |
237 | 236 |
struct FindEdgeTagIndicator< |
238 |
Graph, |
|
237 |
Graph, |
|
239 | 238 |
typename enable_if<typename Graph::FindEdgeTag, void>::type |
240 | 239 |
> { |
241 | 240 |
static const bool value = true; |
242 | 241 |
}; |
243 | 242 |
|
244 | 243 |
template <typename Graph, typename Enable = void> |
245 | 244 |
struct UndirectedTagIndicator { |
246 | 245 |
static const bool value = false; |
247 | 246 |
}; |
248 | 247 |
|
249 | 248 |
template <typename Graph> |
250 | 249 |
struct UndirectedTagIndicator< |
251 |
Graph, |
|
250 |
Graph, |
|
252 | 251 |
typename enable_if<typename Graph::UndirectedTag, void>::type |
253 | 252 |
> { |
254 | 253 |
static const bool value = true; |
255 | 254 |
}; |
256 | 255 |
|
257 | 256 |
template <typename Graph, typename Enable = void> |
258 | 257 |
struct BuildTagIndicator { |
259 | 258 |
static const bool value = false; |
260 | 259 |
}; |
261 | 260 |
|
262 | 261 |
template <typename Graph> |
263 | 262 |
struct BuildTagIndicator< |
264 |
Graph, |
|
263 |
Graph, |
|
265 | 264 |
typename enable_if<typename Graph::BuildTag, void>::type |
266 | 265 |
> { |
267 | 266 |
static const bool value = true; |
268 | 267 |
}; |
269 | 268 |
|
270 | 269 |
} |
1 |
/* -*- C++ -*- |
|
1 |
/* -*- mode: C++; indent-tabs-mode: nil; -*- |
|
2 | 2 |
* |
3 |
* This file is a part of LEMON, a generic C++ optimization library |
|
3 |
* This file is a part of LEMON, a generic C++ optimization library. |
|
4 | 4 |
* |
5 | 5 |
* Copyright (C) 2003-2008 |
6 | 6 |
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
7 | 7 |
* (Egervary Research Group on Combinatorial Optimization, EGRES). |
8 | 8 |
* |
9 | 9 |
* Permission to use, modify and distribute this software is granted |
... | ... |
@@ -80,61 +80,61 @@ |
80 | 80 |
|
81 | 81 |
/**************** dummy class to avoid ambiguity ****************/ |
82 | 82 |
|
83 | 83 |
template<int T> struct dummy { dummy(int) {} }; |
84 | 84 |
|
85 | 85 |
/**************** enable_if from BOOST ****************/ |
86 |
|
|
86 |
|
|
87 | 87 |
template <typename Type, typename T = void> |
88 | 88 |
struct exists { |
89 | 89 |
typedef T type; |
90 | 90 |
}; |
91 | 91 |
|
92 |
|
|
92 |
|
|
93 | 93 |
template <bool B, class T = void> |
94 | 94 |
struct enable_if_c { |
95 | 95 |
typedef T type; |
96 | 96 |
}; |
97 | 97 |
|
98 | 98 |
template <class T> |
99 | 99 |
struct enable_if_c<false, T> {}; |
100 | 100 |
|
101 |
template <class Cond, class T = void> |
|
101 |
template <class Cond, class T = void> |
|
102 | 102 |
struct enable_if : public enable_if_c<Cond::value, T> {}; |
103 | 103 |
|
104 | 104 |
template <bool B, class T> |
105 | 105 |
struct lazy_enable_if_c { |
106 | 106 |
typedef typename T::type type; |
107 | 107 |
}; |
108 | 108 |
|
109 | 109 |
template <class T> |
110 | 110 |
struct lazy_enable_if_c<false, T> {}; |
111 | 111 |
|
112 |
template <class Cond, class T> |
|
112 |
template <class Cond, class T> |
|
113 | 113 |
struct lazy_enable_if : public lazy_enable_if_c<Cond::value, T> {}; |
114 | 114 |
|
115 | 115 |
|
116 | 116 |
template <bool B, class T = void> |
117 | 117 |
struct disable_if_c { |
118 | 118 |
typedef T type; |
119 | 119 |
}; |
120 | 120 |
|
121 | 121 |
template <class T> |
122 | 122 |
struct disable_if_c<true, T> {}; |
123 | 123 |
|
124 |
template <class Cond, class T = void> |
|
124 |
template <class Cond, class T = void> |
|
125 | 125 |
struct disable_if : public disable_if_c<Cond::value, T> {}; |
126 | 126 |
|
127 | 127 |
template <bool B, class T> |
128 | 128 |
struct lazy_disable_if_c { |
129 | 129 |
typedef typename T::type type; |
130 | 130 |
}; |
131 | 131 |
|
132 | 132 |
template <class T> |
133 | 133 |
struct lazy_disable_if_c<true, T> {}; |
134 | 134 |
|
135 |
template <class Cond, class T> |
|
135 |
template <class Cond, class T> |
|
136 | 136 |
struct lazy_disable_if : public lazy_disable_if_c<Cond::value, T> {}; |
137 | 137 |
|
138 | 138 |
} // namespace lemon |
139 | 139 |
|
140 | 140 |
#endif |
1 |
/* -*- C++ -*- |
|
1 |
/* -*- mode: C++; indent-tabs-mode: nil; -*- |
|
2 | 2 |
* |
3 |
* This file is a part of LEMON, a generic C++ optimization library |
|
3 |
* This file is a part of LEMON, a generic C++ optimization library. |
|
4 | 4 |
* |
5 | 5 |
* Copyright (C) 2003-2008 |
6 | 6 |
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
7 | 7 |
* (Egervary Research Group on Combinatorial Optimization, EGRES). |
8 | 8 |
* |
9 | 9 |
* Permission to use, modify and distribute this software is granted |
... | ... |
@@ -46,22 +46,22 @@ |
46 | 46 |
/// |
47 | 47 |
/// \tparam _Notifier The AlterationNotifier that will notify this map. |
48 | 48 |
/// \tparam _Item The item type of the graph items. |
49 | 49 |
/// \tparam _Value The value type of the map. |
50 | 50 |
/// \todo Fix the doc: there is _Graph parameter instead of _Notifier. |
51 | 51 |
template <typename _Graph, typename _Item, typename _Value> |
52 |
class VectorMap |
|
52 |
class VectorMap |
|
53 | 53 |
: public ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase { |
54 | 54 |
private: |
55 |
|
|
55 |
|
|
56 | 56 |
/// The container type of the map. |
57 |
typedef std::vector<_Value> Container; |
|
57 |
typedef std::vector<_Value> Container; |
|
58 | 58 |
|
59 | 59 |
public: |
60 | 60 |
|
61 |
/// The graph type of the map. |
|
61 |
/// The graph type of the map. |
|
62 | 62 |
typedef _Graph Graph; |
63 | 63 |
/// The item type of the map. |
64 | 64 |
typedef _Item Item; |
65 | 65 |
/// The reference map tag. |
66 | 66 |
typedef True ReferenceMapTag; |
67 | 67 |
|
... | ... |
@@ -90,74 +90,74 @@ |
90 | 90 |
/// It adds all the items of the graph to the map. |
91 | 91 |
VectorMap(const Graph& graph) { |
92 | 92 |
Parent::attach(graph.notifier(Item())); |
93 | 93 |
container.resize(Parent::notifier()->maxId() + 1); |
94 | 94 |
} |
95 | 95 |
|
96 |
/// \brief Constructor uses given value to initialize the map. |
|
96 |
/// \brief Constructor uses given value to initialize the map. |
|
97 | 97 |
/// |
98 |
/// It constructs a map uses a given value to initialize the map. |
|
98 |
/// It constructs a map uses a given value to initialize the map. |
|
99 | 99 |
/// It adds all the items of the graph to the map. |
100 | 100 |
VectorMap(const Graph& graph, const Value& value) { |
101 | 101 |
Parent::attach(graph.notifier(Item())); |
102 | 102 |
container.resize(Parent::notifier()->maxId() + 1, value); |
103 | 103 |
} |
104 | 104 |
|
105 | 105 |
/// \brief Copy constructor |
106 | 106 |
/// |
107 | 107 |
/// Copy constructor. |
108 | 108 |
VectorMap(const VectorMap& _copy) : Parent() { |
109 | 109 |
if (_copy.attached()) { |
110 |
Parent::attach(*_copy.notifier()); |
|
111 |
container = _copy.container; |
|
110 |
Parent::attach(*_copy.notifier()); |
|
111 |
container = _copy.container; |
|
112 | 112 |
} |
113 | 113 |
} |
114 | 114 |
|
115 | 115 |
/// \brief Assign operator. |
116 | 116 |
/// |
117 | 117 |
/// This operator assigns for each item in the map the |
118 |
/// value mapped to the same item in the copied map. |
|
118 |
/// value mapped to the same item in the copied map. |
|
119 | 119 |
/// The parameter map should be indiced with the same |
120 | 120 |
/// itemset because this assign operator does not change |
121 |
/// the container of the map. |
|
121 |
/// the container of the map. |
|
122 | 122 |
VectorMap& operator=(const VectorMap& cmap) { |
123 | 123 |
return operator=<VectorMap>(cmap); |
124 | 124 |
} |
125 | 125 |
|
126 | 126 |
|
127 | 127 |
/// \brief Template assign operator. |
128 | 128 |
/// |
129 | 129 |
/// The given parameter should be conform to the ReadMap |
130 | 130 |
/// concecpt and could be indiced by the current item set of |
131 | 131 |
/// the NodeMap. In this case the value for each item |
132 |
/// is assigned by the value of the given ReadMap. |
|
132 |
/// is assigned by the value of the given ReadMap. |
|
133 | 133 |
template <typename CMap> |
134 | 134 |
VectorMap& operator=(const CMap& cmap) { |
135 | 135 |
checkConcept<concepts::ReadMap<Key, _Value>, CMap>(); |
136 | 136 |
const typename Parent::Notifier* nf = Parent::notifier(); |
137 | 137 |
Item it; |
138 | 138 |
for (nf->first(it); it != INVALID; nf->next(it)) { |
139 | 139 |
set(it, cmap[it]); |
140 | 140 |
} |
141 | 141 |
return *this; |
142 | 142 |
} |
143 |
|
|
143 |
|
|
144 | 144 |
public: |
145 | 145 |
|
146 | 146 |
/// \brief The subcript operator. |
147 | 147 |
/// |
148 | 148 |
/// The subscript operator. The map can be subscripted by the |
149 |
/// actual items of the graph. |
|
149 |
/// actual items of the graph. |
|
150 | 150 |
Reference operator[](const Key& key) { |
151 | 151 |
return container[Parent::notifier()->id(key)]; |
152 |
} |
|
153 |
|
|
152 |
} |
|
153 |
|
|
154 | 154 |
/// \brief The const subcript operator. |
155 | 155 |
/// |
156 | 156 |
/// The const subscript operator. The map can be subscripted by the |
157 |
/// actual items of the graph. |
|
157 |
/// actual items of the graph. |
|
158 | 158 |
ConstReference operator[](const Key& key) const { |
159 | 159 |
return container[Parent::notifier()->id(key)]; |
160 | 160 |
} |
161 | 161 |
|
162 | 162 |
|
163 | 163 |
/// \brief The setter function of the map. |
... | ... |
@@ -167,26 +167,26 @@ |
167 | 167 |
(*this)[key] = value; |
168 | 168 |
} |
169 | 169 |
|
170 | 170 |
protected: |
171 | 171 |
|
172 | 172 |
/// \brief Adds a new key to the map. |
173 |
/// |
|
173 |
/// |
|
174 | 174 |
/// It adds a new key to the map. It called by the observer notifier |
175 |
/// and it overrides the add() member function of the observer base. |
|
175 |
/// and it overrides the add() member function of the observer base. |
|
176 | 176 |
virtual void add(const Key& key) { |
177 | 177 |
int id = Parent::notifier()->id(key); |
178 | 178 |
if (id >= int(container.size())) { |
179 |
|
|
179 |
container.resize(id + 1); |
|
180 | 180 |
} |
181 | 181 |
} |
182 | 182 |
|
183 | 183 |
/// \brief Adds more new keys to the map. |
184 |
/// |
|
184 |
/// |
|
185 | 185 |
/// It adds more new keys to the map. It called by the observer notifier |
186 |
/// and it overrides the add() member function of the observer base. |
|
186 |
/// and it overrides the add() member function of the observer base. |
|
187 | 187 |
virtual void add(const std::vector<Key>& keys) { |
188 | 188 |
int max = container.size() - 1; |
189 | 189 |
for (int i = 0; i < int(keys.size()); ++i) { |
190 | 190 |
int id = Parent::notifier()->id(keys[i]); |
191 | 191 |
if (id >= max) { |
192 | 192 |
max = id; |
... | ... |
@@ -195,47 +195,47 @@ |
195 | 195 |
container.resize(max + 1); |
196 | 196 |
} |
197 | 197 |
|
198 | 198 |
/// \brief Erase a key from the map. |
199 | 199 |
/// |
200 | 200 |
/// Erase a key from the map. It called by the observer notifier |
201 |
/// and it overrides the erase() member function of the observer base. |
|
201 |
/// and it overrides the erase() member function of the observer base. |
|
202 | 202 |
virtual void erase(const Key& key) { |
203 | 203 |
container[Parent::notifier()->id(key)] = Value(); |
204 | 204 |
} |
205 | 205 |
|
206 | 206 |
/// \brief Erase more keys from the map. |
207 | 207 |
/// |
208 | 208 |
/// Erase more keys from the map. It called by the observer notifier |
209 |
/// and it overrides the erase() member function of the observer base. |
|
209 |
/// and it overrides the erase() member function of the observer base. |
|
210 | 210 |
virtual void erase(const std::vector<Key>& keys) { |
211 | 211 |
for (int i = 0; i < int(keys.size()); ++i) { |
212 |
|
|
212 |
container[Parent::notifier()->id(keys[i])] = Value(); |
|
213 | 213 |
} |
214 | 214 |
} |
215 |
|
|
215 |
|
|
216 | 216 |
/// \brief Buildes the map. |
217 |
/// |
|
217 |
/// |
|
218 | 218 |
/// It buildes the map. It called by the observer notifier |
219 | 219 |
/// and it overrides the build() member function of the observer base. |
220 |
virtual void build() { |
|
220 |
virtual void build() { |
|
221 | 221 |
int size = Parent::notifier()->maxId() + 1; |
222 | 222 |
container.reserve(size); |
223 | 223 |
container.resize(size); |
224 | 224 |
} |
225 | 225 |
|
226 | 226 |
/// \brief Clear the map. |
227 | 227 |
/// |
228 | 228 |
/// It erase all items from the map. It called by the observer notifier |
229 |
/// and it overrides the clear() member function of the observer base. |
|
230 |
virtual void clear() { |
|
229 |
/// and it overrides the clear() member function of the observer base. |
|
230 |
virtual void clear() { |
|
231 | 231 |
container.clear(); |
232 | 232 |
} |
233 |
|
|
233 |
|
|
234 | 234 |
private: |
235 |
|
|
235 |
|
|
236 | 236 |
Container container; |
237 | 237 |
|
238 | 238 |
}; |
239 | 239 |
|
240 | 240 |
} |
241 | 241 |
1 |
/* -*- C++ -*- |
|
1 |
/* -*- mode: C++; indent-tabs-mode: nil; -*- |
|
2 | 2 |
* |
3 |
* This file is a part of LEMON, a generic C++ optimization library |
|
3 |
* This file is a part of LEMON, a generic C++ optimization library. |
|
4 | 4 |
* |
5 | 5 |
* Copyright (C) 2003-2008 |
6 | 6 |
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
7 | 7 |
* (Egervary Research Group on Combinatorial Optimization, EGRES). |
8 | 8 |
* |
9 | 9 |
* Permission to use, modify and distribute this software is granted |
... | ... |
@@ -21,13 +21,13 @@ |
21 | 21 |
|
22 | 22 |
#include<lemon/color.h> |
23 | 23 |
|
24 | 24 |
namespace lemon { |
25 | 25 |
|
26 | 26 |
const Color WHITE(1,1,1); |
27 |
|
|
27 |
|
|
28 | 28 |
const Color BLACK(0,0,0); |
29 | 29 |
const Color RED(1,0,0); |
30 | 30 |
const Color GREEN(0,1,0); |
31 | 31 |
const Color BLUE(0,0,1); |
32 | 32 |
const Color YELLOW(1,1,0); |
33 | 33 |
const Color MAGENTA(1,0,1); |
... | ... |
@@ -37,8 +37,8 @@ |
37 | 37 |
const Color DARK_RED(.5,0,0); |
38 | 38 |
const Color DARK_GREEN(0,.5,0); |
39 | 39 |
const Color DARK_BLUE(0,0,.5); |
40 | 40 |
const Color DARK_YELLOW(.5,.5,0); |
41 | 41 |
const Color DARK_MAGENTA(.5,0,.5); |
42 | 42 |
const Color DARK_CYAN(0,.5,.5); |
43 |
|
|
43 |
|
|
44 | 44 |
} //namespace lemon |
1 |
/* -*- C++ -*- |
|
1 |
/* -*- mode: C++; indent-tabs-mode: nil; -*- |
|
2 | 2 |
* |
3 |
* This file is a part of LEMON, a generic C++ optimization library |
|
3 |
* This file is a part of LEMON, a generic C++ optimization library. |
|
4 | 4 |
* |
5 | 5 |
* Copyright (C) 2003-2008 |
6 | 6 |
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
7 | 7 |
* (Egervary Research Group on Combinatorial Optimization, EGRES). |
8 | 8 |
* |
9 | 9 |
* Permission to use, modify and distribute this software is granted |
... | ... |
@@ -59,13 +59,13 @@ |
59 | 59 |
const double & blue() const {return _b;} |
60 | 60 |
///Set the color components |
61 | 61 |
void set(double r,double g,double b) { _r=r;_g=g;_b=b; }; |
62 | 62 |
}; |
63 | 63 |
|
64 | 64 |
/// White color constant |
65 |
extern const Color WHITE; |
|
65 |
extern const Color WHITE; |
|
66 | 66 |
/// Black color constant |
67 | 67 |
extern const Color BLACK; |
68 | 68 |
/// Red color constant |
69 | 69 |
extern const Color RED; |
70 | 70 |
/// Green color constant |
71 | 71 |
extern const Color GREEN; |
... | ... |
@@ -127,28 +127,28 @@ |
127 | 127 |
colors.push_back(Color(1,0,0)); |
128 | 128 |
colors.push_back(Color(0,1,0)); |
129 | 129 |
colors.push_back(Color(0,0,1)); |
130 | 130 |
colors.push_back(Color(1,1,0)); |
131 | 131 |
colors.push_back(Color(1,0,1)); |
132 | 132 |
colors.push_back(Color(0,1,1)); |
133 |
|
|
133 |
|
|
134 | 134 |
colors.push_back(Color(.5,0,0)); |
135 | 135 |
colors.push_back(Color(0,.5,0)); |
136 | 136 |
colors.push_back(Color(0,0,.5)); |
137 | 137 |
colors.push_back(Color(.5,.5,0)); |
138 | 138 |
colors.push_back(Color(.5,0,.5)); |
139 | 139 |
colors.push_back(Color(0,.5,.5)); |
140 |
|
|
140 |
|
|
141 | 141 |
colors.push_back(Color(.5,.5,.5)); |
142 | 142 |
colors.push_back(Color(1,.5,.5)); |
143 | 143 |
colors.push_back(Color(.5,1,.5)); |
144 | 144 |
colors.push_back(Color(.5,.5,1)); |
145 | 145 |
colors.push_back(Color(1,1,.5)); |
146 | 146 |
colors.push_back(Color(1,.5,1)); |
147 | 147 |
colors.push_back(Color(.5,1,1)); |
148 |
|
|
148 |
|
|
149 | 149 |
colors.push_back(Color(1,.5,0)); |
150 | 150 |
colors.push_back(Color(.5,1,0)); |
151 | 151 |
colors.push_back(Color(1,0,.5)); |
152 | 152 |
colors.push_back(Color(0,1,.5)); |
153 | 153 |
colors.push_back(Color(0,.5,1)); |
154 | 154 |
colors.push_back(Color(.5,0,1)); |
... | ... |
@@ -168,13 +168,13 @@ |
168 | 168 |
///\e |
169 | 169 |
void set(int i,const Color &c) |
170 | 170 |
{ |
171 | 171 |
colors[i%colors.size()]=c; |
172 | 172 |
} |
173 | 173 |
///Adds a new color to the end of the color list. |
174 |
void add(const Color &c) |
|
174 |
void add(const Color &c) |
|
175 | 175 |
{ |
176 | 176 |
colors.push_back(c); |
177 | 177 |
} |
178 | 178 |
|
179 | 179 |
///Sets the number of the existing colors. |
180 | 180 |
void resize(int s) { colors.resize(s);} |
... | ... |
@@ -183,13 +183,13 @@ |
183 | 183 |
}; |
184 | 184 |
|
185 | 185 |
///Returns a visibly distinct \ref Color |
186 | 186 |
|
187 | 187 |
///Returns a \ref Color which is as different from the given parameter |
188 | 188 |
///as it is possible. |
189 |
inline Color distantColor(const Color &c) |
|
189 |
inline Color distantColor(const Color &c) |
|
190 | 190 |
{ |
191 | 191 |
return Color(c.red()<.5?1:0,c.green()<.5?1:0,c.blue()<.5?1:0); |
192 | 192 |
} |
193 | 193 |
///Returns black for light colors and white for the dark ones. |
194 | 194 |
|
195 | 195 |
///Returns black for light colors and white for the dark ones. |
1 |
/* -*- C++ -*- |
|
1 |
/* -*- mode: C++; indent-tabs-mode: nil; -*- |
|
2 | 2 |
* |
3 |
* This file is a part of LEMON, a generic C++ optimization library |
|
3 |
* This file is a part of LEMON, a generic C++ optimization library. |
|
4 | 4 |
* |
5 | 5 |
* Copyright (C) 2003-2008 |
6 | 6 |
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
7 | 7 |
* (Egervary Research Group on Combinatorial Optimization, EGRES). |
8 | 8 |
* |
9 | 9 |
* Permission to use, modify and distribute this software is granted |
... | ... |
@@ -33,13 +33,13 @@ |
33 | 33 |
|
34 | 34 |
// See http://www.boost.org/libs/concept_check for documentation. |
35 | 35 |
|
36 | 36 |
///\file |
37 | 37 |
///\brief Basic utilities for concept checking. |
38 | 38 |
/// |
39 |
///\todo Are we still using BOOST concept checking utility? |
|
39 |
///\todo Are we still using BOOST concept checking utility? |
|
40 | 40 |
///Is the BOOST copyright notice necessary? |
41 | 41 |
|
42 | 42 |
#ifndef LEMON_CONCEPT_CHECK_H |
43 | 43 |
#define LEMON_CONCEPT_CHECK_H |
44 | 44 |
|
45 | 45 |
namespace lemon { |
1 |
/* -*- C++ -*- |
|
1 |
/* -*- mode: C++; indent-tabs-mode: nil; -*- |
|
2 | 2 |
* |
3 |
* This file is a part of LEMON, a generic C++ optimization library |
|
3 |
* This file is a part of LEMON, a generic C++ optimization library. |
|
4 | 4 |
* |
5 | 5 |
* Copyright (C) 2003-2008 |
6 | 6 |
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
7 | 7 |
* (Egervary Research Group on Combinatorial Optimization, EGRES). |
8 | 8 |
* |
9 | 9 |
* Permission to use, modify and distribute this software is granted |
... | ... |
@@ -43,19 +43,19 @@ |
43 | 43 |
/// @ref SmartDigraph may have several additional functionality. |
44 | 44 |
/// |
45 | 45 |
/// \sa concept |
46 | 46 |
class Digraph { |
47 | 47 |
private: |
48 | 48 |
///Digraphs are \e not copy constructible. Use DigraphCopy() instead. |
49 |
|
|
49 |
|
|
50 | 50 |
///Digraphs are \e not copy constructible. Use DigraphCopy() instead. |
51 | 51 |
/// |
52 | 52 |
Digraph(const Digraph &) {}; |
53 | 53 |
///\brief Assignment of \ref Digraph "Digraph"s to another ones are |
54 | 54 |
///\e not allowed. Use DigraphCopy() instead. |
55 |
|
|
55 |
|
|
56 | 56 |
///Assignment of \ref Digraph "Digraph"s to another ones are |
57 | 57 |
///\e not allowed. Use DigraphCopy() instead. |
58 | 58 |
|
59 | 59 |
void operator=(const Digraph &) {} |
60 | 60 |
public: |
61 | 61 |
///\e |
... | ... |
@@ -92,29 +92,29 @@ |
92 | 92 |
|
93 | 93 |
/// Two iterators are equal if and only if they point to the |
94 | 94 |
/// same object or both are invalid. |
95 | 95 |
bool operator==(Node) const { return true; } |
96 | 96 |
|
97 | 97 |
/// Inequality operator |
98 |
|
|
98 |
|
|
99 | 99 |
/// \sa operator==(Node n) |
100 | 100 |
/// |
101 | 101 |
bool operator!=(Node) const { return true; } |
102 | 102 |
|
103 |
/// Artificial ordering operator. |
|
104 |
|
|
105 |
/// To allow the use of digraph descriptors as key type in std::map or |
|
106 |
/// similar associative container we require this. |
|
107 |
/// |
|
108 |
/// \note This operator only have to define some strict ordering of |
|
109 |
/// the items; this order has nothing to do with the iteration |
|
110 |
/// ordering of the items. |
|
111 |
|
|
103 |
/// Artificial ordering operator. |
|
104 |
|
|
105 |
/// To allow the use of digraph descriptors as key type in std::map or |
|
106 |
/// similar associative container we require this. |
|
107 |
/// |
|
108 |
/// \note This operator only have to define some strict ordering of |
|
109 |
/// the items; this order has nothing to do with the iteration |
|
110 |
/// ordering of the items. |
|
111 |
bool operator<(Node) const { return false; } |
|
112 | 112 |
|
113 | 113 |
}; |
114 |
|
|
114 |
|
|
115 | 115 |
/// This iterator goes through each node. |
116 | 116 |
|
117 | 117 |
/// This iterator goes through each node. |
118 | 118 |
/// Its usage is quite simple, for example you can count the number |
119 | 119 |
/// of nodes in digraph \c g of type \c Digraph like this: |
120 | 120 |
///\code |
... | ... |
@@ -126,13 +126,13 @@ |
126 | 126 |
/// Default constructor |
127 | 127 |
|
128 | 128 |
/// @warning The default constructor sets the iterator |
129 | 129 |
/// to an undefined value. |
130 | 130 |
NodeIt() { } |
131 | 131 |
/// Copy constructor. |
132 |
|
|
132 |
|
|
133 | 133 |
/// Copy constructor. |
134 | 134 |
/// |
135 | 135 |
NodeIt(const NodeIt& n) : Node(n) { } |
136 | 136 |
/// Invalid constructor \& conversion. |
137 | 137 |
|
138 | 138 |
/// Initialize the iterator to be invalid. |
... | ... |
@@ -142,25 +142,25 @@ |
142 | 142 |
|
143 | 143 |
/// Sets the iterator to the first node of \c g. |
144 | 144 |
/// |
145 | 145 |
NodeIt(const Digraph&) { } |
146 | 146 |
/// Node -> NodeIt conversion. |
147 | 147 |
|
148 |
/// Sets the iterator to the node of \c the digraph pointed by |
|
149 |
/// the trivial iterator. |
|
150 |
/// |
|
148 |
/// Sets the iterator to the node of \c the digraph pointed by |
|
149 |
/// the trivial iterator. |
|
150 |
/// This feature necessitates that each time we |
|
151 | 151 |
/// iterate the arc-set, the iteration order is the same. |
152 | 152 |
NodeIt(const Digraph&, const Node&) { } |
153 | 153 |
/// Next node. |
154 | 154 |
|
155 | 155 |
/// Assign the iterator to the next node. |
156 | 156 |
/// |
157 | 157 |
NodeIt& operator++() { return *this; } |
158 | 158 |
}; |
159 |
|
|
160 |
|
|
159 |
|
|
160 |
|
|
161 | 161 |
/// Class for identifying an arc of the digraph |
162 | 162 |
|
163 | 163 |
/// This class identifies an arc of the digraph. It also serves |
164 | 164 |
/// as a base class of the arc iterators, |
165 | 165 |
/// thus they will convert to this type. |
166 | 166 |
class Arc { |
... | ... |
@@ -188,35 +188,35 @@ |
188 | 188 |
/// Inequality operator |
189 | 189 |
|
190 | 190 |
/// \sa operator==(Arc n) |
191 | 191 |
/// |
192 | 192 |
bool operator!=(Arc) const { return true; } |
193 | 193 |
|
194 |
/// Artificial ordering operator. |
|
195 |
|
|
196 |
/// To allow the use of digraph descriptors as key type in std::map or |
|
197 |
/// similar associative container we require this. |
|
198 |
/// |
|
199 |
/// \note This operator only have to define some strict ordering of |
|
200 |
/// the items; this order has nothing to do with the iteration |
|
201 |
/// ordering of the items. |
|
202 |
|
|
194 |
/// Artificial ordering operator. |
|
195 |
|
|
196 |
/// To allow the use of digraph descriptors as key type in std::map or |
|
197 |
/// similar associative container we require this. |
|
198 |
/// |
|
199 |
/// \note This operator only have to define some strict ordering of |
|
200 |
/// the items; this order has nothing to do with the iteration |
|
201 |
/// ordering of the items. |
|
202 |
bool operator<(Arc) const { return false; } |
|
203 | 203 |
}; |
204 |
|
|
204 |
|
|
205 | 205 |
/// This iterator goes trough the outgoing arcs of a node. |
206 | 206 |
|
207 | 207 |
/// This iterator goes trough the \e outgoing arcs of a certain node |
208 | 208 |
/// of a digraph. |
209 | 209 |
/// Its usage is quite simple, for example you can count the number |
210 | 210 |
/// of outgoing arcs of a node \c n |
211 | 211 |
/// in digraph \c g of type \c Digraph as follows. |
212 | 212 |
///\code |
213 | 213 |
/// int count=0; |
214 | 214 |
/// for (Digraph::OutArcIt e(g, n); e!=INVALID; ++e) ++count; |
215 | 215 |
///\endcode |
216 |
|
|
216 |
|
|
217 | 217 |
class OutArcIt : public Arc { |
218 | 218 |
public: |
219 | 219 |
/// Default constructor |
220 | 220 |
|
221 | 221 |
/// @warning The default constructor sets the iterator |
222 | 222 |
/// to an undefined value. |
... | ... |
@@ -229,25 +229,25 @@ |
229 | 229 |
/// Initialize the iterator to be invalid. |
230 | 230 |
|
231 | 231 |
/// Initialize the iterator to be invalid. |
232 | 232 |
/// |
233 | 233 |
OutArcIt(Invalid) { } |
234 | 234 |
/// This constructor sets the iterator to the first outgoing arc. |
235 |
|
|
235 |
|
|
236 | 236 |
/// This constructor sets the iterator to the first outgoing arc of |
237 | 237 |
/// the node. |
238 | 238 |
OutArcIt(const Digraph&, const Node&) { } |
239 | 239 |
/// Arc -> OutArcIt conversion |
240 | 240 |
|
241 | 241 |
/// Sets the iterator to the value of the trivial iterator. |
242 |
|
|
242 |
/// This feature necessitates that each time we |
|
243 | 243 |
/// iterate the arc-set, the iteration order is the same. |
244 | 244 |
OutArcIt(const Digraph&, const Arc&) { } |
245 | 245 |
///Next outgoing arc |
246 |
|
|
247 |
/// Assign the iterator to the next |
|
246 |
|
|
247 |
/// Assign the iterator to the next |
|
248 | 248 |
/// outgoing arc of the corresponding node. |
249 | 249 |
OutArcIt& operator++() { return *this; } |
250 | 250 |
}; |
251 | 251 |
|
252 | 252 |
/// This iterator goes trough the incoming arcs of a node. |
253 | 253 |
|
... | ... |
@@ -276,20 +276,20 @@ |
276 | 276 |
/// Initialize the iterator to be invalid. |
277 | 277 |
|
278 | 278 |
/// Initialize the iterator to be invalid. |
279 | 279 |
/// |
280 | 280 |
InArcIt(Invalid) { } |
281 | 281 |
/// This constructor sets the iterator to first incoming arc. |
282 |
|
|
282 |
|
|
283 | 283 |
/// This constructor set the iterator to the first incoming arc of |
284 | 284 |
/// the node. |
285 | 285 |
InArcIt(const Digraph&, const Node&) { } |
286 | 286 |
/// Arc -> InArcIt conversion |
287 | 287 |
|
288 | 288 |
/// Sets the iterator to the value of the trivial iterator \c e. |
289 |
/// This feature necessitates that each time we |
|
289 |
/// This feature necessitates that each time we |
|
290 | 290 |
/// iterate the arc-set, the iteration order is the same. |
291 | 291 |
InArcIt(const Digraph&, const Arc&) { } |
292 | 292 |
/// Next incoming arc |
293 | 293 |
|
294 | 294 |
/// Assign the iterator to the next inarc of the corresponding node. |
295 | 295 |
/// |
... | ... |
@@ -319,24 +319,24 @@ |
319 | 319 |
/// Initialize the iterator to be invalid. |
320 | 320 |
|
321 | 321 |
/// Initialize the iterator to be invalid. |
322 | 322 |
/// |
323 | 323 |
ArcIt(Invalid) { } |
324 | 324 |
/// This constructor sets the iterator to the first arc. |
325 |
|
|
325 |
|
|
326 | 326 |
/// This constructor sets the iterator to the first arc of \c g. |
327 | 327 |
///@param g the digraph |
328 | 328 |
ArcIt(const Digraph& g) { ignore_unused_variable_warning(g); } |
329 | 329 |
/// Arc -> ArcIt conversion |
330 | 330 |
|
331 | 331 |
/// Sets the iterator to the value of the trivial iterator \c e. |
332 |
/// This feature necessitates that each time we |
|
332 |
/// This feature necessitates that each time we |
|
333 | 333 |
/// iterate the arc-set, the iteration order is the same. |
334 |
ArcIt(const Digraph&, const Arc&) { } |
|
334 |
ArcIt(const Digraph&, const Arc&) { } |
|
335 | 335 |
///Next arc |
336 |
|
|
336 |
|
|
337 | 337 |
/// Assign the iterator to the next arc. |
338 | 338 |
ArcIt& operator++() { return *this; } |
339 | 339 |
}; |
340 | 340 |
///Gives back the target node of an arc. |
341 | 341 |
|
342 | 342 |
///Gives back the target node of an arc. |
... | ... |
@@ -346,32 +346,32 @@ |
346 | 346 |
|
347 | 347 |
///Gives back the source node of an arc. |
348 | 348 |
/// |
349 | 349 |
Node source(Arc) const { return INVALID; } |
350 | 350 |
|
351 | 351 |
/// \brief Returns the ID of the node. |
352 |
int id(Node) const { return -1; } |
|
352 |
int id(Node) const { return -1; } |
|
353 | 353 |
|
354 | 354 |
/// \brief Returns the ID of the arc. |
355 |
int id(Arc) const { return -1; } |
|
355 |
int id(Arc) const { return -1; } |
|
356 | 356 |
|
357 | 357 |
/// \brief Returns the node with the given ID. |
358 | 358 |
/// |
359 | 359 |
/// \pre The argument should be a valid node ID in the graph. |
360 |
Node nodeFromId(int) const { return INVALID; } |
|
360 |
Node nodeFromId(int) const { return INVALID; } |
|
361 | 361 |
|
362 | 362 |
/// \brief Returns the arc with the given ID. |
363 | 363 |
/// |
364 | 364 |
/// \pre The argument should be a valid arc ID in the graph. |
365 |
Arc arcFromId(int) const { return INVALID; } |
|
365 |
Arc arcFromId(int) const { return INVALID; } |
|
366 | 366 |
|
367 | 367 |
/// \brief Returns an upper bound on the node IDs. |
368 |
int maxNodeId() const { return -1; } |
|
368 |
int maxNodeId() const { return -1; } |
|
369 | 369 |
|
370 | 370 |
/// \brief Returns an upper bound on the arc IDs. |
371 |
int maxArcId() const { return -1; } |
|
371 |
int maxArcId() const { return -1; } |
|
372 | 372 |
|
373 | 373 |
void first(Node&) const {} |
374 | 374 |
void next(Node&) const {} |
375 | 375 |
|
376 | 376 |
void first(Arc&) const {} |
377 | 377 |
void next(Arc&) const {} |
... | ... |
@@ -386,15 +386,15 @@ |
386 | 386 |
// The second parameter is dummy. |
387 | 387 |
Node fromId(int, Node) const { return INVALID; } |
388 | 388 |
// The second parameter is dummy. |
389 | 389 |
Arc fromId(int, Arc) const { return INVALID; } |
390 | 390 |
|
391 | 391 |
// Dummy parameter. |
392 |
int maxId(Node) const { return -1; } |
|
392 |
int maxId(Node) const { return -1; } |
|
393 | 393 |
// Dummy parameter. |
394 |
int maxId(Arc) const { return -1; } |
|
394 |
int maxId(Arc) const { return -1; } |
|
395 | 395 |
|
396 | 396 |
/// \brief The base node of the iterator. |
397 | 397 |
/// |
398 | 398 |
/// Gives back the base node of the iterator. |
399 | 399 |
/// It is always the target of the pointed arc. |
400 | 400 |
Node baseNode(const InArcIt&) const { return INVALID; } |
... | ... |
@@ -420,67 +420,67 @@ |
420 | 420 |
/// \brief The opposite node on the given arc. |
421 | 421 |
/// |
422 | 422 |
/// Gives back the opposite node on the given arc. |
423 | 423 |
Node oppositeNode(const Node&, const Arc&) const { return INVALID; } |
424 | 424 |
|
425 | 425 |
/// \brief Read write map of the nodes to type \c T. |
426 |
/// |
|
426 |
/// |
|
427 | 427 |
/// ReadWrite map of the nodes to type \c T. |
428 | 428 |
/// \sa Reference |
429 |
template<class T> |
|
429 |
template<class T> |
|
430 | 430 |
class NodeMap : public ReadWriteMap< Node, T > { |
431 | 431 |
public: |
432 | 432 |
|
433 | 433 |
///\e |
434 | 434 |
NodeMap(const Digraph&) { } |
435 | 435 |
///\e |
436 | 436 |
NodeMap(const Digraph&, T) { } |
437 | 437 |
|
438 | 438 |
///Copy constructor |
439 | 439 |
NodeMap(const NodeMap& nm) : ReadWriteMap< Node, T >(nm) { } |
440 | 440 |
///Assignment operator |
441 | 441 |
template <typename CMap> |
442 |
NodeMap& operator=(const CMap&) { |
|
442 |
NodeMap& operator=(const CMap&) { |
|
443 | 443 |
checkConcept<ReadMap<Node, T>, CMap>(); |
444 |
return *this; |
|
444 |
return *this; |
|
445 | 445 |
} |
446 | 446 |
}; |
447 | 447 |
|
448 | 448 |
/// \brief Read write map of the arcs to type \c T. |
449 | 449 |
/// |
450 | 450 |
/// Reference map of the arcs to type \c T. |
451 | 451 |
/// \sa Reference |
452 |
template<class T> |
|
452 |
template<class T> |
|
453 | 453 |
class ArcMap : public ReadWriteMap<Arc,T> { |
454 | 454 |
public: |
455 | 455 |
|
456 | 456 |
///\e |
457 | 457 |
ArcMap(const Digraph&) { } |
458 | 458 |
///\e |
459 | 459 |
ArcMap(const Digraph&, T) { } |
460 | 460 |
///Copy constructor |
461 | 461 |
ArcMap(const ArcMap& em) : ReadWriteMap<Arc,T>(em) { } |
462 | 462 |
///Assignment operator |
463 | 463 |
template <typename CMap> |
464 |
ArcMap& operator=(const CMap&) { |
|
464 |
ArcMap& operator=(const CMap&) { |
|
465 | 465 |
checkConcept<ReadMap<Arc, T>, CMap>(); |
466 |
return *this; |
|
466 |
return *this; |
|
467 | 467 |
} |
468 | 468 |
}; |
469 | 469 |
|
470 | 470 |
template <typename _Digraph> |
471 | 471 |
struct Constraints { |
472 | 472 |
void constraints() { |
473 | 473 |
checkConcept<IterableDigraphComponent<>, _Digraph>(); |
474 |
|
|
474 |
checkConcept<IDableDigraphComponent<>, _Digraph>(); |
|
475 | 475 |
checkConcept<MappableDigraphComponent<>, _Digraph>(); |
476 | 476 |
} |
477 | 477 |
}; |
478 | 478 |
|
479 | 479 |
}; |
480 |
|
|
481 |
} //namespace concepts |
|
480 |
|
|
481 |
} //namespace concepts |
|
482 | 482 |
} //namespace lemon |
483 | 483 |
|
484 | 484 |
|
485 | 485 |
|
486 | 486 |
#endif // LEMON_CONCEPT_DIGRAPH_H |
1 |
/* -*- C++ -*- |
|
1 |
/* -*- mode: C++; indent-tabs-mode: nil; -*- |
|
2 | 2 |
* |
3 |
* This file is a part of LEMON, a generic C++ optimization library |
|
3 |
* This file is a part of LEMON, a generic C++ optimization library. |
|
4 | 4 |
* |
5 | 5 |
* Copyright (C) 2003-2008 |
6 | 6 |
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
7 | 7 |
* (Egervary Research Group on Combinatorial Optimization, EGRES). |
8 | 8 |
* |
9 | 9 |
* Permission to use, modify and distribute this software is granted |
... | ... |
@@ -62,29 +62,29 @@ |
62 | 62 |
/// |
63 | 63 |
/// The EdgeIt is an iterator for the edges. We can use |
64 | 64 |
/// the EdgeMap to map values for the edges. The InArcIt and |
65 | 65 |
/// OutArcIt iterates on the same edges but with opposite |
66 | 66 |
/// direction. The IncEdgeIt iterates also on the same edges |
67 | 67 |
/// as the OutArcIt and InArcIt but it is not convertible to Arc just |
68 |
/// to Edge. |
|
68 |
/// to Edge. |
|
69 | 69 |
class Graph { |
70 | 70 |
public: |
71 | 71 |
/// \brief The undirected graph should be tagged by the |
72 | 72 |
/// UndirectedTag. |
73 | 73 |
/// |
74 | 74 |
/// The undirected graph should be tagged by the UndirectedTag. This |
75 |
/// tag helps the enable_if technics to make compile time |
|
76 |
/// specializations for undirected graphs. |
|
75 |
/// tag helps the enable_if technics to make compile time |
|
76 |
/// specializations for undirected graphs. |
|
77 | 77 |
typedef True UndirectedTag; |
78 | 78 |
|
79 |
/// \brief The base type of node iterators, |
|
79 |
/// \brief The base type of node iterators, |
|
80 | 80 |
/// or in other words, the trivial node iterator. |
81 | 81 |
/// |
82 | 82 |
/// This is the base type of each node iterator, |
83 | 83 |
/// thus each kind of node iterator converts to this. |
84 |
/// More precisely each kind of node iterator should be inherited |
|
84 |
/// More precisely each kind of node iterator should be inherited |
|
85 | 85 |
/// from the trivial node iterator. |
86 | 86 |
class Node { |
87 | 87 |
public: |
88 | 88 |
/// Default constructor |
89 | 89 |
|
90 | 90 |
/// @warning The default constructor sets the iterator |
... | ... |
@@ -105,29 +105,29 @@ |
105 | 105 |
|
106 | 106 |
/// Two iterators are equal if and only if they point to the |
107 | 107 |
/// same object or both are invalid. |
108 | 108 |
bool operator==(Node) const { return true; } |
109 | 109 |
|
110 | 110 |
/// Inequality operator |
111 |
|
|
111 |
|
|
112 | 112 |
/// \sa operator==(Node n) |
113 | 113 |
/// |
114 | 114 |
bool operator!=(Node) const { return true; } |
115 | 115 |
|
116 |
/// Artificial ordering operator. |
|
117 |
|
|
118 |
/// To allow the use of graph descriptors as key type in std::map or |
|
119 |
/// similar associative container we require this. |
|
120 |
/// |
|
121 |
/// \note This operator only have to define some strict ordering of |
|
122 |
/// the items; this order has nothing to do with the iteration |
|
123 |
/// ordering of the items. |
|
124 |
|
|
116 |
/// Artificial ordering operator. |
|
117 |
|
|
118 |
/// To allow the use of graph descriptors as key type in std::map or |
|
119 |
/// similar associative container we require this. |
|
120 |
/// |
|
121 |
/// \note This operator only have to define some strict ordering of |
|
122 |
/// the items; this order has nothing to do with the iteration |
|
123 |
/// ordering of the items. |
|
124 |
bool operator<(Node) const { return false; } |
|
125 | 125 |
|
126 | 126 |
}; |
127 |
|
|
127 |
|
|
128 | 128 |
/// This iterator goes through each node. |
129 | 129 |
|
130 | 130 |
/// This iterator goes through each node. |
131 | 131 |
/// Its usage is quite simple, for example you can count the number |
132 | 132 |
/// of nodes in graph \c g of type \c Graph like this: |
133 | 133 |
///\code |
... | ... |
@@ -139,13 +139,13 @@ |
139 | 139 |
/// Default constructor |
140 | 140 |
|
141 | 141 |
/// @warning The default constructor sets the iterator |
142 | 142 |
/// to an undefined value. |
143 | 143 |
NodeIt() { } |
144 | 144 |
/// Copy constructor. |
145 |
|
|
145 |
|
|
146 | 146 |
/// Copy constructor. |
147 | 147 |
/// |
148 | 148 |
NodeIt(const NodeIt& n) : Node(n) { } |
149 | 149 |
/// Invalid constructor \& conversion. |
150 | 150 |
|
151 | 151 |
/// Initialize the iterator to be invalid. |
... | ... |
@@ -155,25 +155,25 @@ |
155 | 155 |
|
156 | 156 |
/// Sets the iterator to the first node of \c g. |
157 | 157 |
/// |
158 | 158 |
NodeIt(const Graph&) { } |
159 | 159 |
/// Node -> NodeIt conversion. |
160 | 160 |
|
161 |
/// Sets the iterator to the node of \c the graph pointed by |
|
162 |
/// the trivial iterator. |
|
163 |
/// |
|
161 |
/// Sets the iterator to the node of \c the graph pointed by |
|
162 |
/// the trivial iterator. |
|
163 |
/// This feature necessitates that each time we |
|
164 | 164 |
/// iterate the arc-set, the iteration order is the same. |
165 | 165 |
NodeIt(const Graph&, const Node&) { } |
166 | 166 |
/// Next node. |
167 | 167 |
|
168 | 168 |
/// Assign the iterator to the next node. |
169 | 169 |
/// |
170 | 170 |
NodeIt& operator++() { return *this; } |
171 | 171 |
}; |
172 |
|
|
173 |
|
|
172 |
|
|
173 |
|
|
174 | 174 |
/// The base type of the edge iterators. |
175 | 175 |
|
176 | 176 |
/// The base type of the edge iterators. |
177 | 177 |
/// |
178 | 178 |
class Edge { |
179 | 179 |
public: |
... | ... |
@@ -200,21 +200,21 @@ |
200 | 200 |
/// Inequality operator |
201 | 201 |
|
202 | 202 |
/// \sa operator==(Edge n) |
203 | 203 |
/// |
204 | 204 |
bool operator!=(Edge) const { return true; } |
205 | 205 |
|
206 |
/// Artificial ordering operator. |
|
207 |
|
|
208 |
/// To allow the use of graph descriptors as key type in std::map or |
|
209 |
/// similar associative container we require this. |
|
210 |
/// |
|
211 |
/// \note This operator only have to define some strict ordering of |
|
212 |
/// the items; this order has nothing to do with the iteration |
|
213 |
/// ordering of the items. |
|
214 |
|
|
206 |
/// Artificial ordering operator. |
|
207 |
|
|
208 |
/// To allow the use of graph descriptors as key type in std::map or |
|
209 |
/// similar associative container we require this. |
|
210 |
/// |
|
211 |
/// \note This operator only have to define some strict ordering of |
|
212 |
/// the items; this order has nothing to do with the iteration |
|
213 |
/// ordering of the items. |
|
214 |
bool operator<(Edge) const { return false; } |
|
215 | 215 |
}; |
216 | 216 |
|
217 | 217 |
/// This iterator goes through each edge. |
218 | 218 |
|
219 | 219 |
/// This iterator goes through each edge of a graph. |
220 | 220 |
/// Its usage is quite simple, for example you can count the number |
... | ... |
@@ -238,38 +238,38 @@ |
238 | 238 |
/// Initialize the iterator to be invalid. |
239 | 239 |
|
240 | 240 |
/// Initialize the iterator to be invalid. |
241 | 241 |
/// |
242 | 242 |
EdgeIt(Invalid) { } |
243 | 243 |
/// This constructor sets the iterator to the first edge. |
244 |
|
|
244 |
|
|
245 | 245 |
/// This constructor sets the iterator to the first edge. |
246 | 246 |
EdgeIt(const Graph&) { } |
247 | 247 |
/// Edge -> EdgeIt conversion |
248 | 248 |
|
249 | 249 |
/// Sets the iterator to the value of the trivial iterator. |
250 | 250 |
/// This feature necessitates that each time we |
251 |
/// iterate the edge-set, the iteration order is the |
|
252 |
/// same. |
|
253 |
|
|
251 |
/// iterate the edge-set, the iteration order is the |
|
252 |
/// same. |
|
253 |
EdgeIt(const Graph&, const Edge&) { } |
|
254 | 254 |
/// Next edge |
255 |
|
|
255 |
|
|
256 | 256 |
/// Assign the iterator to the next edge. |
257 | 257 |
EdgeIt& operator++() { return *this; } |
258 | 258 |
}; |
259 | 259 |
|
260 |
/// \brief This iterator goes trough the incident undirected |
|
260 |
/// \brief This iterator goes trough the incident undirected |
|
261 | 261 |
/// arcs of a node. |
262 | 262 |
/// |
263 | 263 |
/// This iterator goes trough the incident edges |
264 |
/// of a certain node of a graph. You should assume that the |
|
264 |
/// of a certain node of a graph. You should assume that the |
|
265 | 265 |
/// loop arcs will be iterated twice. |
266 |
/// |
|
266 |
/// |
|
267 | 267 |
/// Its usage is quite simple, for example you can compute the |
268 | 268 |
/// degree (i.e. count the number of incident arcs of a node \c n |
269 |
/// in graph \c g of type \c Graph as follows. |
|
269 |
/// in graph \c g of type \c Graph as follows. |
|
270 | 270 |
/// |
271 | 271 |
///\code |
272 | 272 |
/// int count=0; |
273 | 273 |
/// for(Graph::IncEdgeIt e(g, n); e!=INVALID; ++e) ++count; |
274 | 274 |
///\endcode |
275 | 275 |
class IncEdgeIt : public Edge { |
... | ... |
@@ -287,26 +287,26 @@ |
287 | 287 |
/// Initialize the iterator to be invalid. |
288 | 288 |
|
289 | 289 |
/// Initialize the iterator to be invalid. |
290 | 290 |
/// |
291 | 291 |
IncEdgeIt(Invalid) { } |
292 | 292 |
/// This constructor sets the iterator to first incident arc. |
293 |
|
|
293 |
|
|
294 | 294 |
/// This constructor set the iterator to the first incident arc of |
295 | 295 |
/// the node. |
296 | 296 |
IncEdgeIt(const Graph&, const Node&) { } |
297 | 297 |
/// Edge -> IncEdgeIt conversion |
298 | 298 |
|
299 | 299 |
/// Sets the iterator to the value of the trivial iterator \c e. |
300 |
/// This feature necessitates that each time we |
|
300 |
/// This feature necessitates that each time we |
|
301 | 301 |
/// iterate the arc-set, the iteration order is the same. |
302 | 302 |
IncEdgeIt(const Graph&, const Edge&) { } |
303 | 303 |
/// Next incident arc |
304 | 304 |
|
305 | 305 |
/// Assign the iterator to the next incident arc |
306 |
|
|
306 |
/// of the corresponding node. |
|
307 | 307 |
IncEdgeIt& operator++() { return *this; } |
308 | 308 |
}; |
309 | 309 |
|
310 | 310 |
/// The directed arc type. |
311 | 311 |
|
312 | 312 |
/// The directed arc type. It can be converted to the |
... | ... |
@@ -337,23 +337,23 @@ |
337 | 337 |
/// Inequality operator |
338 | 338 |
|
339 | 339 |
/// \sa operator==(Arc n) |
340 | 340 |
/// |
341 | 341 |
bool operator!=(Arc) const { return true; } |
342 | 342 |
|
343 |
/// Artificial ordering operator. |
|
344 |
|
|
345 |
/// To allow the use of graph descriptors as key type in std::map or |
|
346 |
/// similar associative container we require this. |
|
347 |
/// |
|
348 |
/// \note This operator only have to define some strict ordering of |
|
349 |
/// the items; this order has nothing to do with the iteration |
|
350 |
/// ordering of the items. |
|
351 |
bool operator<(Arc) const { return false; } |
|
352 |
|
|
353 |
|
|
343 |
/// Artificial ordering operator. |
|
344 |
|
|
345 |
/// To allow the use of graph descriptors as key type in std::map or |
|
346 |
/// similar associative container we require this. |
|
347 |
/// |
|
348 |
/// \note This operator only have to define some strict ordering of |
|
349 |
/// the items; this order has nothing to do with the iteration |
|
350 |
/// ordering of the items. |
|
351 |
bool operator<(Arc) const { return false; } |
|
352 |
|
|
353 |
}; |
|
354 | 354 |
/// This iterator goes through each directed arc. |
355 | 355 |
|
356 | 356 |
/// This iterator goes through each arc of a graph. |
357 | 357 |
/// Its usage is quite simple, for example you can count the number |
358 | 358 |
/// of arcs in a graph \c g of type \c Graph as follows: |
359 | 359 |
///\code |
... | ... |
@@ -375,40 +375,40 @@ |
375 | 375 |
/// Initialize the iterator to be invalid. |
376 | 376 |
|
377 | 377 |
/// Initialize the iterator to be invalid. |
378 | 378 |
/// |
379 | 379 |
ArcIt(Invalid) { } |
380 | 380 |
/// This constructor sets the iterator to the first arc. |
381 |
|
|
381 |
|
|
382 | 382 |
/// This constructor sets the iterator to the first arc of \c g. |
383 | 383 |
///@param g the graph |
384 | 384 |
ArcIt(const Graph &g) { ignore_unused_variable_warning(g); } |
385 | 385 |
/// Arc -> ArcIt conversion |
386 | 386 |
|
387 | 387 |
/// Sets the iterator to the value of the trivial iterator \c e. |
388 |
/// This feature necessitates that each time we |
|
388 |
/// This feature necessitates that each time we |
|
389 | 389 |
/// iterate the arc-set, the iteration order is the same. |
390 |
ArcIt(const Graph&, const Arc&) { } |
|
390 |
ArcIt(const Graph&, const Arc&) { } |
|
391 | 391 |
///Next arc |
392 |
|
|
392 |
|
|
393 | 393 |
/// Assign the iterator to the next arc. |
394 | 394 |
ArcIt& operator++() { return *this; } |
395 | 395 |
}; |
396 |
|
|
396 |
|
|
397 | 397 |
/// This iterator goes trough the outgoing directed arcs of a node. |
398 | 398 |
|
399 | 399 |
/// This iterator goes trough the \e outgoing arcs of a certain node |
400 | 400 |
/// of a graph. |
401 | 401 |
/// Its usage is quite simple, for example you can count the number |
402 | 402 |
/// of outgoing arcs of a node \c n |
403 | 403 |
/// in graph \c g of type \c Graph as follows. |
404 | 404 |
///\code |
405 | 405 |
/// int count=0; |
406 | 406 |
/// for (Graph::OutArcIt e(g, n); e!=INVALID; ++e) ++count; |
407 | 407 |
///\endcode |
408 |
|
|
408 |
|
|
409 | 409 |
class OutArcIt : public Arc { |
410 | 410 |
public: |
411 | 411 |
/// Default constructor |
412 | 412 |
|
413 | 413 |
/// @warning The default constructor sets the iterator |
414 | 414 |
/// to an undefined value. |
... | ... |
@@ -421,30 +421,30 @@ |
421 | 421 |
/// Initialize the iterator to be invalid. |
422 | 422 |
|
423 | 423 |
/// Initialize the iterator to be invalid. |
424 | 424 |
/// |
425 | 425 |
OutArcIt(Invalid) { } |
426 | 426 |
/// This constructor sets the iterator to the first outgoing arc. |
427 |
|
|
427 |
|
|
428 | 428 |
/// This constructor sets the iterator to the first outgoing arc of |
429 | 429 |
/// the node. |
430 | 430 |
///@param n the node |
431 | 431 |
///@param g the graph |
432 | 432 |
OutArcIt(const Graph& n, const Node& g) { |
433 |
ignore_unused_variable_warning(n); |
|
434 |
ignore_unused_variable_warning(g); |
|
435 |
|
|
433 |
ignore_unused_variable_warning(n); |
|
434 |
ignore_unused_variable_warning(g); |
|
435 |
} |
|
436 | 436 |
/// Arc -> OutArcIt conversion |
437 | 437 |
|
438 | 438 |
/// Sets the iterator to the value of the trivial iterator. |
439 |
|
|
439 |
/// This feature necessitates that each time we |
|
440 | 440 |
/// iterate the arc-set, the iteration order is the same. |
441 | 441 |
OutArcIt(const Graph&, const Arc&) { } |
442 | 442 |
///Next outgoing arc |
443 |
|
|
444 |
/// Assign the iterator to the next |
|
443 |
|
|
444 |
/// Assign the iterator to the next |
|
445 | 445 |
/// outgoing arc of the corresponding node. |
446 | 446 |
OutArcIt& operator++() { return *this; } |
447 | 447 |
}; |
448 | 448 |
|
449 | 449 |
/// This iterator goes trough the incoming directed arcs of a node. |
450 | 450 |
|
... | ... |
@@ -473,39 +473,39 @@ |
473 | 473 |
/// Initialize the iterator to be invalid. |
474 | 474 |
|
475 | 475 |
/// Initialize the iterator to be invalid. |
476 | 476 |
/// |
477 | 477 |
InArcIt(Invalid) { } |
478 | 478 |
/// This constructor sets the iterator to first incoming arc. |
479 |
|
|
479 |
|
|
480 | 480 |
/// This constructor set the iterator to the first incoming arc of |
481 | 481 |
/// the node. |
482 | 482 |
///@param n the node |
483 | 483 |
///@param g the graph |
484 |
InArcIt(const Graph& g, const Node& n) { |
|
485 |
ignore_unused_variable_warning(n); |
|
486 |
ignore_unused_variable_warning(g); |
|
487 |
} |
|
484 |
InArcIt(const Graph& g, const Node& n) { |
|
485 |
ignore_unused_variable_warning(n); |
|
486 |
ignore_unused_variable_warning(g); |
|
487 |
} |
|
488 | 488 |
/// Arc -> InArcIt conversion |
489 | 489 |
|
490 | 490 |
/// Sets the iterator to the value of the trivial iterator \c e. |
491 |
/// This feature necessitates that each time we |
|
491 |
/// This feature necessitates that each time we |
|
492 | 492 |
/// iterate the arc-set, the iteration order is the same. |
493 | 493 |
InArcIt(const Graph&, const Arc&) { } |
494 | 494 |
/// Next incoming arc |
495 | 495 |
|
496 | 496 |
/// Assign the iterator to the next inarc of the corresponding node. |
497 | 497 |
/// |
498 | 498 |
InArcIt& operator++() { return *this; } |
499 | 499 |
}; |
500 | 500 |
|
501 | 501 |
/// \brief Read write map of the nodes to type \c T. |
502 |
/// |
|
502 |
/// |
|
503 | 503 |
/// ReadWrite map of the nodes to type \c T. |
504 | 504 |
/// \sa Reference |
505 |
template<class T> |
|
505 |
template<class T> |
|
506 | 506 |
class NodeMap : public ReadWriteMap< Node, T > |
507 | 507 |
{ |
508 | 508 |
public: |
509 | 509 |
|
510 | 510 |
///\e |
511 | 511 |
NodeMap(const Graph&) { } |
... | ... |
@@ -513,80 +513,80 @@ |
513 | 513 |
NodeMap(const Graph&, T) { } |
514 | 514 |
|
515 | 515 |
///Copy constructor |
516 | 516 |
NodeMap(const NodeMap& nm) : ReadWriteMap< Node, T >(nm) { } |
517 | 517 |
///Assignment operator |
518 | 518 |
template <typename CMap> |
519 |
NodeMap& operator=(const CMap&) { |
|
519 |
NodeMap& operator=(const CMap&) { |
|
520 | 520 |
checkConcept<ReadMap<Node, T>, CMap>(); |
521 |
return *this; |
|
521 |
return *this; |
|
522 | 522 |
} |
523 | 523 |
}; |
524 | 524 |
|
525 | 525 |
/// \brief Read write map of the directed arcs to type \c T. |
526 | 526 |
/// |
527 | 527 |
/// Reference map of the directed arcs to type \c T. |
528 | 528 |
/// \sa Reference |
529 |
template<class T> |
|
529 |
template<class T> |
|
530 | 530 |
class ArcMap : public ReadWriteMap<Arc,T> |
531 | 531 |
{ |
532 | 532 |
public: |
533 | 533 |
|
534 | 534 |
///\e |
535 | 535 |
ArcMap(const Graph&) { } |
536 | 536 |
///\e |
537 | 537 |
ArcMap(const Graph&, T) { } |
538 | 538 |
///Copy constructor |
539 | 539 |
ArcMap(const ArcMap& em) : ReadWriteMap<Arc,T>(em) { } |
540 | 540 |
///Assignment operator |
541 | 541 |
template <typename CMap> |
542 |
ArcMap& operator=(const CMap&) { |
|
542 |
ArcMap& operator=(const CMap&) { |
|
543 | 543 |
checkConcept<ReadMap<Arc, T>, CMap>(); |
544 |
return *this; |
|
544 |
return *this; |
|
545 | 545 |
} |
546 | 546 |
}; |
547 | 547 |
|
548 | 548 |
/// Read write map of the edges to type \c T. |
549 | 549 |
|
550 | 550 |
/// Reference map of the arcs to type \c T. |
551 | 551 |
/// \sa Reference |
552 |
template<class T> |
|
552 |
template<class T> |
|
553 | 553 |
class EdgeMap : public ReadWriteMap<Edge,T> |
554 | 554 |
{ |
555 | 555 |
public: |
556 | 556 |
|
557 | 557 |
///\e |
558 | 558 |
EdgeMap(const Graph&) { } |
559 | 559 |
///\e |
560 | 560 |
EdgeMap(const Graph&, T) { } |
561 | 561 |
///Copy constructor |
562 | 562 |
EdgeMap(const EdgeMap& em) : ReadWriteMap<Edge,T>(em) {} |
563 | 563 |
///Assignment operator |
564 | 564 |
template <typename CMap> |
565 |
EdgeMap& operator=(const CMap&) { |
|
565 |
EdgeMap& operator=(const CMap&) { |
|
566 | 566 |
checkConcept<ReadMap<Edge, T>, CMap>(); |
567 |
return *this; |
|
567 |
return *this; |
|
568 | 568 |
} |
569 | 569 |
}; |
570 | 570 |
|
571 | 571 |
/// \brief Direct the given edge. |
572 | 572 |
/// |
573 | 573 |
/// Direct the given edge. The returned arc source |
574 | 574 |
/// will be the given node. |
575 | 575 |
Arc direct(const Edge&, const Node&) const { |
576 |
|
|
576 |
return INVALID; |
|
577 | 577 |
} |
578 | 578 |
|
579 | 579 |
/// \brief Direct the given edge. |
580 | 580 |
/// |
581 | 581 |
/// Direct the given edge. The returned arc |
582 | 582 |
/// represents the given edge and the direction comes |
583 | 583 |
/// from the bool parameter. The source of the edge and |
584 | 584 |
/// the directed arc is the same when the given bool is true. |
585 | 585 |
Arc direct(const Edge&, bool) const { |
586 |
|
|
586 |
return INVALID; |
|
587 | 587 |
} |
588 | 588 |
|
589 | 589 |
/// \brief Returns true if the arc has default orientation. |
590 | 590 |
/// |
591 | 591 |
/// Returns whether the given directed arc is same orientation as |
592 | 592 |
/// the corresponding edge's default orientation. |
... | ... |
@@ -622,43 +622,43 @@ |
622 | 622 |
Node source(Arc) const { return INVALID; } |
623 | 623 |
|
624 | 624 |
/// \brief Target node of the directed arc. |
625 | 625 |
Node target(Arc) const { return INVALID; } |
626 | 626 |
|
627 | 627 |
/// \brief Returns the id of the node. |
628 |
int id(Node) const { return -1; } |
|
628 |
int id(Node) const { return -1; } |
|
629 | 629 |
|
630 | 630 |
/// \brief Returns the id of the edge. |
631 |
int id(Edge) const { return -1; } |
|
631 |
int id(Edge) const { return -1; } |
|
632 | 632 |
|
633 | 633 |
/// \brief Returns the id of the arc. |
634 |
int id(Arc) const { return -1; } |
|
634 |
int id(Arc) const { return -1; } |
|
635 | 635 |
|
636 | 636 |
/// \brief Returns the node with the given id. |
637 | 637 |
/// |
638 | 638 |
/// \pre The argument should be a valid node id in the graph. |
639 |
Node nodeFromId(int) const { return INVALID; } |
|
639 |
Node nodeFromId(int) const { return INVALID; } |
|
640 | 640 |
|
641 | 641 |
/// \brief Returns the edge with the given id. |
642 | 642 |
/// |
643 | 643 |
/// \pre The argument should be a valid edge id in the graph. |
644 |
Edge edgeFromId(int) const { return INVALID; } |
|
644 |
Edge edgeFromId(int) const { return INVALID; } |
|
645 | 645 |
|
646 | 646 |
/// \brief Returns the arc with the given id. |
647 | 647 |
/// |
648 | 648 |
/// \pre The argument should be a valid arc id in the graph. |
649 |
Arc arcFromId(int) const { return INVALID; } |
|
649 |
Arc arcFromId(int) const { return INVALID; } |
|
650 | 650 |
|
651 | 651 |
/// \brief Returns an upper bound on the node IDs. |
652 |
int maxNodeId() const { return -1; } |
|
652 |
int maxNodeId() const { return -1; } |
|
653 | 653 |
|
654 | 654 |
/// \brief Returns an upper bound on the edge IDs. |
655 |
int maxEdgeId() const { return -1; } |
|
655 |
int maxEdgeId() const { return -1; } |
|
656 | 656 |
|
657 | 657 |
/// \brief Returns an upper bound on the arc IDs. |
658 |
int maxArcId() const { return -1; } |
|
658 |
int maxArcId() const { return -1; } |
|
659 | 659 |
|
660 | 660 |
void first(Node&) const {} |
661 | 661 |
void next(Node&) const {} |
662 | 662 |
|
663 | 663 |
void first(Edge&) const {} |
664 | 664 |
void next(Edge&) const {} |
... | ... |
@@ -680,67 +680,67 @@ |
680 | 680 |
// The second parameter is dummy. |
681 | 681 |
Edge fromId(int, Edge) const { return INVALID; } |
682 | 682 |
// The second parameter is dummy. |
683 | 683 |
Arc fromId(int, Arc) const { return INVALID; } |
684 | 684 |
|
685 | 685 |
// Dummy parameter. |
686 |
int maxId(Node) const { return -1; } |
|
686 |
int maxId(Node) const { return -1; } |
|
687 | 687 |
// Dummy parameter. |
688 |
int maxId(Edge) const { return -1; } |
|
688 |
int maxId(Edge) const { return -1; } |
|
689 | 689 |
// Dummy parameter. |
690 |
int maxId(Arc) const { return -1; } |
|
690 |
int maxId(Arc) const { return -1; } |
|
691 | 691 |
|
692 | 692 |
/// \brief Base node of the iterator |
693 | 693 |
/// |
694 | 694 |
/// Returns the base node (the source in this case) of the iterator |
695 | 695 |
Node baseNode(OutArcIt e) const { |
696 |
|
|
696 |
return source(e); |
|
697 | 697 |
} |
698 | 698 |
/// \brief Running node of the iterator |
699 | 699 |
/// |
700 | 700 |
/// Returns the running node (the target in this case) of the |
701 | 701 |
/// iterator |
702 | 702 |
Node runningNode(OutArcIt e) const { |
703 |
|
|
703 |
return target(e); |
|
704 | 704 |
} |
705 | 705 |
|
706 | 706 |
/// \brief Base node of the iterator |
707 | 707 |
/// |
708 | 708 |
/// Returns the base node (the target in this case) of the iterator |
709 | 709 |
Node baseNode(InArcIt e) const { |
710 |
|
|
710 |
return target(e); |
|
711 | 711 |
} |
712 | 712 |
/// \brief Running node of the iterator |
713 | 713 |
/// |
714 | 714 |
/// Returns the running node (the source in this case) of the |
715 | 715 |
/// iterator |
716 | 716 |
Node runningNode(InArcIt e) const { |
717 |
|
|
717 |
return source(e); |
|
718 | 718 |
} |
719 | 719 |
|
720 | 720 |
/// \brief Base node of the iterator |
721 | 721 |
/// |
722 | 722 |
/// Returns the base node of the iterator |
723 | 723 |
Node baseNode(IncEdgeIt) const { |
724 |
|
|
724 |
return INVALID; |
|
725 | 725 |
} |
726 |
|
|
726 |
|
|
727 | 727 |
/// \brief Running node of the iterator |
728 | 728 |
/// |
729 | 729 |
/// Returns the running node of the iterator |
730 | 730 |
Node runningNode(IncEdgeIt) const { |
731 |
|
|
731 |
return INVALID; |
|
732 | 732 |
} |
733 | 733 |
|
734 | 734 |
template <typename _Graph> |
735 | 735 |
struct Constraints { |
736 |
void constraints() { |
|
737 |
checkConcept<IterableGraphComponent<>, _Graph>(); |
|
738 |
checkConcept<IDableGraphComponent<>, _Graph>(); |
|
739 |
checkConcept<MappableGraphComponent<>, _Graph>(); |
|
740 |
|
|
736 |
void constraints() { |
|
737 |
checkConcept<IterableGraphComponent<>, _Graph>(); |
|
738 |
checkConcept<IDableGraphComponent<>, _Graph>(); |
|
739 |
checkConcept<MappableGraphComponent<>, _Graph>(); |
|
740 |
} |
|
741 | 741 |
}; |
742 | 742 |
|
743 | 743 |
}; |
744 | 744 |
|
745 | 745 |
} |
746 | 746 |
Changeset was too big and was cut off... Show full diff
0 comments (0 inline)