Merge branch 'master' of git.tuebingen.mpg.de:libdai
[libdai.git] / tests / unit / graph_test.cpp
1 /* This file is part of libDAI - http://www.libdai.org/
2 *
3 * libDAI is licensed under the terms of the GNU General Public License version
4 * 2, or (at your option) any later version. libDAI is distributed without any
5 * warranty. See the file COPYING for more details.
6 *
7 * Copyright (C) 2010 Joris Mooij [joris dot mooij at libdai dot org]
8 */
9
10
11 #include <dai/graph.h>
12 #include <vector>
13 #include <strstream>
14
15
16 using namespace dai;
17
18
19 #define BOOST_TEST_MODULE GraphALTest
20
21
22 #include <boost/test/unit_test.hpp>
23
24
25 BOOST_AUTO_TEST_CASE( ConstructorsTest ) {
26 // check constructors
27 GraphAL G0;
28 BOOST_CHECK_EQUAL( G0.nrNodes(), 0 );
29 BOOST_CHECK_EQUAL( G0.nrEdges(), 0 );
30 BOOST_CHECK_EQUAL( G0.isConnected(), true );
31 BOOST_CHECK_EQUAL( G0.isTree(), true );
32 G0.checkConsistency();
33
34 GraphAL G2( 2 );
35 BOOST_CHECK_EQUAL( G2.nrNodes(), 2 );
36 BOOST_CHECK_EQUAL( G2.nrEdges(), 0 );
37 BOOST_CHECK_EQUAL( G2.isConnected(), false );
38 BOOST_CHECK_EQUAL( G2.isTree(), false );
39 G2.checkConsistency();
40 BOOST_CHECK( !(G2 == G0) );
41
42 typedef GraphAL::Edge Edge;
43 std::vector<Edge> edges;
44 edges.push_back( Edge( 0, 1 ) );
45 edges.push_back( Edge( 1, 2 ) );
46 edges.push_back( Edge( 2, 1 ) );
47 edges.push_back( Edge( 1, 2 ) );
48 GraphAL G3( 3, edges.begin(), edges.end() );
49 BOOST_CHECK_EQUAL( G3.nrNodes(), 3 );
50 BOOST_CHECK_EQUAL( G3.nrEdges(), 2 );
51 BOOST_CHECK_EQUAL( G3.isConnected(), true );
52 BOOST_CHECK_EQUAL( G3.isTree(), true );
53 G3.checkConsistency();
54 BOOST_CHECK( !(G3 == G0) );
55 BOOST_CHECK( !(G3 == G2) );
56
57 GraphAL G4( G3 );
58 BOOST_CHECK( !(G4 == G0) );
59 BOOST_CHECK( !(G4 == G2) );
60 BOOST_CHECK( G4 == G3 );
61
62 GraphAL G5 = G3;
63 BOOST_CHECK( !(G5 == G0) );
64 BOOST_CHECK( !(G5 == G2) );
65 BOOST_CHECK( G5 == G3 );
66 }
67
68
69 BOOST_AUTO_TEST_CASE( NeighborTest ) {
70 // check nb() accessor / mutator
71 typedef GraphAL::Edge Edge;
72 std::vector<Edge> edges;
73 edges.push_back( Edge( 0, 1 ) );
74 edges.push_back( Edge( 1, 2 ) );
75 GraphAL G( 3, edges.begin(), edges.end() );
76 BOOST_CHECK_EQUAL( G.nb(0).size(), 1 );
77 BOOST_CHECK_EQUAL( G.nb(1).size(), 2 );
78 BOOST_CHECK_EQUAL( G.nb(2).size(), 1 );
79 BOOST_CHECK_EQUAL( G.nb(0,0).iter, 0 );
80 BOOST_CHECK_EQUAL( G.nb(0,0).node, 1 );
81 BOOST_CHECK_EQUAL( G.nb(0,0).dual, 0 );
82 BOOST_CHECK_EQUAL( G.nb(1,0).iter, 0 );
83 BOOST_CHECK_EQUAL( G.nb(1,0).node, 0 );
84 BOOST_CHECK_EQUAL( G.nb(1,0).dual, 0 );
85 BOOST_CHECK_EQUAL( G.nb(1,1).iter, 1 );
86 BOOST_CHECK_EQUAL( G.nb(1,1).node, 2 );
87 BOOST_CHECK_EQUAL( G.nb(1,1).dual, 0 );
88 BOOST_CHECK_EQUAL( G.nb(2,0).iter, 0 );
89 BOOST_CHECK_EQUAL( G.nb(2,0).node, 1 );
90 BOOST_CHECK_EQUAL( G.nb(2,0).dual, 1 );
91 }
92
93
94 BOOST_AUTO_TEST_CASE( AddEraseTest ) {
95 // check addition and erasure of nodes and edges
96 typedef GraphAL::Edge Edge;
97 std::vector<Edge> edges;
98 edges.push_back( Edge( 0, 1 ) );
99 edges.push_back( Edge( 1, 2 ) );
100 edges.push_back( Edge( 1, 0 ) );
101 GraphAL G( 2 );
102 G.construct( 3, edges.begin(), edges.end() );
103 G.checkConsistency();
104 BOOST_CHECK_EQUAL( G.nrNodes(), 3 );
105 BOOST_CHECK_EQUAL( G.nrEdges(), 2 );
106 BOOST_CHECK_EQUAL( G.addNode(), 3 );
107 G.checkConsistency();
108 std::vector<size_t> nbs;
109 nbs.push_back( 3 );
110 BOOST_CHECK_EQUAL( G.addNode( nbs.begin(), nbs.end() ), 4 );
111 BOOST_CHECK_EQUAL( G.addNode(), 5 );
112 G.checkConsistency();
113 G.addEdge( 0, 4 );
114 G.checkConsistency();
115 G.addEdge( 0, 5 );
116 BOOST_CHECK( G.isTree() );
117 G.checkConsistency();
118 BOOST_CHECK_EQUAL( G.nrNodes(), 6 );
119 BOOST_CHECK_EQUAL( G.nrEdges(), 5 );
120 G.addEdge( 2, 3 );
121 BOOST_CHECK( !G.isTree() );
122
123 G.addEdge( 5, 3 );
124 G.eraseNode( 0 );
125 G.checkConsistency();
126 BOOST_CHECK( G.isTree() );
127 G.eraseEdge( 0, 1 );
128 G.checkConsistency();
129 BOOST_CHECK( !G.isTree() );
130 BOOST_CHECK( !G.isConnected() );
131 G.eraseNode( 0 );
132 G.checkConsistency();
133 BOOST_CHECK( G.isTree() );
134 G.addEdge( 3, 2 );
135 G.checkConsistency();
136 BOOST_CHECK( !G.isTree() );
137 G.eraseNode( 1 );
138 G.checkConsistency();
139 BOOST_CHECK( !G.isTree() );
140 BOOST_CHECK( !G.isConnected() );
141 G.eraseNode( 2 );
142 G.checkConsistency();
143 BOOST_CHECK( !G.isTree() );
144 BOOST_CHECK( !G.isConnected() );
145 G.addEdge( 1, 0 );
146 G.checkConsistency();
147 BOOST_CHECK( G.isTree() );
148 BOOST_CHECK( G.isConnected() );
149 G.eraseNode( 1 );
150 G.checkConsistency();
151 BOOST_CHECK( G.isTree() );
152 BOOST_CHECK( G.isConnected() );
153 G.eraseNode( 0 );
154 BOOST_CHECK( G.isTree() );
155 BOOST_CHECK( G.isConnected() );
156 BOOST_CHECK_EQUAL( G.nrNodes(), 0 );
157 BOOST_CHECK_EQUAL( G.nrEdges(), 0 );
158
159 G.addNode();
160 G.addNode();
161 G.addNode();
162 G.addNode();
163 G.addEdge( 0, 1 );
164 G.addEdge( 2, 3 );
165 G.addEdge( 0, 3 );
166 G.checkConsistency();
167 G.eraseNode( 2 );
168 G.checkConsistency();
169 }
170
171
172 BOOST_AUTO_TEST_CASE( RandomAddEraseTest ) {
173 // check adding and erasing nodes and edges randomly
174 GraphAL G;
175 for( size_t maxN = 2; maxN < 50; maxN++ )
176 for( size_t repeats = 0; repeats < 10000; repeats++ ) {
177 size_t action = rnd( 5 );
178 size_t N = G.nrNodes();
179 size_t M = G.nrEdges();
180 size_t maxM = N * (N - 1) / 2;
181 if( action == 0 ) {
182 // add node
183 if( N < maxN )
184 G.addNode();
185 } else if( action == 1 ) {
186 // erase node
187 if( N > 0 )
188 G.eraseNode( rnd( N ) );
189 } else if( action == 2 || action == 3 ) {
190 // add edge
191 if( N >= 2 && M < maxM ) {
192 size_t n1 = 0;
193 do {
194 n1 = rnd( N );
195 } while( G.nb(n1).size() >= N - 1 );
196 size_t n2 = 0;
197 do {
198 n2 = rnd( N );
199 } while( G.hasEdge( n1, n2 ) );
200 G.addEdge( n1, n2 );
201 }
202 } else if( action == 4 ) {
203 // erase edge
204 if( M > 0 ) {
205 size_t n1 = 0;
206 do {
207 n1 = rnd( N );
208 } while( G.nb(n1).size() == 0 );
209 size_t n2 = 0;
210 do {
211 n2 = rnd( N );
212 } while( !G.hasEdge( n1, n2 ) );
213 G.eraseEdge( n1, n2 );
214 }
215 }
216 G.checkConsistency();
217 }
218 }
219
220
221 BOOST_AUTO_TEST_CASE( QueriesAndCreationTest ) {
222 // check queries and createGraph* functions
223
224 // createGraphFull
225 for( size_t N = 0; N < 20; N++ ) {
226 GraphAL G = createGraphFull( N );
227 BOOST_CHECK_EQUAL( G.nrNodes(), N );
228 BOOST_CHECK_EQUAL( G.nrEdges(), N > 0 ? N * (N-1) / 2 : 0 );
229 BOOST_CHECK( G.isConnected() );
230 BOOST_CHECK_EQUAL( G.isTree(), N < 3 );
231 for( size_t n1 = 0; n1 < G.nrNodes(); n1++ ) {
232 foreach( const GraphAL::Neighbor &n2, G.nb(n1) ) {
233 BOOST_CHECK( G.hasEdge( n1, n2 ) );
234 BOOST_CHECK( G.hasEdge( n2, n1 ) );
235 }
236 for( size_t n2 = 0; n2 < G.nrNodes(); n2++ )
237 if( G.hasEdge( n1, n2 ) ) {
238 BOOST_CHECK_EQUAL( G.nb( n1, G.findNb( n1, n2 ) ), n2 );
239 BOOST_CHECK_EQUAL( G.nb( n2, G.findNb( n2, n1 ) ), n1 );
240 BOOST_CHECK_EQUAL( G.nb( n1, G.findNb( n1, n2 ) ).iter, G.findNb( n1, n2 ) );
241 BOOST_CHECK_EQUAL( G.nb( n2, G.findNb( n2, n1 ) ).iter, G.findNb( n2, n1 ) );
242 }
243 }
244 G.checkConsistency();
245 }
246
247 // createGraphGrid
248 for( size_t N1 = 0; N1 < 10; N1++ )
249 for( size_t N2 = 0; N2 < 10; N2++ ) {
250 GraphAL G = createGraphGrid( N1, N2, false );
251 BOOST_CHECK_EQUAL( G.nrNodes(), N1 * N2 );
252 BOOST_CHECK_EQUAL( G.nrEdges(), (N1 > 0 && N2 > 0) ? 2 * (N1-1) * (N2-1) + (N1-1) + (N2-1) : 0 );
253 BOOST_CHECK( G.isConnected() );
254 BOOST_CHECK_EQUAL( G.isTree(), (N1 <= 1) || (N2 <= 1) );
255 for( size_t n1 = 0; n1 < G.nrNodes(); n1++ ) {
256 foreach( const GraphAL::Neighbor &n2, G.nb(n1) ) {
257 BOOST_CHECK( G.hasEdge( n1, n2 ) );
258 BOOST_CHECK( G.hasEdge( n2, n1 ) );
259 }
260 for( size_t n2 = 0; n2 < G.nrNodes(); n2++ )
261 if( G.hasEdge( n1, n2 ) ) {
262 BOOST_CHECK_EQUAL( G.nb( n1, G.findNb( n1, n2 ) ), n2 );
263 BOOST_CHECK_EQUAL( G.nb( n2, G.findNb( n2, n1 ) ), n1 );
264 BOOST_CHECK_EQUAL( G.nb( n1, G.findNb( n1, n2 ) ).iter, G.findNb( n1, n2 ) );
265 BOOST_CHECK_EQUAL( G.nb( n2, G.findNb( n2, n1 ) ).iter, G.findNb( n2, n1 ) );
266 }
267 }
268 G.checkConsistency();
269
270 G = createGraphGrid( N1, N2, true );
271 BOOST_CHECK_EQUAL( G.nrNodes(), N1 * N2 );
272 if( N1 == 0 || N2 == 0 )
273 BOOST_CHECK_EQUAL( G.nrEdges(), 0 );
274 else
275 BOOST_CHECK_EQUAL( G.nrEdges(), (N1 <= 2 ? (N1-1) : N1) * N2 + N1 * (N2 <= 2 ? (N2-1) : N2) );
276 BOOST_CHECK( G.isConnected() );
277 BOOST_CHECK_EQUAL( G.isTree(), (G.nrNodes() <= 2) );
278 for( size_t n1 = 0; n1 < G.nrNodes(); n1++ ) {
279 foreach( const GraphAL::Neighbor &n2, G.nb(n1) ) {
280 BOOST_CHECK( G.hasEdge( n1, n2 ) );
281 BOOST_CHECK( G.hasEdge( n2, n1 ) );
282 }
283 for( size_t n2 = 0; n2 < G.nrNodes(); n2++ )
284 if( G.hasEdge( n1, n2 ) ) {
285 BOOST_CHECK_EQUAL( G.nb( n1, G.findNb( n1, n2 ) ), n2 );
286 BOOST_CHECK_EQUAL( G.nb( n2, G.findNb( n2, n1 ) ), n1 );
287 BOOST_CHECK_EQUAL( G.nb( n1, G.findNb( n1, n2 ) ).iter, G.findNb( n1, n2 ) );
288 BOOST_CHECK_EQUAL( G.nb( n2, G.findNb( n2, n1 ) ).iter, G.findNb( n2, n1 ) );
289 }
290 }
291 G.checkConsistency();
292 }
293
294 // createGraphGrid3D
295 for( size_t N1 = 0; N1 < 8; N1++ )
296 for( size_t N2 = 0; N2 < 8; N2++ )
297 for( size_t N3 = 0; N3 < 8; N3++ ) {
298 GraphAL G = createGraphGrid3D( N1, N2, N3, false );
299 BOOST_CHECK_EQUAL( G.nrNodes(), N1 * N2 * N3 );
300 BOOST_CHECK_EQUAL( G.nrEdges(), (N1 > 0 && N2 > 0 && N3 > 0) ? 3 * (N1-1) * (N2-1) * (N3-1) + 2 * (N1-1) * (N2-1) + 2 * (N1-1) * (N3-1) + 2 * (N2-1) * (N3-1) + (N1-1) + (N2-1) + (N3-1) : 0 );
301 BOOST_CHECK( G.isConnected() );
302 BOOST_CHECK_EQUAL( G.isTree(), (G.nrNodes() == 0) || (N1 <= 1 && N2 <= 1) || (N1 <= 1 && N3 <= 1) || (N2 <= 1 && N3 <= 1) );
303 for( size_t n1 = 0; n1 < G.nrNodes(); n1++ ) {
304 foreach( const GraphAL::Neighbor &n2, G.nb(n1) ) {
305 BOOST_CHECK( G.hasEdge( n1, n2 ) );
306 BOOST_CHECK( G.hasEdge( n2, n1 ) );
307 }
308 for( size_t n2 = 0; n2 < G.nrNodes(); n2++ )
309 if( G.hasEdge( n1, n2 ) ) {
310 BOOST_CHECK_EQUAL( G.nb( n1, G.findNb( n1, n2 ) ), n2 );
311 BOOST_CHECK_EQUAL( G.nb( n2, G.findNb( n2, n1 ) ), n1 );
312 BOOST_CHECK_EQUAL( G.nb( n1, G.findNb( n1, n2 ) ).iter, G.findNb( n1, n2 ) );
313 BOOST_CHECK_EQUAL( G.nb( n2, G.findNb( n2, n1 ) ).iter, G.findNb( n2, n1 ) );
314 }
315 }
316 G.checkConsistency();
317
318 G = createGraphGrid3D( N1, N2, N3, true );
319 BOOST_CHECK_EQUAL( G.nrNodes(), N1 * N2 * N3 );
320 if( N1 == 0 || N2 == 0 || N3 == 0 )
321 BOOST_CHECK_EQUAL( G.nrEdges(), 0 );
322 else
323 BOOST_CHECK_EQUAL( G.nrEdges(), (N1 <= 2 ? (N1-1) : N1) * N2 * N3 + N1 * (N2 <= 2 ? (N2-1) : N2) * N3 + N1 * N2 * (N3 <= 2 ? (N3-1) : N3) );
324 BOOST_CHECK( G.isConnected() );
325 BOOST_CHECK_EQUAL( G.isTree(), (G.nrNodes() <= 2) );
326 for( size_t n1 = 0; n1 < G.nrNodes(); n1++ ) {
327 foreach( const GraphAL::Neighbor &n2, G.nb(n1) ) {
328 BOOST_CHECK( G.hasEdge( n1, n2 ) );
329 BOOST_CHECK( G.hasEdge( n2, n1 ) );
330 }
331 for( size_t n2 = 0; n2 < G.nrNodes(); n2++ )
332 if( G.hasEdge( n1, n2 ) ) {
333 BOOST_CHECK_EQUAL( G.nb( n1, G.findNb( n1, n2 ) ), n2 );
334 BOOST_CHECK_EQUAL( G.nb( n2, G.findNb( n2, n1 ) ), n1 );
335 BOOST_CHECK_EQUAL( G.nb( n1, G.findNb( n1, n2 ) ).iter, G.findNb( n1, n2 ) );
336 BOOST_CHECK_EQUAL( G.nb( n2, G.findNb( n2, n1 ) ).iter, G.findNb( n2, n1 ) );
337 }
338 }
339 G.checkConsistency();
340 }
341
342 // createGraphLoop
343 for( size_t N = 0; N < 100; N++ ) {
344 GraphAL G = createGraphLoop( N );
345 BOOST_CHECK_EQUAL( G.nrNodes(), N );
346 if( N == 0 )
347 BOOST_CHECK_EQUAL( G.nrEdges(), 0 );
348 else if( N <= 2 )
349 BOOST_CHECK_EQUAL( G.nrEdges(), N-1 );
350 else
351 BOOST_CHECK_EQUAL( G.nrEdges(), N );
352 BOOST_CHECK( G.isConnected() );
353 BOOST_CHECK_EQUAL( G.isTree(), N <= 2 );
354 for( size_t n1 = 0; n1 < G.nrNodes(); n1++ ) {
355 foreach( const GraphAL::Neighbor &n2, G.nb(n1) ) {
356 BOOST_CHECK( G.hasEdge( n1, n2 ) );
357 BOOST_CHECK( G.hasEdge( n2, n1 ) );
358 }
359 for( size_t n2 = 0; n2 < G.nrNodes(); n2++ )
360 if( G.hasEdge( n1, n2 ) ) {
361 BOOST_CHECK_EQUAL( G.nb( n1, G.findNb( n1, n2 ) ), n2 );
362 BOOST_CHECK_EQUAL( G.nb( n2, G.findNb( n2, n1 ) ), n1 );
363 BOOST_CHECK_EQUAL( G.nb( n1, G.findNb( n1, n2 ) ).iter, G.findNb( n1, n2 ) );
364 BOOST_CHECK_EQUAL( G.nb( n2, G.findNb( n2, n1 ) ).iter, G.findNb( n2, n1 ) );
365 }
366 }
367 G.checkConsistency();
368 }
369
370 // createGraphTree
371 for( size_t N = 0; N < 100; N++ ) {
372 GraphAL G = createGraphTree( N );
373 BOOST_CHECK_EQUAL( G.nrNodes(), N );
374 BOOST_CHECK_EQUAL( G.nrEdges(), N > 0 ? N - 1 : N );
375 BOOST_CHECK( G.isConnected() );
376 BOOST_CHECK( G.isTree() );
377 for( size_t n1 = 0; n1 < G.nrNodes(); n1++ ) {
378 foreach( const GraphAL::Neighbor &n2, G.nb(n1) ) {
379 BOOST_CHECK( G.hasEdge( n1, n2 ) );
380 BOOST_CHECK( G.hasEdge( n2, n1 ) );
381 }
382 for( size_t n2 = 0; n2 < G.nrNodes(); n2++ )
383 if( G.hasEdge( n1, n2 ) ) {
384 BOOST_CHECK_EQUAL( G.nb( n1, G.findNb( n1, n2 ) ), n2 );
385 BOOST_CHECK_EQUAL( G.nb( n2, G.findNb( n2, n1 ) ), n1 );
386 BOOST_CHECK_EQUAL( G.nb( n1, G.findNb( n1, n2 ) ).iter, G.findNb( n1, n2 ) );
387 BOOST_CHECK_EQUAL( G.nb( n2, G.findNb( n2, n1 ) ).iter, G.findNb( n2, n1 ) );
388 }
389 }
390 G.checkConsistency();
391 }
392
393 // createGraphRegular
394 for( size_t N = 0; N < 50; N++ ) {
395 for( size_t d = 0; d < N && d <= 15; d++ ) {
396 if( (N * d) % 2 == 0 ) {
397 GraphAL G = createGraphRegular( N, d );
398 BOOST_CHECK_EQUAL( G.nrNodes(), N );
399 BOOST_CHECK_EQUAL( G.nrEdges(), d * N / 2 );
400 for( size_t n1 = 0; n1 < G.nrNodes(); n1++ ) {
401 BOOST_CHECK_EQUAL( G.nb(n1).size(), d );
402 foreach( const GraphAL::Neighbor &n2, G.nb(n1) ) {
403 BOOST_CHECK( G.hasEdge( n1, n2 ) );
404 BOOST_CHECK( G.hasEdge( n2, n1 ) );
405 }
406 for( size_t n2 = 0; n2 < G.nrNodes(); n2++ )
407 if( G.hasEdge( n1, n2 ) ) {
408 BOOST_CHECK_EQUAL( G.nb( n1, G.findNb( n1, n2 ) ), n2 );
409 BOOST_CHECK_EQUAL( G.nb( n2, G.findNb( n2, n1 ) ), n1 );
410 BOOST_CHECK_EQUAL( G.nb( n1, G.findNb( n1, n2 ) ).iter, G.findNb( n1, n2 ) );
411 BOOST_CHECK_EQUAL( G.nb( n2, G.findNb( n2, n1 ) ).iter, G.findNb( n2, n1 ) );
412 }
413 }
414 G.checkConsistency();
415 }
416 }
417 }
418 }
419
420
421 BOOST_AUTO_TEST_CASE( StreamTest ) {
422 // check printDot
423 GraphAL G( 4 );
424 G.addEdge( 0, 1 );
425 G.addEdge( 0, 2 );
426 G.addEdge( 1, 3 );
427 G.addEdge( 2, 3 );
428 G.addEdge( 2, 2 );
429 G.addEdge( 3, 2 );
430
431 std::stringstream ss;
432 std::string s;
433
434 G.printDot( ss );
435 std::getline( ss, s ); BOOST_CHECK_EQUAL( s, "graph GraphAL {" );
436 std::getline( ss, s ); BOOST_CHECK_EQUAL( s, "node[shape=circle,width=0.4,fixedsize=true];" );
437 std::getline( ss, s ); BOOST_CHECK_EQUAL( s, "\tx0;" );
438 std::getline( ss, s ); BOOST_CHECK_EQUAL( s, "\tx1;" );
439 std::getline( ss, s ); BOOST_CHECK_EQUAL( s, "\tx2;" );
440 std::getline( ss, s ); BOOST_CHECK_EQUAL( s, "\tx3;" );
441 std::getline( ss, s ); BOOST_CHECK_EQUAL( s, "\tx0 -- x1;" );
442 std::getline( ss, s ); BOOST_CHECK_EQUAL( s, "\tx0 -- x2;" );
443 std::getline( ss, s ); BOOST_CHECK_EQUAL( s, "\tx1 -- x3;" );
444 std::getline( ss, s ); BOOST_CHECK_EQUAL( s, "\tx2 -- x3;" );
445 std::getline( ss, s ); BOOST_CHECK_EQUAL( s, "}" );
446
447 ss << G;
448 std::getline( ss, s ); BOOST_CHECK_EQUAL( s, "graph GraphAL {" );
449 std::getline( ss, s ); BOOST_CHECK_EQUAL( s, "node[shape=circle,width=0.4,fixedsize=true];" );
450 std::getline( ss, s ); BOOST_CHECK_EQUAL( s, "\tx0;" );
451 std::getline( ss, s ); BOOST_CHECK_EQUAL( s, "\tx1;" );
452 std::getline( ss, s ); BOOST_CHECK_EQUAL( s, "\tx2;" );
453 std::getline( ss, s ); BOOST_CHECK_EQUAL( s, "\tx3;" );
454 std::getline( ss, s ); BOOST_CHECK_EQUAL( s, "\tx0 -- x1;" );
455 std::getline( ss, s ); BOOST_CHECK_EQUAL( s, "\tx0 -- x2;" );
456 std::getline( ss, s ); BOOST_CHECK_EQUAL( s, "\tx1 -- x3;" );
457 std::getline( ss, s ); BOOST_CHECK_EQUAL( s, "\tx2 -- x3;" );
458 std::getline( ss, s ); BOOST_CHECK_EQUAL( s, "}" );
459 }