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