alpar@1118
|
1 |
namespace lemon {
|
deba@1114
|
2 |
/*!
|
deba@1114
|
3 |
|
deba@1114
|
4 |
|
deba@1114
|
5 |
|
deba@1114
|
6 |
\page graph-io-page Graph Input-Output
|
deba@1114
|
7 |
|
deba@1114
|
8 |
The standard graph IO makes possible to store graphs and additional maps
|
alpar@1118
|
9 |
in a flexible and efficient way.
|
deba@1114
|
10 |
|
deba@1114
|
11 |
\section format The general file format
|
deba@1114
|
12 |
|
deba@1114
|
13 |
The graph file contains at most four section in the next order:
|
deba@1114
|
14 |
|
deba@1114
|
15 |
\li nodeset
|
deba@1114
|
16 |
\li edgeset
|
deba@1114
|
17 |
\li nodes
|
deba@1114
|
18 |
\li edges
|
deba@1114
|
19 |
|
deba@1114
|
20 |
The nodeset section starts with the \c \@nodeset line.
|
deba@1114
|
21 |
The next line contains the names of the maps separated by whitespaces.
|
deba@1114
|
22 |
Each following line describes a node in the graph, it contains
|
deba@1114
|
23 |
in the right order the values of the maps. The first map should contain
|
deba@1114
|
24 |
unique values because it regarded as Id-map.
|
deba@1114
|
25 |
|
deba@1114
|
26 |
\code
|
deba@1114
|
27 |
@nodeset
|
deba@1114
|
28 |
id x-coord y-coord color
|
deba@1114
|
29 |
3 1.0 4.0 blue
|
deba@1114
|
30 |
5 2.3 5.7 red
|
deba@1114
|
31 |
12 7.8 2.3 green
|
deba@1114
|
32 |
\endcode
|
deba@1114
|
33 |
|
deba@1114
|
34 |
The edgeset section is very similar to the nodeset section, it has
|
deba@1114
|
35 |
same coloumn oriented structure. It starts with the line \c \@edgeset
|
deba@1114
|
36 |
The next line contains the whitespace separated list of names of the map.
|
alpar@1118
|
37 |
Each of the next lines describes one edge. The first two elements in the line
|
alpar@1118
|
38 |
are the ID of the source and target node as they occur in the first node map.
|
deba@1114
|
39 |
|
deba@1114
|
40 |
\code
|
deba@1114
|
41 |
@edgeset
|
deba@1114
|
42 |
id weight label
|
deba@1114
|
43 |
3 5 a 4.3 a-edge
|
deba@1114
|
44 |
5 12 c 2.6 c-edge
|
deba@1114
|
45 |
3 12 g 3.4 g-edge
|
deba@1114
|
46 |
\endcode
|
deba@1114
|
47 |
|
alpar@1118
|
48 |
The next section contains <em>labeles nodes</em> (i.e. nodes having a special
|
alpar@1118
|
49 |
label on them). The section starts with
|
deba@1114
|
50 |
\c \@nodes. Each of the next lines contains a label for a node in the graph
|
deba@1114
|
51 |
and then the ID described in the first column in the nodeset.
|
deba@1114
|
52 |
|
deba@1114
|
53 |
\code
|
deba@1114
|
54 |
@nodes
|
deba@1114
|
55 |
source 3
|
deba@1114
|
56 |
target 12
|
deba@1114
|
57 |
\endcode
|
deba@1114
|
58 |
|
alpar@1118
|
59 |
The last section describes the <em>labeles edges</em>
|
alpar@1118
|
60 |
(i.e. edges having a special
|
alpar@1118
|
61 |
label on them). It starts with \c \@edges
|
deba@1114
|
62 |
and then each line contains the name of the edge and the ID.
|
deba@1114
|
63 |
|
deba@1114
|
64 |
\code
|
deba@1114
|
65 |
@nodes
|
deba@1114
|
66 |
observed c
|
deba@1114
|
67 |
\endcode
|
deba@1114
|
68 |
|
deba@1114
|
69 |
The file ends with the \c \@end line.
|
deba@1114
|
70 |
|
deba@1114
|
71 |
The file may contain empty lines and comment lines. The comment lines
|
deba@1114
|
72 |
start with an \c # character.
|
deba@1114
|
73 |
|
deba@1114
|
74 |
\code
|
deba@1114
|
75 |
@end
|
deba@1114
|
76 |
\endcode
|
deba@1114
|
77 |
|
deba@1114
|
78 |
\section use Using graph input-output
|
deba@1114
|
79 |
The graph input and output based on writing and reading commands. The user
|
alpar@1118
|
80 |
adds writing and reading commands for the reader or writer class, then
|
alpar@1118
|
81 |
calls the \c run() method that executes all the given commands.
|
deba@1114
|
82 |
|
deba@1114
|
83 |
\subsection write Writing a graph
|
deba@1114
|
84 |
|
deba@1114
|
85 |
The \c GraphWriter class provides the graph output. To write a graph
|
deba@1114
|
86 |
you should first give writing commands for the writer. You can declare
|
alpar@1118
|
87 |
write command as \c NodeMap or \c EdgeMap writing and labeled Node and
|
deba@1114
|
88 |
Edge writing.
|
deba@1114
|
89 |
|
deba@1114
|
90 |
\code
|
deba@1114
|
91 |
GraphWriter<ListGraph> writer(graph);
|
deba@1114
|
92 |
\endcode
|
deba@1114
|
93 |
|
deba@1114
|
94 |
The \c addNodeMap() function declares a \c NodeMap writing command in the
|
deba@1114
|
95 |
\c GraphWriter. You should give as parameter the name of the map and the map
|
alpar@1118
|
96 |
object. The first NodeMap writing command should write a unique map because
|
deba@1114
|
97 |
it is regarded as ID map.
|
deba@1114
|
98 |
|
deba@1114
|
99 |
\see IdMap, DescriptorMap
|
deba@1114
|
100 |
|
deba@1114
|
101 |
\code
|
deba@1114
|
102 |
IdMap<ListGraph, Node> nodeIdMap;
|
deba@1114
|
103 |
writer.addNodeMap("id", nodeIdMap);
|
deba@1114
|
104 |
|
deba@1114
|
105 |
writer.addNodeMap("x-coord", xCoordMap);
|
deba@1114
|
106 |
writer.addNodeMap("y-coord", yCoordMap);
|
deba@1114
|
107 |
writer.addNodeMap("color", colorMap);
|
deba@1114
|
108 |
\endcode
|
deba@1114
|
109 |
|
deba@1114
|
110 |
With the \c addEdgeMap() member function you can give an edge map
|
deba@1114
|
111 |
writing command similar to the NodeMaps. The first map writing command should
|
deba@1114
|
112 |
write unique map.
|
deba@1114
|
113 |
|
deba@1114
|
114 |
\see IdMap, DescriptorMap
|
deba@1114
|
115 |
\code
|
deba@1114
|
116 |
DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> > edgeDescMap(graph);
|
deba@1114
|
117 |
writer.addEdgeMap("descriptor", edgeDescMap);
|
deba@1114
|
118 |
|
deba@1114
|
119 |
writer.addEdgeMap("weight", weightMap);
|
deba@1114
|
120 |
writer.addEdgeMap("label", labelMap);
|
deba@1114
|
121 |
\endcode
|
deba@1114
|
122 |
|
deba@1114
|
123 |
With \c addNode() and \c addEdge() functions you can point out Nodes and
|
deba@1114
|
124 |
Edges in the graph. By example, you can write out the source and target
|
deba@1114
|
125 |
of the graph.
|
deba@1114
|
126 |
|
deba@1114
|
127 |
\code
|
deba@1114
|
128 |
writer.addNode("source", sourceNode);
|
deba@1114
|
129 |
writer.addNode("target", targetNode);
|
deba@1114
|
130 |
|
deba@1114
|
131 |
writer.addEdge("observed", edge);
|
deba@1114
|
132 |
\endcode
|
deba@1114
|
133 |
|
deba@1114
|
134 |
After you give all write commands you must call the \c run() member
|
alpar@1118
|
135 |
function, which execute all the write commands.
|
deba@1114
|
136 |
|
deba@1114
|
137 |
\code
|
deba@1114
|
138 |
writer.run();
|
deba@1114
|
139 |
\endcode
|
deba@1114
|
140 |
|
deba@1114
|
141 |
\subsection reading Reading a graph
|
deba@1114
|
142 |
|
alpar@1118
|
143 |
The given file format may contain several maps and labeled nodes or edges.
|
deba@1114
|
144 |
If you read a graph you need not read all the maps and items just those
|
deba@1114
|
145 |
that you need. The interface of the \c GraphReader is very similar to
|
deba@1114
|
146 |
the GraphWriter but the reading method does not depend on the order the
|
deba@1114
|
147 |
given commands.
|
deba@1114
|
148 |
|
alpar@1118
|
149 |
The reader object suppose that each not readed value does not contain
|
alpar@1118
|
150 |
whitespaces, therefore it has some extra possibilities to control how
|
alpar@1118
|
151 |
it should skip the values when the string representation contains spaces.
|
deba@1114
|
152 |
|
deba@1114
|
153 |
\code
|
deba@1114
|
154 |
GraphReader<ListGraph> reader(graph);
|
deba@1114
|
155 |
\endcode
|
deba@1114
|
156 |
|
deba@1114
|
157 |
The \c addNodeMap() function reads a map from the \c \@nodeset section.
|
alpar@1118
|
158 |
If there is a map that you do not want to read from the file and there is
|
deba@1114
|
159 |
whitespace in the string represenation of the values then you should
|
deba@1114
|
160 |
call the \c skipNodeMap() template member function with proper parameters.
|
deba@1114
|
161 |
|
deba@1114
|
162 |
\see QuotedStringReader
|
deba@1114
|
163 |
\code
|
deba@1114
|
164 |
reader.addNodeMap("x-coord", xCoordMap);
|
deba@1114
|
165 |
reader.addNodeMap("y-coord", yCoordMap);
|
deba@1114
|
166 |
|
deba@1114
|
167 |
reader.addNodeMap<QuotedStringReader>("label", labelMap);
|
deba@1114
|
168 |
reader.skipNodeMap<QuotedStringReader>("description");
|
deba@1114
|
169 |
|
deba@1114
|
170 |
reader.addNodeMap("color", colorMap);
|
deba@1114
|
171 |
\endcode
|
deba@1114
|
172 |
|
deba@1114
|
173 |
With the \c addEdgeMap() member function you can give an edge map
|
deba@1114
|
174 |
reading command similar to the NodeMaps.
|
deba@1114
|
175 |
|
deba@1114
|
176 |
\code
|
deba@1114
|
177 |
reader.addEdgeMap("weight", weightMap);
|
deba@1114
|
178 |
reader.addEdgeMap("label", labelMap);
|
deba@1114
|
179 |
\endcode
|
deba@1114
|
180 |
|
alpar@1118
|
181 |
With \c addNode() and \c addEdge() functions you can read labeled Nodes and
|
deba@1114
|
182 |
Edges.
|
deba@1114
|
183 |
|
deba@1114
|
184 |
\code
|
deba@1114
|
185 |
reader.addNode("source", sourceNode);
|
deba@1114
|
186 |
reader.addNode("target", targetNode);
|
deba@1114
|
187 |
|
deba@1114
|
188 |
reader.addEdge("observed", edge);
|
deba@1114
|
189 |
\endcode
|
deba@1114
|
190 |
|
deba@1114
|
191 |
After you give all read commands you must call the \c run() member
|
alpar@1118
|
192 |
function, which execute all the commands.
|
deba@1114
|
193 |
|
deba@1114
|
194 |
\code
|
deba@1114
|
195 |
reader.run();
|
deba@1114
|
196 |
\endcode
|
deba@1114
|
197 |
|
deba@1114
|
198 |
\section types The background of the Reading and Writing
|
deba@1114
|
199 |
The \c GraphReader should know how can read a Value from the given map.
|
deba@1114
|
200 |
By the default implementation the input operator reads a value from
|
deba@1114
|
201 |
the stream and the type of the readed value is the value type of the given map.
|
deba@1114
|
202 |
When the reader should skip a value in the stream, because you do not
|
deba@1114
|
203 |
want to store it in map, the reader skips a character sequence without
|
deba@1114
|
204 |
whitespace.
|
deba@1114
|
205 |
|
deba@1114
|
206 |
If you want to change the functionality of the reader, you can use
|
deba@1114
|
207 |
template parameters to specialize it. When you give a reading
|
deba@1114
|
208 |
command for a map you can give a Reader type as template parameter.
|
deba@1114
|
209 |
With this template parameter you can control how does read the Reader
|
deba@1114
|
210 |
a value from the stream.
|
deba@1114
|
211 |
|
deba@1114
|
212 |
The reader has the next structure:
|
deba@1114
|
213 |
\code
|
deba@1114
|
214 |
struct TypeReader {
|
deba@1114
|
215 |
typedef TypeName Value;
|
deba@1114
|
216 |
|
deba@1114
|
217 |
void read(std::istream& is, Value& value);
|
deba@1114
|
218 |
};
|
deba@1114
|
219 |
\endcode
|
deba@1114
|
220 |
|
deba@1114
|
221 |
By example, the \c "strings" nodemap contains strings and you do not need
|
deba@1114
|
222 |
the value of the string just the length. Then you can implement own Reader
|
deba@1114
|
223 |
struct.
|
deba@1114
|
224 |
|
deba@1114
|
225 |
\code
|
deba@1114
|
226 |
struct LengthReader {
|
deba@1114
|
227 |
typedef int Value;
|
deba@1114
|
228 |
|
deba@1114
|
229 |
void read(std::istream& is, Value& value) {
|
deba@1114
|
230 |
std::string tmp;
|
deba@1114
|
231 |
is >> tmp;
|
deba@1114
|
232 |
value = tmp.length();
|
deba@1114
|
233 |
}
|
deba@1114
|
234 |
};
|
deba@1114
|
235 |
...
|
deba@1114
|
236 |
reader.addNodeMap<LengthReader>("strings", lengthMap);
|
deba@1114
|
237 |
\endcode
|
deba@1114
|
238 |
|
deba@1114
|
239 |
The global functionality of the reader class can be changed by giving a
|
alpar@1118
|
240 |
special template parameter for the GraphReader class. By default, the
|
alpar@1118
|
241 |
template parameter is \c DefaultReaderTraits. A reader traits class
|
deba@1114
|
242 |
should provide an inner template class Reader for each type, and an
|
deba@1114
|
243 |
DefaultReader for skipping a value.
|
deba@1114
|
244 |
|
deba@1114
|
245 |
The specialization of the writing should be very similar to the reading.
|
deba@1114
|
246 |
|
deba@1114
|
247 |
|
deba@1114
|
248 |
*/
|
alpar@1118
|
249 |
} |