00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "BUnit.h"
00011 #include "ADH_Graph.h"
00012 #include "ADH_Graph_Lib.h"
00013 #include <algorithm>
00014
00015 namespace ADH {
00016
00017
00018 class test_Graph : public TestCase {
00019 bool m_cycle;
00020 Graph G;
00021 public:
00022 test_Graph() : G(), m_cycle(false) {}
00023 void test_connected();
00024 void test_connected_cycle();
00025 void test_isVertex();
00026 void test_vertexList();
00027 void setUp();
00028 void do_cout( std::ostream & COUT );
00029 void do_dump( std::ostream & COUT );
00030 void test_Rep_const_iterator();
00031 void test_isConnected();
00032 void test_isCircuit();
00033 void test_spanningTree();
00034 bool run();
00035 void set_cycles( bool v ) {
00036 m_cycle = v;
00037 }
00038 };
00039
00040
00041 bool test_Graph::run() {
00042 test_connected();
00043 if ( m_cycle ) { test_connected_cycle(); }
00044 test_isVertex();
00045 test_vertexList();
00046 test_Rep_const_iterator();
00047 test_isConnected();
00048 test_isCircuit();
00049 test_spanningTree();
00050 return wasSuccessful();
00051 }
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 void test_Graph::setUp() {
00065 G.set("F", "A(1)", 2 ); G.set( "A(1)", "B", 2 );
00066 G.set("F", "A(2)", 8 ); G.set( "A(2)", "B", 8 );
00067 G.set("F", "A(3)", 64 ); G.set( "A(3)", "B", 64 );
00068
00069 G.set("B", "C(1)", 3 ); G.set( "C(1)", "D", 3 );
00070 G.set("B", "C(2)", 27 ); G.set( "C(2)", "D", 27 );
00071
00072 G.set("O(1)", "O(2)", 2*2*2 );
00073 G.set("O(2)", "O(3)", 3*3*3 );
00074 G.set("O(3)", "O(4)", 5*5*5 );
00075 G.set("O(4)", "O(1)", 7*7*7 );
00076 }
00077
00078
00079 void test_Graph::do_cout( std::ostream & COUT ) {
00080 COUT << G;
00081 }
00082
00083
00084 void test_Graph::do_dump( std::ostream & COUT ) {
00085 Graph G;
00086 G.set("O(1)", "O(2)", 2*2*2 );
00087 G.set("O(2)", "O(3)", 3*3*3 );
00088 G.set("O(3)", "O(4)", 5*5*5 );
00089 G.set("O(4)", "O(1)", 7*7*7 );
00090 ADH::dump( COUT , G );
00091 }
00092
00093
00094 void test_Graph::test_Rep_const_iterator() {
00095 {{
00096 Graph Tree;
00097 Tree.set("root", "child(1)", 1 );
00098 Tree.set("root", "child(2)", 2*2 );
00099 Tree.set("root", "child(3)", 3*3*3);
00100 Graph::Rep_const_iterator it, jt; int val = int();
00101 for ( it = Tree.begin_Rep() ; it != Tree.end_Rep() ; ++it ) {
00102 for ( jt = Tree.begin_Rep() ; jt != Tree.end_Rep() ; ++jt ) {
00103 if ( Tree.isArc( it->first , jt->first , val ) ) {
00104 assertTrue( it->first == "root" );
00105 assertTrue( jt->first.substr(0,5) == "child" );
00106 }
00107 }
00108 }
00109 }}
00110 }
00111
00112
00113 void test_Graph::test_connected() {
00114 {{
00115 std::list< std::string > C;
00116 std::list< std::string >::iterator it;
00117
00118 assertTrue( ! connected( G , "???" , "???", C ) );
00119 assertTrue( ! connected( G , "F" , "O(4)", C ) );
00120 assertTrue( C.size() == 0 );
00121 assertTrue( ! connected( G , "D" , "F" , C ) );
00122 assertTrue( C.size() == 0 );
00123
00124 assertTrue( connected( G , "F" , "F", C ) );
00125 assertTrue( C.size() == 1 && C.front() == "F" );
00126
00127 assertTrue( ! connected( G , "D", "A(2)" , C ) ); assertTrue( C.size() == 0 );
00128 assertTrue( connected( G , "A(2)" , "D", C ) ); assertTrue( C.size() == 4 );
00129 assertTrue( C.front() == "A(2)" && C.back() == "D" );
00130 it = C.begin(); it++;
00131 assertTrue( *it == "B" );
00132 it++;
00133 assertTrue( *it == "C(1)" || *it == "C(2)" );
00134 }}
00135 {
00136 std::list< std::string > C;
00137 std::list< std::string >::iterator it;
00138 assertTrue( connected( G , "A(2)", "B" , C ) );
00139 assertTrue( C.size() == 2 );
00140 assertTrue( C.front() == "A(2)" && C.back() == "B" );
00141
00142 assertTrue( connected( G , "A(2)", "C(2)" , C ) );
00143 assertTrue( C.size() == 3 );
00144 assertTrue( C.front() == "A(2)" && C.back() == "C(2)" );
00145 }
00146 {
00147 std::list< std::string > C;
00148 std::list< std::string >::iterator it;
00149 assertTrue( ! connected( G , "D", "F" , C ) ); assertTrue( C.size() == 0 );
00150 assertTrue( connected( G , "F", "D" , C ) ); assertTrue( C.size() == 5 );
00151 assertTrue( C.front() == "F" && C.back() == "D" );
00152 it = C.begin();
00153 assertTrue( *it == "F" );
00154 it++;
00155 assertTrue( *it == "A(1)" || *it == "A(2)" || *it == "A(3)" );
00156 it++;
00157 assertTrue( *it == "B" );
00158 it++;
00159 assertTrue( *it == "C(1)" || *it == "C(2)" );
00160 it++;
00161 assertTrue( *it == "D" );
00162 }
00163 {
00164 ADH::Graph G;
00165 G.set( "1", "2", 2 ); {
00166 G.set( "2", "4", 4 ); {
00167 G.set( "4", "8", 8 );
00168 G.set( "4", "9", 9 );
00169 }
00170 G.set( "2", "5", 5 ); {
00171 G.set( "5", "10", 10 );
00172 G.set( "5", "11", 11 );
00173 }
00174 }
00175 G.set( "1", "3", 3 ); {
00176 G.set( "3", "6", 6 ); {
00177 G.set( "6", "12", 12 );
00178 G.set( "6", "13", 13 );
00179 }
00180 G.set( "3", "7", 7 ); {
00181 G.set( "7", "14", 14 );
00182 G.set( "7", "15", 15 );
00183 }
00184 }
00185 using namespace std;
00186 list< string > C; int val, i, j, k, n;
00187 for ( i=2; i<16; ++i ) {
00188 string i_str = TestCase::toString(i);
00189 for ( j=2; j<16; ++j ) {
00190 val = 666; C.clear(); C.push_back( "???" );
00191 string j_str = TestCase::toString(j), k_str;
00192 if ( i==j ) {
00193 assertTrue( ! G.isArc ( i_str , j_str, val ) );
00194 assertTrue( val == 666 && "unchanged val" );
00195 assertTrue_Msg( "connected( G ,"+i_str+" , "+j_str+')', connected( G , i_str , j_str , C ) );
00196 assertTrue( C.size() >= 1 && C.front() == i_str );
00197 assertTrue( ! connected( G , i_str , "1", C ) );
00198 assertTrue( C.empty() );
00199 assertTrue_Msg( "connected( G , 1 , "+i_str+')', connected( G , "1" , i_str , C ) );
00200 assertTrue( C.size() >= 1 && C.back() == i_str );
00201 }
00202 else if ( i < j ) {
00203 for ( (n=1, k=j); k>0 ; (k/=2,++n) ) {
00204 k_str = TestCase::toString(k);
00205 assertTrue_Msg( "connected( G ,"+k_str+" , "+j_str+')' ,
00206 connected( G , k_str , j_str , C ) );
00207 assertTrue_Msg( "C.front() == "+k_str+ " && C.back() == "+j_str ,
00208 ( C.front() == k_str && C.back() == j_str ) );
00209 assertTrue( C.size() == n );
00210 if ( k != j ) {
00211 assertTrue_Msg( "! connected( G ,"+j_str+" , "+k_str+')' ,
00212 ! connected( G , j_str , k_str , C ) );
00213 assertTrue( C.empty() );
00214 }
00215 }
00216 }
00217 }
00218 }
00219 }
00220 }
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235 void test_Graph::test_connected_cycle() {
00236 Graph G = test_Graph::G;
00237
00238 G.set( "C(1)" , "A(1)", 800 );
00239
00240 G.set( "D" , "C(1)", 1492 );
00241 std::list< std::string > C;
00242 assertTrue( ! connected( G , "D", "F" , C ) ); assertTrue( C.size() == 0 );
00243
00244 assertTrue( connected( G , "A(1)", "D" , C ) ); assertTrue( C.size() >= 4 );
00245 assertTrue( connected( G , "D", "A(1)" , C ) ); assertTrue( C.size() >= 3 );
00246
00247 assertTrue( connected( G , "A(1)", "B" , C ) ); assertTrue( C.size() >= 2 );
00248 assertTrue( connected( G , "B", "A(1)" , C ) ); assertTrue( C.size() >= 3 );
00249
00250 assertTrue( connected( G , "A(1)", "C(2)" , C ) ); assertTrue( C.size() >= 3 );
00251 assertTrue( connected( G , "C(2)", "A(1)" , C ) ); assertTrue( C.size() >= 4 );
00252 }
00253
00254
00255 void test_Graph::test_isVertex() {
00256 {{
00257 Graph G; int val = 666;
00258 G.set( "F", "D", 2*2*2 );
00259 assertTrue( G.isVertex( "F" ) ) ;
00260 assertTrue( G.isVertex( "D" ) ) ;
00261 assertTrue( val == 666 && "initial val" );
00262 assertTrue( G.isArc( "F" , "D", val ) );
00263 assertTrue( val == 2*2*2 && "returned val" );
00264 val = 666;
00265 assertTrue( ! G.isArc( "D" , "F", val ) );
00266 assertTrue( val == 666 && "unchanged val" );
00267 }}
00268 { Graph::Rep::const_iterator it = G.m_DICC.begin();
00269 for ( ; it != G.m_DICC.end(); ++it ) {
00270 assertTrue( G.isVertex( it->first ) ) ;
00271 assertTrue( ! G.isVertex( it->first + "chungis") ) ;
00272 }
00273 }
00274 { int val;
00275 Graph::Rep::const_iterator it = G.m_DICC.begin();
00276 for ( ; it != G.m_DICC.begin(); ++it ) {
00277 Graph::mapped_type::const_iterator jt = it->second.begin();
00278 for ( ; jt != it->second.end(); ++jt ) {
00279 assertTrue( G.isArc( it->first , jt->first , val ) );
00280 assertTrue( val == jt->second );
00281 assertTrue( ! G.isArc( 'c'+it->first , jt->first , val ) );
00282 assertTrue( ! G.isArc( 'c'+it->first , 'c'+jt->first , val ) );
00283 assertTrue( ! G.isArc( it->first , 'c'+jt->first , val ) );
00284 }
00285 }
00286 assertTrue( ! G.isArc( "A(1)" , "O(1)" , val ) );
00287 assertTrue( ! G.isArc( "O(1)" , "A(1)" , val ) );
00288 assertTrue( ! G.isArc( "O(4)" , "O(3)" , val ) );
00289 assertTrue( ! G.isArc( "0(1)" , "B" , val ) );
00290 assertTrue( ! G.isArc( "A(3)" , "F" , val ) );
00291 }
00292 }
00293
00294
00295 void test_Graph::test_vertexList() {
00296 {{
00297 std::list< std::string > L;
00298 G.vertexList( L );
00299 assertTrue( L.size() == 12 );
00300
00301 G.vertexList( "F", L );
00302 assertTrue( L.size() == 3 );
00303 assertTrue( find(L.begin(), L.end() ,"A(1)") != L.end() );
00304 assertTrue( find(L.begin(), L.end() ,"A(2)") != L.end() );
00305 assertTrue( find(L.begin(), L.end() ,"A(3)") != L.end() );
00306
00307 G.vertexList( "D", L );
00308 assertTrue( L.empty() );
00309
00310 G.vertexList( "A(2)", L );
00311 assertTrue( L.size() == 1 );
00312 assertTrue( L.front() == "B" );
00313 }}
00314 }
00315
00316
00317 void test_Graph::test_isConnected() {
00318 {{
00319 Graph G;
00320 std::list<std::string> C;
00321 std::list<std::string> tmp;
00322 G.set("M(1)", "M(2)", 13 );
00323 G.set("M(2)", "M(3)", 15 );
00324 G.set("M(3)", "M(4)", 17 );
00325 G.set("M(4)", "M(2)", 19 );
00326 G.set("M(2)", "M(1)", 23 );
00327 G.set("M(4)", "M(1)", 29 );
00328
00329 assertTrue( isConnected(G) );
00330 G.vertexList( C );
00331
00332
00333 for ( std::list< std::string >::iterator it = C.begin(); it != C.end(); ++it ) {
00334 for ( std::list< std::string >::iterator jt = C.begin(); jt != C.end(); ++jt ) {
00335 assertTrue ( connected( G , *it , *jt , tmp ) );
00336 }
00337 }
00338 assertTrue( !isTree( G ) );
00339 }}
00340 }
00341
00342
00343 void test_Graph::test_isCircuit() {
00344 {{
00345 }}
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357 Graph CH;
00358 std::list<std::string> camino;
00359 CH.set("F", "A(1)", 2 ); CH.set( "A(1)", "B", 2 );
00360 CH.set("F", "A(2)", 8 ); CH.set( "A(2)", "B", 8 );
00361 CH.set("F", "A(3)", 64 ); CH.set( "A(3)", "B", 64 );
00362
00363 CH.set("B", "C(1)", 3 ); CH.set( "C(1)", "D", 3 );
00364 CH.set("B", "C(2)", 27 ); CH.set( "C(2)", "D", 27 );
00365
00366
00367 CH.set( "C(1)" , "A(1)", 80 );
00368 CH.set( "D" , "C(2)", 14 );
00369 CH.set( "C(2)" , "A(3)", 59 );
00370 camino.push_back("A(3)"); camino.push_back("B"); camino.push_back("C(1)");
00371 camino.push_back("D"); camino.push_back("C(2)"); camino.push_back("A(3)");
00372
00373
00374
00375
00376
00377 assertTrue( isCircuit(CH,camino) );
00378
00379
00380 camino.pop_back();
00381 assertTrue( !isCircuit(CH,camino) );
00382
00383 assertTrue( connected( CH,"A(2)", "A(1)", camino ) );
00384
00385
00386
00387 assertTrue( !isCircuit(CH,camino ) );
00388
00389 camino.push_back("A(2)");
00390 assertTrue( !isCircuit(CH,camino) );
00391
00392 assertTrue( !connected( CH,"A(1)", "F", camino ));
00393
00394
00395 std::list<std::string> listTmp;
00396 CH.vertexList(listTmp);
00397
00398 for ( std::list<std::string>::iterator iTmp = ++listTmp.begin();
00399 iTmp != listTmp.end(); ++iTmp
00400 ) {
00401 connected( CH,"F", *iTmp, camino );
00402 camino.push_back("F");
00403 assertTrue (!isCircuit(CH,camino));
00404 }
00405
00406
00407 assertTrue( !isConnected(CH));
00408
00409 assertTrue( !isTree(CH));
00410
00411 Graph newG;
00412 assertTrue( spanningTree(CH,newG));
00413 assertTrue( isTree(newG));
00414 std::list<std::string> lT;
00415 newG.vertexList(lT);
00416 std::list<std::string> N_Nodos;
00417 int cant = 0;
00418 for(std::list<std::string>::iterator iT = lT.begin(); iT != lT.end(); ++iT){
00419 newG.vertexList(*iT, N_Nodos);
00420 cant += N_Nodos.size();
00421 }
00422 assertTrue( cant+1 == lT.size() );
00423 }
00424
00425
00426 void test_Graph::test_spanningTree() {
00427 {{
00428 Graph G;
00429 G.set( "A", "B", 10 ); G.set( "A", "C", 12 );
00430 G.set( "C", "B", 14 ); G.set( "C", "D", 21 );
00431 G.set( "C", "E", 16 ); G.set( "D", "B", 20 );
00432 G.set( "D", "E", 18 );
00433
00434
00435 Graph T;
00436 assertTrue( spanningTree(G,T));
00437 assertTrue( isTree(T));
00438 std::list<std::string> T_Vertices;
00439 T.vertexList(T_Vertices);
00440 std::list<std::string> N_Nodos;
00441 int cant = 0;
00442 for( std::list<std::string>::iterator iT = T_Vertices.begin(); iT != T_Vertices.end(); ++iT ) {
00443 T.vertexList(*iT, N_Nodos);
00444 cant += N_Nodos.size();
00445 }
00446 assertTrue( cant +1 == T_Vertices.size());
00447
00448
00449 assertTrue( !isConnected(T) );
00450
00451
00452 assertTrue( isTree(T) );
00453 }}
00454 }
00455
00456 }
00457
00458
00459 int main() {
00460 using namespace ADH;
00461 using namespace std;
00462 test_Graph tester;
00463 tester.setUp();
00464 if (1) {
00465 tester.do_dump(cout); cout << endl;
00466 tester.do_cout(cout); cout << endl;
00467 }
00468 tester.run();
00469 cout << tester.summary() << endl;
00470 cout << tester.report() << endl;
00471 tester.set_cycles(true);
00472 tester.run();
00473 cout << endl << endl;
00474 cout << tester.report() << endl;
00475 return 0;
00476 }
00477