alpar@2391
|
1 |
/* -*- C++ -*-
|
alpar@2391
|
2 |
*
|
alpar@2391
|
3 |
* This file is a part of LEMON, a generic C++ optimization library
|
alpar@2391
|
4 |
*
|
alpar@2553
|
5 |
* Copyright (C) 2003-2008
|
alpar@2391
|
6 |
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
|
alpar@2391
|
7 |
* (Egervary Research Group on Combinatorial Optimization, EGRES).
|
alpar@2391
|
8 |
*
|
alpar@2391
|
9 |
* Permission to use, modify and distribute this software is granted
|
alpar@2391
|
10 |
* provided that this copyright notice appears in all copies. For
|
alpar@2391
|
11 |
* precise terms see the accompanying LICENSE file.
|
alpar@2391
|
12 |
*
|
alpar@2391
|
13 |
* This software is provided "AS IS" with no warranty of any kind,
|
alpar@2391
|
14 |
* express or implied, and with no claim as to its suitability for any
|
alpar@2391
|
15 |
* purpose.
|
alpar@2391
|
16 |
*
|
alpar@2391
|
17 |
*/
|
alpar@2391
|
18 |
|
alpar@2216
|
19 |
namespace lemon {
|
alpar@2216
|
20 |
/*!
|
alpar@2216
|
21 |
\page read_write_bg Background of Reading and Writing
|
alpar@2216
|
22 |
|
alpar@2216
|
23 |
To read a map (on the nodes or edges)
|
alpar@2216
|
24 |
the \ref lemon::GraphReader "GraphReader"
|
alpar@2216
|
25 |
should know how to read a Value from the given map.
|
alpar@2216
|
26 |
By the default implementation the input operator reads a value from
|
alpar@2216
|
27 |
the stream and the type of the read value is the value type of the given map.
|
alpar@2216
|
28 |
When the reader should skip a value in the stream, because you do not
|
alpar@2216
|
29 |
want to store it in a map, the reader skips a character sequence without
|
alpar@2216
|
30 |
whitespaces.
|
alpar@2216
|
31 |
|
alpar@2216
|
32 |
If you want to change the functionality of the reader, you can use
|
alpar@2216
|
33 |
template parameters to specialize it. When you give a reading
|
alpar@2216
|
34 |
command for a map you can give a Reader type as template parameter.
|
alpar@2216
|
35 |
With this template parameter you can control how the Reader reads
|
alpar@2216
|
36 |
a value from the stream.
|
alpar@2216
|
37 |
|
alpar@2216
|
38 |
The reader has the next structure:
|
alpar@2216
|
39 |
\code
|
alpar@2216
|
40 |
struct TypeReader {
|
alpar@2216
|
41 |
typedef TypeName Value;
|
alpar@2216
|
42 |
|
alpar@2216
|
43 |
void read(std::istream& is, Value& value);
|
alpar@2216
|
44 |
};
|
alpar@2216
|
45 |
\endcode
|
alpar@2216
|
46 |
|
alpar@2216
|
47 |
For example, the \c "strings" nodemap contains strings and you do not need
|
alpar@2216
|
48 |
the value of the string just the length. Then you can implement an own Reader
|
alpar@2216
|
49 |
struct.
|
alpar@2216
|
50 |
|
alpar@2216
|
51 |
\code
|
alpar@2216
|
52 |
struct LengthReader {
|
alpar@2216
|
53 |
typedef int Value;
|
alpar@2216
|
54 |
|
alpar@2216
|
55 |
void read(std::istream& is, Value& value) {
|
alpar@2216
|
56 |
std::string tmp;
|
alpar@2216
|
57 |
is >> tmp;
|
alpar@2216
|
58 |
value = tmp.length();
|
alpar@2216
|
59 |
}
|
alpar@2216
|
60 |
};
|
alpar@2216
|
61 |
...
|
alpar@2216
|
62 |
reader.readNodeMap<LengthReader>("strings", lengthMap);
|
alpar@2216
|
63 |
\endcode
|
alpar@2216
|
64 |
|
alpar@2216
|
65 |
The global functionality of the reader class can be changed by giving a
|
alpar@2216
|
66 |
special template parameter to the GraphReader class. By default, the
|
alpar@2216
|
67 |
template parameter is \c DefaultReaderTraits. A reader traits class
|
alpar@2216
|
68 |
should provide a nested template class Reader for each type, and a
|
alpar@2216
|
69 |
DefaultReader for skipping a value.
|
alpar@2216
|
70 |
|
alpar@2216
|
71 |
The specialization of writing is very similar to that of reading.
|
alpar@2216
|
72 |
|
alpar@2216
|
73 |
\section u Undirected graphs
|
alpar@2216
|
74 |
|
alpar@2216
|
75 |
In a file describing an undirected graph (ugraph, for short) you find an
|
alpar@2216
|
76 |
\c uedgeset section instead of the \c edgeset section. The first line of
|
alpar@2216
|
77 |
the section describes the names of the maps on the undirected egdes and all
|
alpar@2216
|
78 |
next lines describe one undirected edge with the the incident nodes and the
|
alpar@2216
|
79 |
values of the map.
|
alpar@2216
|
80 |
|
alpar@2216
|
81 |
The format handles directed edge maps as a syntactical sugar???, if there
|
alpar@2216
|
82 |
are two maps with names being the same with a \c '+' and a \c '-' prefix
|
alpar@2216
|
83 |
then this will be read as a directed map.
|
alpar@2216
|
84 |
|
alpar@2216
|
85 |
\code
|
alpar@2216
|
86 |
@uedgeset
|
alpar@2216
|
87 |
label capacity +flow -flow
|
alpar@2216
|
88 |
32 2 1 4.3 2.0 0.0
|
alpar@2216
|
89 |
21 21 5 2.6 0.0 2.6
|
alpar@2216
|
90 |
21 12 8 3.4 0.0 0.0
|
alpar@2216
|
91 |
\endcode
|
alpar@2216
|
92 |
|
alpar@2216
|
93 |
The \c edges section is changed to \c uedges section. This section
|
alpar@2216
|
94 |
describes labeled edges and undirected edges. The directed edge label
|
alpar@2216
|
95 |
should start with a \c '+' or a \c '-' prefix to decide the direction
|
alpar@2216
|
96 |
of the edge.
|
alpar@2216
|
97 |
|
alpar@2216
|
98 |
\code
|
alpar@2216
|
99 |
@uedges
|
alpar@2216
|
100 |
uedge 1
|
alpar@2216
|
101 |
+edge 5
|
alpar@2216
|
102 |
-back 5
|
alpar@2216
|
103 |
\endcode
|
alpar@2216
|
104 |
|
alpar@2216
|
105 |
There are similar classes to the \ref lemon::GraphReader "GraphReader" and
|
alpar@2216
|
106 |
\ref lemon::GraphWriter "GraphWriter" which
|
alpar@2216
|
107 |
handle the undirected graphs. These classes are
|
alpar@2216
|
108 |
the \ref lemon::UGraphReader "UGraphReader"
|
alpar@2216
|
109 |
and \ref lemon::UGraphWriter "UGraphWriter".
|
alpar@2216
|
110 |
|
alpar@2216
|
111 |
The \ref lemon::UGraphReader::readUEdgeMap() "readUEdgeMap()"
|
alpar@2216
|
112 |
function reads an undirected map and the
|
alpar@2216
|
113 |
\ref lemon::UGraphReader::readUEdge() "readUEdge()"
|
alpar@2216
|
114 |
reads an undirected edge from the file,
|
alpar@2216
|
115 |
|
alpar@2216
|
116 |
\code
|
alpar@2216
|
117 |
reader.readUEdgeMap("capacity", capacityMap);
|
alpar@2216
|
118 |
reader.readEdgeMap("flow", flowMap);
|
alpar@2216
|
119 |
...
|
alpar@2216
|
120 |
reader.readUEdge("u_edge", u_edge);
|
alpar@2216
|
121 |
reader.readEdge("edge", edge);
|
alpar@2216
|
122 |
\endcode
|
alpar@2216
|
123 |
|
alpar@2216
|
124 |
\section advanced Advanced features
|
alpar@2216
|
125 |
|
alpar@2216
|
126 |
The graph reader and writer classes give an easy way to read and write
|
alpar@2216
|
127 |
graphs. But sometimes we want more advanced features. In this case we can
|
alpar@2216
|
128 |
use the more general <tt>lemon reader and writer</tt> interface.
|
alpar@2216
|
129 |
|
alpar@2216
|
130 |
The LEMON file format is a section oriented file format. It contains one or
|
alpar@2216
|
131 |
more sections, each starting with a line identifying its type
|
alpar@2216
|
132 |
(the word starting with the \c \@ character).
|
alpar@2216
|
133 |
The content of the section this way cannot contain line with \c \@ first
|
alpar@2216
|
134 |
character. The file may contains comment lines with \c # first character.
|
alpar@2216
|
135 |
|
alpar@2216
|
136 |
The \ref lemon::LemonReader "LemonReader"
|
alpar@2216
|
137 |
and \ref lemon::LemonWriter "LemonWriter"
|
alpar@2216
|
138 |
gives a framework to read and
|
alpar@2216
|
139 |
write sections. There are various section reader and section writer
|
alpar@2216
|
140 |
classes which can be attached to a \ref lemon::LemonReader "LemonReader"
|
alpar@2216
|
141 |
or a \ref lemon::LemonWriter "LemonWriter".
|
alpar@2216
|
142 |
|
alpar@2216
|
143 |
There are default section readers and writers for reading and writing
|
alpar@2216
|
144 |
item sets, and labeled items in the graph. These read and write
|
alpar@2216
|
145 |
the format described above. Other type of data can be handled with own
|
alpar@2216
|
146 |
section reader and writer classes which are inherited from the
|
alpar@2216
|
147 |
\c LemonReader::SectionReader or the
|
alpar@2216
|
148 |
\ref lemon::LemonWriter::SectionWriter "LemonWriter::SectionWriter"
|
alpar@2216
|
149 |
classes.
|
alpar@2216
|
150 |
|
alpar@2216
|
151 |
The next example defines a special section reader which reads the
|
alpar@2216
|
152 |
\c \@description sections into a string:
|
alpar@2216
|
153 |
|
alpar@2216
|
154 |
\code
|
alpar@2216
|
155 |
class DescriptionReader : LemonReader::SectionReader {
|
alpar@2216
|
156 |
protected:
|
alpar@2216
|
157 |
virtual bool header(const std::string& line) {
|
alpar@2216
|
158 |
std::istringstream ls(line);
|
alpar@2216
|
159 |
std::string head;
|
alpar@2216
|
160 |
ls >> head;
|
alpar@2216
|
161 |
return head == "@description";
|
alpar@2216
|
162 |
}
|
alpar@2216
|
163 |
|
alpar@2216
|
164 |
virtual void read(std::istream& is) {
|
alpar@2216
|
165 |
std::string line;
|
alpar@2216
|
166 |
while (getline(is, line)) {
|
alpar@2216
|
167 |
desc += line;
|
alpar@2216
|
168 |
}
|
alpar@2216
|
169 |
}
|
alpar@2216
|
170 |
public:
|
alpar@2216
|
171 |
|
alpar@2216
|
172 |
typedef LemonReader::SectionReader Parent;
|
alpar@2216
|
173 |
|
alpar@2216
|
174 |
DescriptionReader(LemonReader& reader) : Parent(reader) {}
|
alpar@2216
|
175 |
|
alpar@2216
|
176 |
const std::string& description() const {
|
alpar@2216
|
177 |
return description;
|
alpar@2216
|
178 |
}
|
alpar@2216
|
179 |
|
alpar@2216
|
180 |
private:
|
alpar@2216
|
181 |
std::string desc;
|
alpar@2216
|
182 |
};
|
alpar@2216
|
183 |
\endcode
|
alpar@2216
|
184 |
|
alpar@2216
|
185 |
The other advanced stuff of the generalized file format is that
|
alpar@2216
|
186 |
multiple edgesets can be stored to the same nodeset. It can be used
|
alpar@2216
|
187 |
for example as a network traffic matrix.
|
alpar@2216
|
188 |
|
alpar@2216
|
189 |
In our example there is a network with symmetric links and there are assymetric
|
alpar@2216
|
190 |
traffic request on the network. This construction can be stored in an
|
alpar@2216
|
191 |
undirected graph and in a directed \c ListEdgeSet class. The example
|
alpar@2216
|
192 |
shows the input with the \ref lemon::LemonReader "LemonReader" class:
|
alpar@2216
|
193 |
|
alpar@2216
|
194 |
\code
|
alpar@2216
|
195 |
ListUGraph network;
|
alpar@2216
|
196 |
ListUGraph::UEdgeMap<double> capacity;
|
alpar@2216
|
197 |
ListEdgeSet<ListUGraph> traffic(network);
|
alpar@2216
|
198 |
ListEdgeSet<ListUGraph>::EdgeMap<double> request(network);
|
alpar@2216
|
199 |
|
alpar@2216
|
200 |
LemonReader reader(std::cin);
|
alpar@2216
|
201 |
NodeSetReader<ListUGraph> nodesetReader(reader, network);
|
alpar@2216
|
202 |
UEdgeSetReader<ListUGraph>
|
alpar@2216
|
203 |
uEdgesetReader(reader, network, nodesetReader);
|
alpar@2216
|
204 |
uEdgesetReader.readEdgeMap("capacity", capacity);
|
alpar@2216
|
205 |
EdgeSetReader<ListEdgeSet<ListUGraph> >
|
alpar@2216
|
206 |
edgesetReader(reader, traffic, nodesetReader, "traffic");
|
alpar@2216
|
207 |
edgesetReader.readEdgeMap("request", request);
|
alpar@2216
|
208 |
|
alpar@2216
|
209 |
reader.run();
|
alpar@2216
|
210 |
\endcode
|
alpar@2216
|
211 |
|
alpar@2216
|
212 |
Because both the \ref lemon::GraphReader "GraphReader"
|
alpar@2216
|
213 |
and the \ref lemon::UGraphReader "UGraphReader" can be converted
|
alpar@2216
|
214 |
to \ref lemon::LemonReader "LemonReader"
|
alpar@2216
|
215 |
and it can resolve the label's of the items, the previous
|
alpar@2216
|
216 |
result can be achived with the \ref lemon::UGraphReader "UGraphReader"
|
alpar@2216
|
217 |
class, too.
|
alpar@2216
|
218 |
|
alpar@2216
|
219 |
|
alpar@2216
|
220 |
\code
|
alpar@2216
|
221 |
ListUGraph network;
|
alpar@2216
|
222 |
ListUGraph::UEdgeSet<double> capacity;
|
alpar@2216
|
223 |
ListEdgeSet<ListUGraph> traffic(network);
|
alpar@2216
|
224 |
ListEdgeSet<ListUGraph>::EdgeMap<double> request(network);
|
alpar@2216
|
225 |
|
alpar@2216
|
226 |
UGraphReader<ListUGraph> reader(std::cin, network);
|
alpar@2216
|
227 |
reader.readEdgeMap("capacity", capacity);
|
alpar@2216
|
228 |
EdgeSetReader<ListEdgeSet<ListUGraph> >
|
alpar@2216
|
229 |
edgesetReader(reader, traffic, reader, "traffic");
|
alpar@2216
|
230 |
edgesetReader.readEdgeMap("request", request);
|
alpar@2216
|
231 |
|
alpar@2216
|
232 |
reader.run();
|
alpar@2216
|
233 |
\endcode
|
alpar@2216
|
234 |
|
alpar@2216
|
235 |
\author Balazs Dezso
|
alpar@2216
|
236 |
*/
|
alpar@2216
|
237 |
}
|