00001 #ifndef GRAPHIO_H
00002 #define GRAPHIO_H
00003
00004 #include <vector>
00005 #include <Utilities/progressBar.h>
00006 #include <Structs/Arrays/nodeArray.h>
00007 #include <assert.h>
00008 #include <sstream>
00009
00010
00011
00012 template<typename GraphType>
00013 class GraphReader
00014 {
00015 public:
00016 GraphReader( const std::string& filename):m_filename(filename)
00017 {
00018 }
00019
00020 std::vector< typename GraphType::NodeDescriptor>& getIds()
00021 {
00022 return m_ids;
00023 }
00024
00025 virtual void read( GraphType& G)
00026 {
00027 }
00028 protected:
00029 std::string m_filename;
00030 std::vector< typename GraphType::NodeDescriptor> m_ids;
00031 };
00032
00033
00034 template<typename GraphType>
00035 class GMLReader : public GraphReader<GraphType>
00036 {
00037 public:
00038 typedef typename GraphType::NodeIterator NodeIterator;
00039 typedef typename GraphType::EdgeIterator EdgeIterator;
00040 typedef typename GraphType::NodeDescriptor NodeDescriptor;
00041 typedef typename GraphType::EdgeDescriptor EdgeDescriptor;
00042 typedef typename GraphType::SizeType SizeType;
00043
00044 GMLReader( const std::string& filename):GraphReader<GraphType>(filename)
00045 {
00046 }
00047
00048 void read( GraphType& G)
00049 {
00050 std::ifstream in;
00051 std::string token;
00052 std::cout << "Reading GML from " << GraphReader<GraphType>::m_filename << std::endl;
00053 GraphReader<GraphType>::m_ids.clear();
00054 in.exceptions ( std::ifstream::failbit | std::ifstream::badbit );
00055
00056 try {
00057 in.open( GraphReader<GraphType>::m_filename.c_str());
00058
00059 if (in.is_open())
00060 {
00061 in.exceptions ( std::ios_base::goodbit);
00062 while ( in.good() && !in.eof() )
00063 {
00064 in >> token;
00065
00066 if( !token.compare("node"))
00067 {
00068 readNode( G, in);
00069 }
00070 if( !token.compare("edge"))
00071 {
00072 readEdge( G, in);
00073 }
00074 }
00075 in.close();
00076 }
00077 }
00078 catch (std::ifstream::failure e) {
00079 std::cerr << "Exception opening/reading file '" << GraphReader<GraphType>::m_filename << "'\n";
00080 throw e;
00081 }
00082 }
00083
00084 void readNode(GraphType& G, std::ifstream& in)
00085 {
00086 std::string token,value;
00087 NodeIterator u;
00088 NodeDescriptor uD;
00089
00090 uD = G.insertNode();
00091 GraphReader<GraphType>::m_ids.push_back(uD);
00092 u = G.getNodeIterator(uD);
00093
00094 in >> token;
00095 in >> token;
00096
00097 while( token.compare("]"))
00098 {
00099 in >> value;
00100 u->setProperty( token, value);
00101 in >> token;
00102 }
00103 }
00104
00105 void readEdge(GraphType& G, std::ifstream& in)
00106 {
00107 std::string token,value;
00108 unsigned int source,target;
00109 EdgeIterator e;
00110 EdgeDescriptor eD;
00111
00112 in >> token;
00113 in >> token;
00114 if( !token.compare("source"))
00115 {
00116 in >> source;
00117 }
00118
00119 in >> token;
00120
00121 if( !token.compare("target"))
00122 {
00123 in >> target;
00124 }
00125
00126 eD = G.insertEdge( GraphReader<GraphType>::m_ids[source], GraphReader<GraphType>::m_ids[target]);
00127 e = G.getEdgeIterator(eD);
00128
00129 in >> token;
00130
00131 while( token.compare("]"))
00132 {
00133 in >> value;
00134 e->setProperty( token, value);
00135 in >> token;
00136 }
00137 }
00138
00139 };
00140
00141
00142 template<typename GraphType>
00143 class DIMACS10Reader : public GraphReader<GraphType>
00144 {
00145 public:
00146 typedef typename GraphType::NodeIterator NodeIterator;
00147 typedef typename GraphType::EdgeIterator EdgeIterator;
00148 typedef typename GraphType::NodeDescriptor NodeDescriptor;
00149 typedef typename GraphType::EdgeDescriptor EdgeDescriptor;
00150 typedef typename GraphType::SizeType SizeType;
00151
00152 DIMACS10Reader( const std::string& filename, const std::string& coordinatesFilename):GraphReader<GraphType>(filename),m_coordinatesFilename(coordinatesFilename)
00153 {
00154 }
00155
00156 void read( GraphType& G)
00157 {
00158 GraphReader<GraphType>::m_ids.clear();
00159 std::string token;
00160 SizeType numNodes, numEdges, source, target,edgeId, x, y;
00161 NodeDescriptor uD;
00162 NodeIterator u,end;
00163 EdgeDescriptor eD;
00164 EdgeIterator e;
00165 std::ifstream in;
00166 in.exceptions ( std::ifstream::failbit | std::ifstream::badbit );
00167
00168 try {
00169 in.open( GraphReader<GraphType>::m_filename.c_str());
00170 assert( in.good());
00171
00172 while (getline(in,token))
00173 {
00174
00175 if( token.c_str()[0] == '%') continue;
00176
00177 std::stringstream graphinfo;
00178 graphinfo.str(token);
00179 graphinfo >> numNodes >> numEdges;
00180 break;
00181 }
00182
00183 G.reserve( numNodes, numEdges << 1);
00184 G.memUsage();
00185
00186 std::stringstream nodestream;
00187 nodestream << "Reading " << numNodes << " nodes";
00188 ProgressBar node_progress( numNodes,nodestream.str());
00189 GraphReader<GraphType>::m_ids.push_back(NodeDescriptor());
00190
00191 for( SizeType i = 0; i < numNodes; ++i)
00192 {
00193 uD = G.insertNode();
00194
00195
00196
00197 GraphReader<GraphType>::m_ids.push_back(uD);
00198 ++node_progress;
00199 }
00200
00201
00202
00203
00204
00205
00206 std::stringstream edgestream;
00207 edgestream << "Reading " << numEdges << " edges";
00208 ProgressBar edge_progress(numNodes,edgestream.str());
00209
00210 edgeId = 0;
00211 for( source = 1; source <= numNodes; ++source)
00212 {
00213 getline(in,token);
00214 while( token.c_str()[0] == '%') getline(in,token);
00215 std::stringstream edgeinfo;
00216 edgeinfo.str(token);
00217 while( edgeinfo.good())
00218 {
00219
00220
00221
00222 edgeinfo >> target;
00223 eD = G.insertEdge( GraphReader<GraphType>::m_ids[source], GraphReader<GraphType>::m_ids[target]);
00224
00225
00226 }
00227
00228 ++edge_progress;
00229 }
00230 in.close();
00231 }
00232 catch (std::ifstream::failure e) {
00233 std::cerr << "Exception opening/reading file '" << GraphReader<GraphType>::m_filename << "'\n";
00234 throw e;
00235 }
00236
00237 try {
00238 in.open( m_coordinatesFilename.c_str());
00239 assert( in.good());
00240
00241 for( source = 1; source <= numNodes; ++source)
00242 {
00243 in >> x >> y >> token;
00244 u = G.getNodeIterator( GraphReader<GraphType>::m_ids[source]);
00245 u->x = x;
00246 u->y = y;
00247 }
00248
00249 in.close();
00250 }
00251 catch (std::ifstream::failure e) {
00252 std::cerr << "Exception opening/reading file '" << m_coordinatesFilename << "'\n";
00253 throw e;
00254 }
00255
00256 }
00257 private:
00258 std::string m_coordinatesFilename;
00259 };
00260
00261
00262 template<typename GraphType>
00263 class DIMACS9Reader : public GraphReader<GraphType>
00264 {
00265 public:
00266 typedef typename GraphType::NodeIterator NodeIterator;
00267 typedef typename GraphType::EdgeIterator EdgeIterator;
00268 typedef typename GraphType::NodeDescriptor NodeDescriptor;
00269 typedef typename GraphType::EdgeDescriptor EdgeDescriptor;
00270 typedef typename GraphType::SizeType SizeType;
00271
00272 DIMACS9Reader( const std::string& filename):GraphReader<GraphType>(filename)
00273 {
00274 }
00275
00276 void read( GraphType& G)
00277 {
00278 std::ifstream in;
00279 in.exceptions ( std::ifstream::failbit | std::ifstream::badbit );
00280 SizeType nodeId = 0;
00281 SizeType edgeId = 0;
00282 try {
00283 in.open( GraphReader<GraphType>::m_filename.c_str());
00284 assert( in.good());
00285
00286 std::string token, dummy1, dummy2;
00287 SizeType numNodes, numEdges, source, target,edgeId;
00288 std::vector<NodeDescriptor> V;
00289 NodeDescriptor uD;
00290 NodeIterator u;
00291 EdgeDescriptor eD;
00292 EdgeIterator e;
00293
00294
00295 while (getline(in,token))
00296 {
00297 if( (token.c_str()[0] != 'p') ) continue;
00298
00299 std::stringstream graphinfo;
00300 graphinfo.str(token);
00301 graphinfo >> dummy1 >> dummy2 >> numNodes >> numEdges;
00302 break;
00303 }
00304
00305 std::stringstream nodestream;
00306 nodestream << "Reading " << numNodes << " nodes";
00307 ProgressBar node_progress( numNodes,nodestream.str());
00308 V.push_back(NodeDescriptor());
00309
00310 for( nodeId = 0; nodeId < numNodes; ++nodeId)
00311 {
00312 uD = G.insertNode();
00313 u = G.getNodeIterator(uD);
00314 V.push_back(uD);
00315 ++node_progress;
00316 }
00317
00318 std::stringstream edgestream;
00319 edgestream << "Reading " << numEdges << " edges";
00320 ProgressBar edge_progress(numEdges,edgestream.str());
00321
00322 edgeId = 0;
00323 unsigned int weight;
00324
00325
00326 while ( !in.eof())
00327 {
00328 getline(in,token);
00329
00330
00331
00332
00333
00334
00335
00336
00337 if( (token.c_str()[0] != 'a') )
00338 {
00339
00340 continue;
00341 }
00342
00343 std::stringstream edgeinfo;
00344 edgeinfo.str(token);
00345
00346 while( edgeinfo.good())
00347 {
00348 edgeinfo >> dummy1 >> source >> target >> weight;
00349 if( !G.edgeExists( V[source], V[target]))
00350 {
00351 eD = G.insertEdge( V[source], V[target]);
00352 e = G.getEdgeIterator(eD);
00353 e->setId( edgeId);
00354
00355 }
00356 edgeId++;
00357
00358 ++edge_progress;
00359 }
00360 if( edgeId + 1 == numEdges)
00361 break;
00362 }
00363
00364 in.close();
00365 }
00366 catch (std::ifstream::failure e) {
00367 std::cerr << "Exception opening/reading file '" << GraphReader<GraphType>::m_filename << "'\n";
00368 std::cerr << "Have already read " << nodeId << " nodes and " << edgeId << " edges\n";
00369 throw e;
00370 }
00371 }
00372 };
00373
00374 template<typename GraphType>
00375 class GraphWinReader : public GraphReader<GraphType>
00376 {
00377 public:
00378 typedef typename GraphType::NodeIterator NodeIterator;
00379 typedef typename GraphType::EdgeIterator EdgeIterator;
00380 typedef typename GraphType::NodeDescriptor NodeDescriptor;
00381 typedef typename GraphType::SizeType SizeType;
00382
00383 GraphWinReader( const std::string& filename):GraphReader<GraphType>(filename)
00384 {
00385 }
00386
00387 void read( GraphType& G)
00388 {
00389 std::ifstream in;
00390 in.exceptions ( std::ifstream::failbit | std::ifstream::badbit );
00391 try {
00392 in.open( GraphReader<GraphType>::m_filename.c_str());
00393 assert( in.good());
00394 SizeType numNodes, numEdges, source, target;
00395 std::vector<NodeDescriptor> V;
00396
00397 for( unsigned int i = 0; i < 4; i++)
00398 {
00399 in.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
00400 }
00401
00402 in >> numNodes;
00403 std::stringstream nodestream;
00404 nodestream << "Reading " << numNodes << " nodes";
00405 ProgressBar node_progress( numNodes,nodestream.str());
00406 V.push_back(NodeDescriptor());
00407
00408 for( SizeType i = 0; i < numNodes; ++i)
00409 {
00410 V.push_back(G.insertNode());
00411 in.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
00412 ++node_progress;
00413 }
00414 in.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
00415
00416 in >> numEdges;
00417 std::stringstream edgestream;
00418 edgestream << "Reading " << numEdges << " edges";
00419 ProgressBar edge_progress(numEdges,edgestream.str());
00420 for( SizeType i = 0; i < numEdges; ++i)
00421 {
00422 in >> source;
00423 in >> target;
00424 std::cout << source << " " << target << "\n";
00425 G.insertEdge( V[source], V[target]);
00426 in.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
00427 ++edge_progress;
00428 }
00429 std::cout << "\rReading edges...done!\n";
00430 in.close();
00431 }
00432 catch (std::ifstream::failure e) {
00433 std::cerr << "Exception opening/reading file '" << GraphReader<GraphType>::m_filename << "'\n";
00434 throw e;
00435 }
00436 }
00437 };
00438
00439
00440
00441
00442 template<typename GraphType>
00443 class GraphWriter
00444 {
00445 public:
00446 GraphWriter( const std::string& filename):m_filename(filename)
00447 {
00448 }
00449
00450 virtual void write( GraphType& G)
00451 {
00452 }
00453 protected:
00454 std::string m_filename;
00455 };
00456
00457 template<typename GraphType>
00458 class GraphVizWriter : public GraphWriter<GraphType>
00459 {
00460 public:
00461
00462 typedef typename GraphType::NodeIterator NodeIterator;
00463 typedef typename GraphType::EdgeIterator EdgeIterator;
00464 typedef typename GraphType::SizeType SizeType;
00465
00466 GraphVizWriter( const std::string& filename):GraphWriter<GraphType>(filename)
00467 {
00468 }
00469
00470 virtual void write( GraphType& G)
00471 {
00472 std::ofstream out;
00473 out.exceptions ( std::ofstream::failbit | std::ofstream::badbit );
00474 try {
00475 out.open( GraphWriter<GraphType>::m_filename.c_str());
00476 out << "digraph BFS {\n\tedge [len=3]\n\tnode [fontname=\"Arial\"]\n";
00477
00478 NodeIterator u,v,lastnode;
00479 EdgeIterator e,lastedge;
00480
00481
00482
00483 NodeArray<SizeType, GraphType> dotId( &G,std::numeric_limits<SizeType>::max());
00484
00485 SizeType i = 0;
00486
00487 std::stringstream nodestream;
00488 nodestream << "Writing out " << G.getNumNodes() << " nodes";
00489 ProgressBar node_progress( G.getNumNodes(),nodestream.str());
00490
00491 for( u = G.beginNodes(), lastnode = G.endNodes(); u != lastnode; ++u, ++i)
00492 {
00493 out << i;
00494
00495 dotId[u] = i;
00496
00497
00498
00499 out << "[label=\"" << G.getRelativePosition(u) << " ";
00500 u->print(out);
00501 out << "\"]\n";
00502 ++node_progress;
00503 }
00504
00505 std::stringstream edgestream;
00506 edgestream << "Writing out " << G.getNumEdges() << " edges";
00507 ProgressBar edge_progress( G.getNumEdges(),edgestream.str());
00508
00509 for( u = G.beginNodes(), lastnode = G.endNodes(); u != lastnode; ++u)
00510 {
00511 for( e = G.beginEdges(u), lastedge = G.endEdges(u); e != lastedge; ++e)
00512 {
00513 v = G.target(e);
00514
00515 out << dotId[u] << "->" << dotId[v];
00516 out << "[label=\"" ;
00517 e->print(out);
00518 out << "\"]\n";
00519 ++edge_progress;
00520 }
00521 }
00522
00523
00524
00525 out << "}";
00526 out.close();
00527 }
00528 catch (std::ofstream::failure e) {
00529 std::cout << "Exception opening/writing file '" << GraphWriter<GraphType>::m_filename << "'\n";
00530 throw e;
00531 }
00532 }
00533 };
00534
00535 template<typename GraphType>
00536 class GMLWriter : public GraphWriter<GraphType>
00537 {
00538 public:
00539 typedef typename GraphType::NodeIterator NodeIterator;
00540 typedef typename GraphType::EdgeIterator EdgeIterator;
00541 typedef typename GraphType::NodeDescriptor NodeDescriptor;
00542 typedef typename GraphType::EdgeDescriptor EdgeDescriptor;
00543 typedef typename GraphType::SizeType SizeType;
00544
00545 GMLWriter( const std::string& filename):GraphWriter<GraphType>(filename)
00546 {
00547 }
00548
00549 void write( GraphType& G)
00550 {
00551 std::ofstream out;
00552 std::cout << "Writing GML to " << GraphWriter<GraphType>::m_filename << std::endl;
00553 V.clear();
00554 out.exceptions ( std::ofstream::failbit | std::ofstream::badbit );
00555
00556 try {
00557 out.open( GraphWriter<GraphType>::m_filename.c_str());
00558
00559 if (out.is_open())
00560 {
00561 out.exceptions ( std::ios_base::goodbit);
00562
00563 std::stringstream node_stream, edge_stream;
00564 node_stream << "Writing " << G.getNumNodes() << " nodes";
00565 edge_stream << "Writing " << G.getNumEdges() << " edges";
00566 ProgressBar node_progress( G.getNumNodes(),node_stream.str());
00567 ProgressBar edge_progress( G.getNumEdges(),edge_stream.str());
00568
00569 out << "graph [\n";
00570
00571 NodeIterator u, lastNode;
00572 EdgeIterator e, lastEdge;
00573
00574 nodeId = 0;
00575 for( u = G.beginNodes(), lastNode = G.endNodes(); u != lastNode; ++u)
00576 {
00577 writeNode( G, u, out);
00578 ++node_progress;
00579 }
00580
00581 for( u = G.beginNodes(), lastNode = G.endNodes(); u != lastNode; ++u)
00582 {
00583 for( e = G.beginEdges(u), lastEdge = G.endEdges(u); e != lastEdge; ++e)
00584 {
00585 writeEdge( G, u, e, out);
00586 ++edge_progress;
00587 }
00588 }
00589
00590 out << "]\n";
00591
00592 out.close();
00593 }
00594 }
00595 catch (std::ifstream::failure e) {
00596 std::cerr << "Exception opening/writing file '" << GraphWriter<GraphType>::m_filename << "'\n";
00597 throw e;
00598 }
00599 }
00600
00601 void writeNode(GraphType& G, NodeIterator& u, std::ofstream& out)
00602 {
00603 out << "node [" << std::endl;
00604 out << "id " << nodeId++ << "\n";
00605 u->writeProperties(out);
00606 out << "]" << std::endl;
00607 }
00608
00609 void writeEdge(GraphType& G, NodeIterator& u, EdgeIterator& e, std::ofstream& out)
00610 {
00611 out << "edge [" << std::endl;
00612 out << "source " << G.getRelativePosition(u) << std::endl;
00613 NodeIterator v = G.target(e);
00614 out << "target " << G.getRelativePosition(v) << std::endl;
00615 e->writeProperties(out);
00616 out << "]" << std::endl;
00617 }
00618
00619 private:
00620 std::vector<NodeDescriptor> V;
00621 unsigned int nodeId;
00622 };
00623
00624
00625 template<typename GraphType>
00626 class JSONWriter : public GraphWriter<GraphType>
00627 {
00628 public:
00629 typedef typename GraphType::NodeIterator NodeIterator;
00630 typedef typename GraphType::EdgeIterator EdgeIterator;
00631 typedef typename GraphType::NodeDescriptor NodeDescriptor;
00632 typedef typename GraphType::EdgeDescriptor EdgeDescriptor;
00633 typedef typename GraphType::SizeType SizeType;
00634
00635 JSONWriter( const std::string& filename):GraphWriter<GraphType>(filename)
00636 {
00637 }
00638
00639 void write( GraphType& G)
00640 {
00641 std::ofstream out;
00642 std::cout << "Writing JSON to " << GraphWriter<GraphType>::m_filename << std::endl;
00643 V.clear();
00644 out.exceptions ( std::ofstream::failbit | std::ofstream::badbit );
00645
00646 try {
00647 out.open( GraphWriter<GraphType>::m_filename.c_str());
00648
00649 if (out.is_open())
00650 {
00651 out.exceptions ( std::ios_base::goodbit);
00652 std::stringstream node_stream, edge_stream;
00653 node_stream << "Writing " << G.getNumNodes() << " nodes";
00654 edge_stream << "Writing " << G.getNumEdges() << " edges";
00655 ProgressBar node_progress( G.getNumNodes(),node_stream.str());
00656 ProgressBar edge_progress( G.getNumEdges(),edge_stream.str());
00657
00658
00659 out << "{\n\"graph\": [\n";
00660
00661 NodeIterator u, w, lastNode;
00662 EdgeIterator e, k, lastEdge;
00663
00664 out << "\"nodes\": [\n";
00665
00666 nodeId = 0;
00667 w = G.beginNodes();
00668 ++w;
00669 for( u = G.beginNodes(), lastNode = G.endNodes(); u != lastNode; ++u, ++w)
00670 {
00671 writeNode( G, u, out);
00672 ++node_progress;
00673 if( w != lastNode) out << ",";
00674 out << "\n";
00675 }
00676
00677 out << "],\n\"edges\": [\n";
00678
00679 w = G.beginNodes();
00680 ++w;
00681 for( u = G.beginNodes(), lastNode = G.endNodes(); u != lastNode; ++u)
00682 {
00683 k = G.beginEdges(u);
00684 ++k;
00685 for( e = G.beginEdges(u), lastEdge = G.endEdges(u); e != lastEdge; ++e)
00686 {
00687 writeEdge( G, u, e, out);
00688 ++edge_progress;
00689 if( w != lastNode) out << ",";
00690 else
00691 {
00692 if( k != lastEdge) out << ",";
00693 }
00694 out << "\n";
00695 }
00696 }
00697
00698 out << "}\n";
00699
00700 out.close();
00701 }
00702 }
00703 catch (std::ifstream::failure e) {
00704 std::cerr << "Exception opening/writing file '" << GraphWriter<GraphType>::m_filename << "'\n";
00705 throw e;
00706 }
00707 }
00708
00709 void writeNode(GraphType& G, NodeIterator& u, std::ofstream& out)
00710 {
00711 out << "{" ;
00712 out << "\"id\":" << nodeId++ << "";
00713 u->writeJSON(out);
00714 out << "}";
00715 }
00716
00717 void writeEdge(GraphType& G, NodeIterator& u, EdgeIterator& e, std::ofstream& out)
00718 {
00719 out << "{" ;
00720 out << "\"s\":" << G.getRelativePosition(u) << ",";
00721 NodeIterator v = G.target(e);
00722 out << "\"t\":" << G.getRelativePosition(v) << ",";
00723 e->writeJSON(out);
00724 out << "}";
00725 }
00726
00727 private:
00728 std::vector<NodeDescriptor> V;
00729 unsigned int nodeId;
00730 };
00731
00732
00733 #endif //GRAPHIO_H