Main Page   Class Hierarchy   Compound List   File List   Compound Members  

main.cpp

00001 /****************************************************
00002  *  Bachelor Project:                               *
00003  *  External Memory Minimum Spanning Trees          *
00004  *  by Dominik Schultes <mail@dominik-schultes.de>  *
00005  *                                                  *
00006  *                main.cpp                          *
00007  *                                                  *
00008  *  May 25, 2003                                    *
00009  ****************************************************/
00010 
00011 #include <iostream>
00012 
00013 
00014 #include "config.h"
00015 #include "data_structures/mst.h"
00016 #include "data_structures/edgeVector.cpp"
00017 #include "utils/logging.h"
00018 #include "utils/utils.h"
00019 
00020 DS_LOGGING1( Logging logging("log.txt") );
00021 
00022 #include "buckets/buckets.cpp"
00023 #include "priority_queue/pQueue.cpp"
00024 #include "utils/generate.cpp"
00025 #include "utils/importExport.cpp"
00026 #include "base_case/kruskal.cpp"
00027 #include "utils/parameters.h"
00028 
00029 
00031 void abortAfterNodeReducing(std::string filename, InternalMemoryBucket *reducedGraph)
00032 {
00033     if (filename != "") {
00034         // write reduced graph to the given file
00035         std::ofstream outFile(filename.c_str());
00036         // dummy EdgeVector in order to avoid a compiler error:
00037         // An instance of EdgeVector<RelabeledEdge> is needed to provide
00038         // a suitable output operator for intMemBucket.
00039         EdgeVector<RelabeledEdge> dummy(0,0); 
00040         outFile << 'r' << std::endl << *reducedGraph;
00041         DS_LOGGING1( logging.events().push_back(
00042                          LoggingEvent("reduced graph written to file")) );
00043     }
00044     std::cout << std::endl << "abort after the 'node reducing'-phase" << std::endl;    
00045 }
00046 
00047 
00049 int main(int argc, char *argv[])
00050 {
00051     DS_LOGGING1( logging.events().push_back(LoggingEvent("begin")) );
00052     
00053     Parameters param(argc, argv); // parse the command-line arguments
00054 
00055     DS_USE_BUCKETS(
00056         typedef Buckets<DS_EXT_BUCKET_SIZE> MyBuckets;
00057         // compute the number of buckets that are needed to store the edges of all nodes
00058         MyBuckets::BucketID noOfBuckets =
00059             MyBuckets::noOfExtBuckets(param.noOfNodes(),
00060                                       param.noOfNodesInInternalMemory());
00061         
00062         DS_VERBOSE1( std::cout << "number of external buckets = "
00063                                << noOfBuckets << std::endl;
00064                      memoryUsageForecast(param.noOfNodes(),
00065                                          param.noOfNodesInInternalMemory(),
00066                                          noOfBuckets) );
00067     )
00068 
00069     // INPUT
00070     EdgeVector<> * inputGraph;
00071 
00072     if (param.randomGraph()) {
00073         // generate random graph
00074         inputGraph = generateRandomGraph(param.randomGraphNoOfNodes(),
00075                                          param.randomGraphNoOfEdges());
00076 
00077         DS_LOGGING1( logging.setProblemInstance(
00078                         new LoggingRandomGraph(param.randomGraphNoOfNodes(),
00079                                                param.randomGraphNoOfEdges(),
00080                                                param.noOfNodesInInternalMemory())) );   
00081     }
00082     if (param.gridGraph()) {
00083         // generate grid graph
00084         inputGraph = generateGridGraph(param.gridGraphNoOfNodesX(),
00085                                        param.gridGraphNoOfNodesY());
00086         
00087         DS_LOGGING1( logging.setProblemInstance(
00088                         new LoggingGridGraph(param.gridGraphNoOfNodesX(),
00089                                              param.gridGraphNoOfNodesY(),
00090                                              param.noOfNodesInInternalMemory())) );
00091     }
00092     if (param.geometricGraph()) {
00093         // generate geometric graph
00094         inputGraph = generateGeometricGraph(param.geometricGraphNoOfNodes(),
00095                                             param.geometricGraphNoOfNeighbours());
00096         
00097         DS_LOGGING1( logging.setProblemInstance(
00098                         new LoggingGeometricGraph(param.geometricGraphNoOfNodes(),
00099                                                   param.geometricGraphNoOfNeighbours(),
00100                                                   inputGraph->noOfEdges(),
00101                                                   param.noOfNodesInInternalMemory())) );
00102     }
00103     if (param.importInputFilename() != "") {
00104         // import graph from file
00105         DS_VERBOSE1( std::cout << std::endl << "import graph" << std::endl );
00106         inputGraph = importEdgeVector( param.importInputFilename() );
00107 
00108         DS_LOGGING1( logging.setProblemInstance(
00109                         new LoggingImportedGraph(inputGraph->noOfNodes(),
00110                                                  inputGraph->noOfEdges(),
00111                                                  param.noOfNodesInInternalMemory(),
00112                                                  param.importInputFilename())) );
00113     }
00114     
00115     // export input graph
00116     if (param.exportInputFilename() != "") {
00117         DS_VERBOSE1( std::cout << std::endl << "export graph" << std::endl );
00118         
00119         if ( param.exportInputFormatAdjacencyList() ) {
00120             // export format: adjacency lists
00121             std::ofstream outFile(param.exportInputFilename().c_str());
00122             exportEdgeVectorAdjList(outFile, *inputGraph);
00123         }
00124         else {
00125             if ( param.exportInputFormatCompressed() ) {
00126                 // export format: compressed
00127                 exportEdgeVectorCompressed(param.exportInputFilename(), *inputGraph);   
00128             }
00129             else {
00130                 // export format: list of edges
00131                 std::ofstream outFile(param.exportInputFilename().c_str());
00132                 outFile << *inputGraph; 
00133             }
00134         }
00135         if ( param.quitAfterExporting() ) {
00136             // quit after exporting
00137             std::cout << std::endl
00138                       << "quit after exporting the input graph." << std::endl;
00139             exit(0);
00140         }
00141     }
00142     
00143     DS_LOGGING1( logging.events().push_back(LoggingEvent("graph generated/imported")) );
00144 
00145 
00146     
00147     MST result; // the resulting MST
00148     
00149     // PROCESSING
00150     if ( param.noOfNodes() <= param.noOfNodesInInternalMemory() ) {
00151         // all nodes fit in internal memory
00152         // ==> Kruskal's algorithm can by applied immediately
00153         Kruskal<Edge> *kruskal = new Kruskal<Edge>(*inputGraph,result);
00154         delete kruskal;
00155     }
00156     else {
00157         // node reduction phase is required
00158         DS_LOGGING1( logMemoryUsage("before buckets") );
00159 
00160         
00161         // perform node reduction
00162         
00163         DS_USE_BUCKETS(
00164             // buckets implementation
00165             MyBuckets *buckets = new MyBuckets(*inputGraph, result,
00166                                                noOfBuckets,
00167                                                param.noOfNodesInInternalMemory());
00168             InternalMemoryBucket *intMemBucket = buckets->getIntMemBucket();
00169             delete buckets;
00170         )
00171 
00172         DS_USE_PQUEUE(
00173             // priority queue implementation
00174             PQueue *pqueue = new PQueue(*inputGraph, result,
00175                                         param.noOfNodesInInternalMemory());
00176             InternalMemoryBucket *intMemBucket = pqueue->getIntMemBucket();
00177             delete pqueue;
00178         )
00179             
00180         // end of 'node reduction'
00181 
00182             
00183         DS_LOGGING1( logMemoryUsage("after buckets") );
00184 
00185         DS_LOGGING1( logging.events().push_back(LoggingEvent("nodes reduced")) );
00186         
00187         if ( param.abortAfterNodeReducing() ) {
00188             // abort processing after the node reduction phase
00189             abortAfterNodeReducing( param.reducedGraphFilename(), intMemBucket );
00190         }
00191         else {
00192             // apply Kruskal's algorithm to the reduced graph
00193             Kruskal<RelabeledEdge> *kruskal =
00194                 new Kruskal<RelabeledEdge>(*intMemBucket,result);
00195             delete kruskal;
00196         }
00197     }
00198     
00199     
00200         
00201     // OUTPUT
00202     DS_LOGGING1( logging.setResult(new LoggingResult(result.noOfEdges(),
00203                                                      result.totalWeight())) );
00204     DS_LOGGING1( logging.events().push_back(LoggingEvent("end")) );
00205     DS_LOGGING1( logging.printLog() );
00206 
00207     if (param.outputFilename() != "") {
00208         // write the computed mst to the given file
00209         std::ofstream outFile(param.outputFilename().c_str());
00210         outFile << result;
00211     }
00212     
00213     DS_VERBOSE1( std::cout << std::endl << "finished." << std::endl );
00214     
00215     return 0;
00216 }

Generated on Thu Aug 14 15:13:27 2003 for External Memory Minimum Spanning Trees by doxygen1.2.17