Main Page   Class Hierarchy   Compound List   File List   Compound Members  

pQueue.cpp

00001 /****************************************************
00002  *  Bachelor Project:                               *
00003  *  External Memory Minimum Spanning Trees          *
00004  *  by Dominik Schultes <mail@dominik-schultes.de>  *
00005  *                                                  *
00006  *                pQueue.cpp                        *
00007  *                                                  *
00008  *  July 22, 2003                                   *
00009  ****************************************************/
00010 
00011 
00012 #include "pQueue.h"
00013 #include "../data_structures/duplicatesRemover.h"
00014 #include "../utils/randomizer.h"
00015 
00016 
00021 void PQueue::initPQueue()
00022 {    
00023     // create the first external bucket
00024     _firstExtBucket = new InternalMemoryBucket(_noOfNodesInIntMem,0);
00025 
00026       
00027     // distribute the edges to the first external bucket and the priority queue
00028     DS_RANDOMIZE( Randomizer<RandomizerFeistel> randomizer(_graph.noOfNodes()) );
00029     
00030     DS_VERBOSE1( std::cout << std::endl
00031                  << "distribute edges to the first external bucket and the priority queue"
00032                  << std::endl;
00033                  Percent percent(_graph.size(), true) );
00034         
00035     for (; !_graph.empty(); _graph.pop_back()) {
00036         DS_DONT_RANDOMIZE( RelabeledEdge edge(_graph.back()) );
00037         DS_RANDOMIZE( RelabeledEdge edge = randomizer.randomize(_graph.back()) );
00038 
00039         DS_VERBOSE1( percent.printStatus(_graph.size()) );
00040         DS_VERBOSE2( std::cout << edge << std::endl );
00041         
00042         // The source has to be greater than the target.
00043         if (edge.source() < edge.target()) edge.swap();
00044         
00045         // add the current edge to the first external bucket
00046         // or to the priority queue
00047         add(edge);
00048     }
00049 
00050     // delete the input graph
00051     delete &_graph;
00052 
00053     DS_LOGGING1( logging.events().push_back(
00054                      LoggingEvent("edges distributed to external buckets")) );
00055 }
00056 
00057 
00062 void PQueue::reduceNodes()
00063 {
00064     if ( _pqueue.empty() ) return;
00065     
00066     DS_REMOVE_DUPLICATES(
00067         DuplicatesRemover<PQueue> *duplRem = new DuplicatesRemover<PQueue>(this) );
00068 
00069     // get shortest edge incident to the last node
00070     RelabeledEdge minWeightEdge( _pqueue.top() );
00071     _pqueue.pop();
00072     _result.add( minWeightEdge );
00073 
00074     DS_VERBOSE1( std::cout << std::endl << "reduce nodes" << std::endl;
00075                  Percent percent( minWeightEdge.source() - _noOfNodesInIntMem );
00076                  NodeCount processedNodes = 0 );
00077     
00078     // Process all edges in the priority queue
00079     while ( ! _pqueue.empty() ) {
00080         // get current edge
00081         RelabeledEdge currentEdge( _pqueue.top() );
00082         _pqueue.pop();
00083 
00084         // check whether the current edge has the same source vertex as the predecessor
00085         if ( minWeightEdge.source() == currentEdge.source() ) {
00086             // throw the old source vertex away
00087             RelabeledEdgeWithoutSource currentEdgeWithoutSource( currentEdge );
00088             
00089             DS_DONT_REMOVE_DUPLICATES(
00090                 // add the relabeled edge to the first external bucket
00091                 // resp. to the priority queue
00092                 add( RelabeledEdge(currentEdgeWithoutSource, minWeightEdge.target()) );
00093             )
00094                     
00095             DS_REMOVE_DUPLICATES(
00096                 // add the edge to the DuplicateRemover
00097                 duplRem->insert( currentEdgeWithoutSource, minWeightEdge.target() );
00098                 
00099                 // clear the DuplicateRemover if this is the last edge incident to the
00100                 // current source vertex
00101                 if ((_pqueue.empty()) ||
00102                     (_pqueue.top().source() != minWeightEdge.source())) {
00103                     duplRem->clear( minWeightEdge.target() );
00104                 }
00105             )
00106             
00107         }
00108         else {
00109             // the current edge is the shortest one incident to the currently last node
00110             minWeightEdge = currentEdge;
00111             _result.add( minWeightEdge );
00112             
00113             DS_VERBOSE1( processedNodes++;
00114                          percent.printStatus(processedNodes) );
00115         }
00116     }
00117 
00118     DS_REMOVE_DUPLICATES( delete duplRem );
00119 }
00120 

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