Independent set tie-breaker in O(1) space and time
This commit is contained in:
parent
0388860ea1
commit
666371099e
@ -31,7 +31,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
|||||||
|
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
|
#include "../DataStructures/DeallocatingVector.h"
|
||||||
#include "../DataStructures/DynamicGraph.h"
|
#include "../DataStructures/DynamicGraph.h"
|
||||||
#include "../DataStructures/Percent.h"
|
#include "../DataStructures/Percent.h"
|
||||||
#include "../DataStructures/BinaryHeap.h"
|
#include "../DataStructures/BinaryHeap.h"
|
||||||
@ -77,8 +77,7 @@ private:
|
|||||||
|
|
||||||
struct _PriorityData {
|
struct _PriorityData {
|
||||||
int depth;
|
int depth;
|
||||||
NodeID bias;
|
_PriorityData() : depth(0) { }
|
||||||
_PriorityData() : depth(0), bias(0) { }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _ContractionInformation {
|
struct _ContractionInformation {
|
||||||
@ -95,17 +94,39 @@ private:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class XORFastHash {
|
||||||
|
std::vector<unsigned short> hashLookups;
|
||||||
|
public:
|
||||||
|
XORFastHash() {
|
||||||
|
hashLookups.resize(1 << 16);
|
||||||
|
for(unsigned i = 0; i < (1 << 16); ++i)
|
||||||
|
hashLookups[i] = i;
|
||||||
|
std::random_shuffle(hashLookups.begin(), hashLookups.end());
|
||||||
|
}
|
||||||
|
unsigned short operator()(const unsigned originalValue) const {
|
||||||
|
|
||||||
|
unsigned short msb = (((originalValue-1) >> 16) & 0xffff);
|
||||||
|
unsigned short lsb = ((originalValue-1) & 0xffff);
|
||||||
|
return hashLookups[lsb] ^ msb;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
template<class ContainerT >
|
template<class ContainerT >
|
||||||
Contractor( int nodes, ContainerT& inputEdges) {
|
Contractor( int nodes, ContainerT& inputEdges) {
|
||||||
std::vector< _ContractorEdge > edges;
|
DeallocatingVector< _ContractorEdge > edges;
|
||||||
edges.reserve( 2 * inputEdges.size() );
|
|
||||||
BOOST_FOREACH(typename ContainerT::value_type & currentEdge, inputEdges) {
|
typename ContainerT::deallocation_iterator diter = inputEdges.dbegin();
|
||||||
|
typename ContainerT::deallocation_iterator dend = inputEdges.dend();
|
||||||
|
|
||||||
|
|
||||||
|
//BOOST_FOREACH(typename ContainerT::value_type & currentEdge, inputEdges) {
|
||||||
|
for(; diter!=dend; ++diter) {
|
||||||
_ContractorEdge edge;
|
_ContractorEdge edge;
|
||||||
edge.source = currentEdge.source();
|
edge.source = diter->source();
|
||||||
edge.target = currentEdge.target();
|
edge.target = diter->target();
|
||||||
edge.data = _ContractorEdgeData( (std::max)((int)currentEdge.weight(), 1 ), 1, currentEdge.id()/*, currentEdge.getNameIDOfTurnTarget(), currentEdge.turnInstruction()*/, false, currentEdge.isForward(), currentEdge.isBackward());
|
edge.data = _ContractorEdgeData( (std::max)((int)diter->weight(), 1 ), 1, diter->id()/*, currentEdge.getNameIDOfTurnTarget(), currentEdge.turnInstruction()*/, false, diter->isForward(), diter->isBackward());
|
||||||
|
|
||||||
assert( edge.data.distance > 0 );
|
assert( edge.data.distance > 0 );
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
@ -116,12 +137,12 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
edges.push_back( edge );
|
edges.push_back( edge );
|
||||||
std::swap( edge.source, edge.target );
|
std::swap( edge.source, edge.target );
|
||||||
edge.data.forward = currentEdge.isBackward();
|
edge.data.forward = diter->isBackward();
|
||||||
edge.data.backward = currentEdge.isForward();
|
edge.data.backward = diter->isForward();
|
||||||
edges.push_back( edge );
|
edges.push_back( edge );
|
||||||
}
|
}
|
||||||
//clear input vector and trim the current set of edges with the well-known swap trick
|
//clear input vector and trim the current set of edges with the well-known swap trick
|
||||||
ContainerT().swap( inputEdges );
|
inputEdges.clear();
|
||||||
|
|
||||||
sort( edges.begin(), edges.end() );
|
sort( edges.begin(), edges.end() );
|
||||||
NodeID edge = 0;
|
NodeID edge = 0;
|
||||||
@ -169,7 +190,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::cout << "merged " << edges.size() - edge << " edges out of " << edges.size() << std::endl;
|
std::cout << "merged " << edges.size() - edge << " edges out of " << edges.size() << std::endl;
|
||||||
edges.resize( edge );
|
// edges.resize( edge );
|
||||||
|
|
||||||
_graph.reset( new _DynamicGraph( nodes, edges ) );
|
_graph.reset( new _DynamicGraph( nodes, edges ) );
|
||||||
edges.clear();
|
edges.clear();
|
||||||
@ -213,16 +234,13 @@ public:
|
|||||||
|
|
||||||
NodeID numberOfContractedNodes = 0;
|
NodeID numberOfContractedNodes = 0;
|
||||||
std::vector< std::pair< NodeID, bool > > remainingNodes( numberOfNodes );
|
std::vector< std::pair< NodeID, bool > > remainingNodes( numberOfNodes );
|
||||||
std::vector< double > nodePriority( numberOfNodes );
|
std::vector< float > nodePriority( numberOfNodes );
|
||||||
std::vector< _PriorityData > nodeData( numberOfNodes );
|
std::vector< _PriorityData > nodeData( numberOfNodes );
|
||||||
|
|
||||||
//initialize the variables
|
//initialize the variables
|
||||||
#pragma omp parallel for schedule ( guided )
|
#pragma omp parallel for schedule ( guided )
|
||||||
for ( int x = 0; x < ( int ) numberOfNodes; ++x )
|
for ( int x = 0; x < ( int ) numberOfNodes; ++x )
|
||||||
remainingNodes[x].first = x;
|
remainingNodes[x].first = x;
|
||||||
std::random_shuffle( remainingNodes.begin(), remainingNodes.end() );
|
|
||||||
for ( int x = 0; x < ( int ) numberOfNodes; ++x )
|
|
||||||
nodeData[remainingNodes[x].first].bias = x;
|
|
||||||
|
|
||||||
std::cout << "initializing elimination PQ ..." << std::flush;
|
std::cout << "initializing elimination PQ ..." << std::flush;
|
||||||
#pragma omp parallel
|
#pragma omp parallel
|
||||||
@ -238,7 +256,7 @@ public:
|
|||||||
bool flushedContractor = false;
|
bool flushedContractor = false;
|
||||||
while ( numberOfContractedNodes < numberOfNodes ) {
|
while ( numberOfContractedNodes < numberOfNodes ) {
|
||||||
if(!flushedContractor && (numberOfContractedNodes > (numberOfNodes*0.65) ) ){
|
if(!flushedContractor && (numberOfContractedNodes > (numberOfNodes*0.65) ) ){
|
||||||
std::vector<_ContractorEdge> newSetOfEdges; //this one is not explicitely cleared since it goes out of scope anywa
|
DeallocatingVector<_ContractorEdge> newSetOfEdges; //this one is not explicitely cleared since it goes out of scope anywa
|
||||||
std::cout << " [flush " << numberOfContractedNodes << " nodes] " << std::flush;
|
std::cout << " [flush " << numberOfContractedNodes << " nodes] " << std::flush;
|
||||||
|
|
||||||
//Delete old heap data to free memory that we need for the coming operations
|
//Delete old heap data to free memory that we need for the coming operations
|
||||||
@ -249,7 +267,7 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
//Create new priority array
|
//Create new priority array
|
||||||
std::vector<double> newNodePriority(remainingNodes.size());
|
std::vector<float> newNodePriority(remainingNodes.size());
|
||||||
//this map gives the old IDs from the new ones, necessary to get a consistent graph at the end of contraction
|
//this map gives the old IDs from the new ones, necessary to get a consistent graph at the end of contraction
|
||||||
oldNodeIDFromNewNodeIDMap.resize(remainingNodes.size());
|
oldNodeIDFromNewNodeIDMap.resize(remainingNodes.size());
|
||||||
//this map gives the new IDs from the old ones, necessary to remap targets from the remaining graph
|
//this map gives the new IDs from the old ones, necessary to remap targets from the remaining graph
|
||||||
@ -309,7 +327,7 @@ public:
|
|||||||
//Replace old priorities array by new one
|
//Replace old priorities array by new one
|
||||||
nodePriority.swap(newNodePriority);
|
nodePriority.swap(newNodePriority);
|
||||||
//Delete old nodePriority vector
|
//Delete old nodePriority vector
|
||||||
std::vector<double>().swap(newNodePriority);
|
std::vector<float>().swap(newNodePriority);
|
||||||
//old Graph is removed
|
//old Graph is removed
|
||||||
_graph.reset();
|
_graph.reset();
|
||||||
|
|
||||||
@ -318,6 +336,7 @@ public:
|
|||||||
|
|
||||||
//int nodes, const ContainerT &graph
|
//int nodes, const ContainerT &graph
|
||||||
_graph.reset( new _DynamicGraph(remainingNodes.size(), newSetOfEdges));
|
_graph.reset( new _DynamicGraph(remainingNodes.size(), newSetOfEdges));
|
||||||
|
newSetOfEdges.clear();
|
||||||
flushedContractor = true;
|
flushedContractor = true;
|
||||||
|
|
||||||
//INFO: MAKE SURE THIS IS THE LAST OPERATION OF THE FLUSH!
|
//INFO: MAKE SURE THIS IS THE LAST OPERATION OF THE FLUSH!
|
||||||
@ -325,7 +344,6 @@ public:
|
|||||||
for ( unsigned threadNum = 0; threadNum < maxThreads; ++threadNum ) {
|
for ( unsigned threadNum = 0; threadNum < maxThreads; ++threadNum ) {
|
||||||
threadData.push_back( new _ThreadData( _graph->GetNumberOfNodes() ) );
|
threadData.push_back( new _ThreadData( _graph->GetNumberOfNodes() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const int last = ( int ) remainingNodes.size();
|
const int last = ( int ) remainingNodes.size();
|
||||||
@ -417,8 +435,8 @@ public:
|
|||||||
//
|
//
|
||||||
// avgdegree /= std::max((unsigned)1,(unsigned)remainingNodes.size() );
|
// avgdegree /= std::max((unsigned)1,(unsigned)remainingNodes.size() );
|
||||||
// quaddegree /= std::max((unsigned)1,(unsigned)remainingNodes.size() );
|
// quaddegree /= std::max((unsigned)1,(unsigned)remainingNodes.size() );
|
||||||
|
//
|
||||||
// INFO("rest: " << remainingNodes.size() << ", max: " << maxdegree << ", min: " << mindegree << ", avg: " << avgdegree << ", quad: " << quaddegree);
|
// INFO("rest: " << remainingNodes.size() << ", max: " << maxdegree << ", min: " << mindegree << ", avg: " << avgdegree << ", quad: " << quaddegree);
|
||||||
|
|
||||||
p.printStatus(numberOfContractedNodes);
|
p.printStatus(numberOfContractedNodes);
|
||||||
}
|
}
|
||||||
@ -429,11 +447,14 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template< class Edge >
|
template< class Edge >
|
||||||
void GetEdges( std::vector< Edge >& edges ) {
|
void GetEdges( DeallocatingVector< Edge >& edges ) {
|
||||||
|
Percent p (_graph->GetNumberOfNodes());
|
||||||
|
INFO("Getting edges of minimized graph");
|
||||||
NodeID numberOfNodes = _graph->GetNumberOfNodes();
|
NodeID numberOfNodes = _graph->GetNumberOfNodes();
|
||||||
if(oldNodeIDFromNewNodeIDMap.size()) {
|
if(oldNodeIDFromNewNodeIDMap.size()) {
|
||||||
for ( NodeID node = 0; node < numberOfNodes; ++node ) {
|
for ( NodeID node = 0; node < numberOfNodes; ++node ) {
|
||||||
for ( _DynamicGraph::EdgeIterator edge = _graph->BeginEdges( node ), endEdges = _graph->EndEdges( node ); edge < endEdges; edge++ ) {
|
p.printStatus(node);
|
||||||
|
for ( _DynamicGraph::EdgeIterator edge = _graph->BeginEdges( node ), endEdges = _graph->EndEdges( node ); edge < endEdges; ++edge ) {
|
||||||
const NodeID target = _graph->GetTarget( edge );
|
const NodeID target = _graph->GetTarget( edge );
|
||||||
const _DynamicGraph::EdgeData& data = _graph->GetEdgeData( edge );
|
const _DynamicGraph::EdgeData& data = _graph->GetEdgeData( edge );
|
||||||
Edge newEdge;
|
Edge newEdge;
|
||||||
@ -456,7 +477,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
INFO("Renumbered remaining edges, freeing space");
|
INFO("Renumbered edges of minimized graph, freeing space");
|
||||||
_graph.reset();
|
_graph.reset();
|
||||||
std::vector<NodeID>().swap(oldNodeIDFromNewNodeIDMap);
|
std::vector<NodeID>().swap(oldNodeIDFromNewNodeIDMap);
|
||||||
INFO("Loading temporary edges");
|
INFO("Loading temporary edges");
|
||||||
@ -468,7 +489,7 @@ public:
|
|||||||
//loads edges of graph before renumbering, no need for further numbering action.
|
//loads edges of graph before renumbering, no need for further numbering action.
|
||||||
NodeID start;
|
NodeID start;
|
||||||
NodeID target;
|
NodeID target;
|
||||||
edges.reserve(edges.size()+numberOfTemporaryEdges);
|
//edges.reserve(edges.size()+numberOfTemporaryEdges);
|
||||||
_DynamicGraph::EdgeData data;
|
_DynamicGraph::EdgeData data;
|
||||||
for(unsigned i = 0; i < numberOfTemporaryEdges; ++i) {
|
for(unsigned i = 0; i < numberOfTemporaryEdges; ++i) {
|
||||||
temporaryEdgeStorage.read((char*)&start, sizeof(NodeID));
|
temporaryEdgeStorage.read((char*)&start, sizeof(NodeID));
|
||||||
@ -666,7 +687,7 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _UpdateNeighbours( std::vector< double > & priorities, std::vector< _PriorityData > & nodeData, _ThreadData* const data, NodeID node) {
|
bool _UpdateNeighbours( std::vector< float > & priorities, std::vector< _PriorityData > & nodeData, _ThreadData* const data, NodeID node) {
|
||||||
std::vector< NodeID >& neighbours = data->neighbours;
|
std::vector< NodeID >& neighbours = data->neighbours;
|
||||||
neighbours.clear();
|
neighbours.clear();
|
||||||
|
|
||||||
@ -691,7 +712,7 @@ private:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _IsIndependent( const std::vector< double >& priorities, const std::vector< _PriorityData >& nodeData, _ThreadData* const data, NodeID node ) {
|
bool _IsIndependent( const std::vector< float >& priorities, const std::vector< _PriorityData >& nodeData, _ThreadData* const data, NodeID node ) {
|
||||||
const double priority = priorities[node];
|
const double priority = priorities[node];
|
||||||
|
|
||||||
std::vector< NodeID >& neighbours = data->neighbours;
|
std::vector< NodeID >& neighbours = data->neighbours;
|
||||||
@ -699,14 +720,17 @@ private:
|
|||||||
|
|
||||||
for ( _DynamicGraph::EdgeIterator e = _graph->BeginEdges( node ) ; e < _graph->EndEdges( node ) ; ++e ) {
|
for ( _DynamicGraph::EdgeIterator e = _graph->BeginEdges( node ) ; e < _graph->EndEdges( node ) ; ++e ) {
|
||||||
const NodeID target = _graph->GetTarget( e );
|
const NodeID target = _graph->GetTarget( e );
|
||||||
|
if(node==target)
|
||||||
|
continue;
|
||||||
const double targetPriority = priorities[target];
|
const double targetPriority = priorities[target];
|
||||||
assert( targetPriority >= 0 );
|
assert( targetPriority >= 0 );
|
||||||
//found a neighbour with lower priority?
|
//found a neighbour with lower priority?
|
||||||
if ( priority > targetPriority )
|
if ( priority > targetPriority )
|
||||||
return false;
|
return false;
|
||||||
//tie breaking
|
//tie breaking
|
||||||
if ( priority == targetPriority && nodeData[node].bias < nodeData[target].bias )
|
if ( priority == targetPriority && bias(node, target) ) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
neighbours.push_back( target );
|
neighbours.push_back( target );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -719,26 +743,44 @@ private:
|
|||||||
|
|
||||||
for ( _DynamicGraph::EdgeIterator e = _graph->BeginEdges( u ) ; e < _graph->EndEdges( u ) ; ++e ) {
|
for ( _DynamicGraph::EdgeIterator e = _graph->BeginEdges( u ) ; e < _graph->EndEdges( u ) ; ++e ) {
|
||||||
const NodeID target = _graph->GetTarget( e );
|
const NodeID target = _graph->GetTarget( e );
|
||||||
|
if(node==target)
|
||||||
|
continue;
|
||||||
|
|
||||||
const double targetPriority = priorities[target];
|
const double targetPriority = priorities[target];
|
||||||
assert( targetPriority >= 0 );
|
assert( targetPriority >= 0 );
|
||||||
//found a neighbour with lower priority?
|
//found a neighbour with lower priority?
|
||||||
if ( priority > targetPriority )
|
if ( priority > targetPriority)
|
||||||
return false;
|
return false;
|
||||||
//tie breaking
|
//tie breaking
|
||||||
if ( priority == targetPriority && nodeData[node].bias < nodeData[target].bias )
|
if ( priority == targetPriority && bias(node, target) ) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool bias(const NodeID a, const NodeID b) {
|
||||||
|
unsigned short hasha = fastHash(a);
|
||||||
|
unsigned short hashb = fastHash(b);
|
||||||
|
|
||||||
|
//Decision with branching
|
||||||
|
// if(hasha != hashb)
|
||||||
|
// return hasha < hashb;
|
||||||
|
// return a < b;
|
||||||
|
|
||||||
|
//Decision without branching
|
||||||
|
return (hasha < hashb)+((hasha==hashb)*(a<b));
|
||||||
|
}
|
||||||
|
|
||||||
boost::shared_ptr<_DynamicGraph> _graph;
|
boost::shared_ptr<_DynamicGraph> _graph;
|
||||||
std::vector<_DynamicGraph::InputEdge> contractedEdges;
|
std::vector<_DynamicGraph::InputEdge> contractedEdges;
|
||||||
std::string temporaryEdgeStorageFilename;
|
std::string temporaryEdgeStorageFilename;
|
||||||
std::vector<NodeID> oldNodeIDFromNewNodeIDMap;
|
std::vector<NodeID> oldNodeIDFromNewNodeIDMap;
|
||||||
long initialFilePosition;
|
long initialFilePosition;
|
||||||
|
|
||||||
|
XORFastHash fastHash;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CONTRACTOR_H_INCLUDED
|
#endif // CONTRACTOR_H_INCLUDED
|
||||||
|
@ -85,7 +85,7 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory(int nodes, std::vector<NodeBasedEdg
|
|||||||
_trafficLights[id] = true;
|
_trafficLights[id] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector< _NodeBasedEdge > edges;
|
DeallocatingVector< _NodeBasedEdge > edges;
|
||||||
// edges.reserve( 2 * inputEdges.size() );
|
// edges.reserve( 2 * inputEdges.size() );
|
||||||
for ( std::vector< NodeBasedEdge >::const_iterator i = inputEdges.begin(); i != inputEdges.end(); ++i ) {
|
for ( std::vector< NodeBasedEdge >::const_iterator i = inputEdges.begin(); i != inputEdges.end(); ++i ) {
|
||||||
|
|
||||||
@ -123,13 +123,13 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory(int nodes, std::vector<NodeBasedEdg
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::vector<NodeBasedEdge>().swap(inputEdges);
|
std::vector<NodeBasedEdge>().swap(inputEdges);
|
||||||
std::vector<_NodeBasedEdge>(edges).swap(edges);
|
//std::vector<_NodeBasedEdge>(edges).swap(edges);
|
||||||
std::sort( edges.begin(), edges.end() );
|
std::sort( edges.begin(), edges.end() );
|
||||||
|
|
||||||
_nodeBasedGraph.reset(new _NodeBasedDynamicGraph( nodes, edges ));
|
_nodeBasedGraph.reset(new _NodeBasedDynamicGraph( nodes, edges ));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EdgeBasedGraphFactory::GetEdgeBasedEdges(std::vector< EdgeBasedEdge >& outputEdgeList ) {
|
void EdgeBasedGraphFactory::GetEdgeBasedEdges(DeallocatingVector< EdgeBasedEdge >& outputEdgeList ) {
|
||||||
GUARANTEE(0 == outputEdgeList.size(), "Vector passed to EdgeBasedGraphFactory::GetEdgeBasedEdges(..) is not empty");
|
GUARANTEE(0 == outputEdgeList.size(), "Vector passed to EdgeBasedGraphFactory::GetEdgeBasedEdges(..) is not empty");
|
||||||
GUARANTEE(0 != edgeBasedEdges.size(), "No edges in edge based graph");
|
GUARANTEE(0 != edgeBasedEdges.size(), "No edges in edge based graph");
|
||||||
|
|
||||||
@ -255,9 +255,6 @@ void EdgeBasedGraphFactory::Run(const char * originalEdgeDataFilename) {
|
|||||||
//distance += heightPenalty;
|
//distance += heightPenalty;
|
||||||
//distance += ComputeTurnPenalty(u, v, w);
|
//distance += ComputeTurnPenalty(u, v, w);
|
||||||
assert(edgeData1.edgeBasedNodeID != edgeData2.edgeBasedNodeID);
|
assert(edgeData1.edgeBasedNodeID != edgeData2.edgeBasedNodeID);
|
||||||
if(edgeBasedEdges.size() == edgeBasedEdges.capacity()-3) {
|
|
||||||
edgeBasedEdges.reserve(edgeBasedEdges.size()*1.2);
|
|
||||||
}
|
|
||||||
if(originalEdgeData.size() == originalEdgeData.capacity()-3) {
|
if(originalEdgeData.size() == originalEdgeData.capacity()-3) {
|
||||||
originalEdgeData.reserve(originalEdgeData.size()*1.2);
|
originalEdgeData.reserve(originalEdgeData.size()*1.2);
|
||||||
}
|
}
|
||||||
@ -290,7 +287,9 @@ void EdgeBasedGraphFactory::Run(const char * originalEdgeDataFilename) {
|
|||||||
INFO("Removing duplicate nodes (if any)");
|
INFO("Removing duplicate nodes (if any)");
|
||||||
edgeBasedNodes.erase( std::unique(edgeBasedNodes.begin(), edgeBasedNodes.end()), edgeBasedNodes.end() );
|
edgeBasedNodes.erase( std::unique(edgeBasedNodes.begin(), edgeBasedNodes.end()), edgeBasedNodes.end() );
|
||||||
INFO("Applying vector self-swap trick to free up memory");
|
INFO("Applying vector self-swap trick to free up memory");
|
||||||
edgeBasedNodes.swap(edgeBasedNodes);
|
INFO("size: " << edgeBasedNodes.size() << ", cap: " << edgeBasedNodes.capacity());
|
||||||
|
std::vector<EdgeBasedNode>(edgeBasedNodes).swap(edgeBasedNodes);
|
||||||
|
INFO("size: " << edgeBasedNodes.size() << ", cap: " << edgeBasedNodes.capacity());
|
||||||
INFO("Node-based graph contains " << nodeBasedEdgeCounter << " edges");
|
INFO("Node-based graph contains " << nodeBasedEdgeCounter << " edges");
|
||||||
INFO("Edge-based graph contains " << edgeBasedEdges.size() << " edges, blowup is " << (double)edgeBasedEdges.size()/(double)nodeBasedEdgeCounter);
|
INFO("Edge-based graph contains " << edgeBasedEdges.size() << " edges, blowup is " << (double)edgeBasedEdges.size()/(double)nodeBasedEdgeCounter);
|
||||||
INFO("Edge-based graph skipped " << numberOfSkippedTurns << " turns, defined by " << numberOfTurnRestrictions << " restrictions.");
|
INFO("Edge-based graph skipped " << numberOfSkippedTurns << " turns, defined by " << numberOfTurnRestrictions << " restrictions.");
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
#include "../typedefs.h"
|
#include "../typedefs.h"
|
||||||
|
#include "../DataStructures/DeallocatingVector.h"
|
||||||
#include "../DataStructures/DynamicGraph.h"
|
#include "../DataStructures/DynamicGraph.h"
|
||||||
#include "../DataStructures/ExtractorStructs.h"
|
#include "../DataStructures/ExtractorStructs.h"
|
||||||
#include "../DataStructures/HashTable.h"
|
#include "../DataStructures/HashTable.h"
|
||||||
@ -103,7 +104,7 @@ private:
|
|||||||
RestrictionMap _restrictionMap;
|
RestrictionMap _restrictionMap;
|
||||||
|
|
||||||
|
|
||||||
std::vector<EdgeBasedEdge> edgeBasedEdges;
|
DeallocatingVector<EdgeBasedEdge> edgeBasedEdges;
|
||||||
std::vector<EdgeBasedNode> edgeBasedNodes;
|
std::vector<EdgeBasedNode> edgeBasedNodes;
|
||||||
std::vector<OriginalEdgeData> originalEdgeData;
|
std::vector<OriginalEdgeData> originalEdgeData;
|
||||||
std::vector<NodeInfo> inputNodeInfoList;
|
std::vector<NodeInfo> inputNodeInfoList;
|
||||||
@ -127,7 +128,7 @@ public:
|
|||||||
explicit EdgeBasedGraphFactory(int nodes, std::vector<InputEdgeT> & inputEdges, std::vector<NodeID> & _bollardNodes, std::vector<NodeID> & trafficLights, std::vector<_Restriction> & inputRestrictions, std::vector<NodeInfo> & nI, boost::property_tree::ptree speedProfile, std::string & srtm);
|
explicit EdgeBasedGraphFactory(int nodes, std::vector<InputEdgeT> & inputEdges, std::vector<NodeID> & _bollardNodes, std::vector<NodeID> & trafficLights, std::vector<_Restriction> & inputRestrictions, std::vector<NodeInfo> & nI, boost::property_tree::ptree speedProfile, std::string & srtm);
|
||||||
|
|
||||||
void Run(const char * originalEdgeDataFilename);
|
void Run(const char * originalEdgeDataFilename);
|
||||||
void GetEdgeBasedEdges( std::vector< EdgeBasedEdge >& edges );
|
void GetEdgeBasedEdges( DeallocatingVector< EdgeBasedEdge >& edges );
|
||||||
void GetEdgeBasedNodes( std::vector< EdgeBasedNode> & nodes);
|
void GetEdgeBasedNodes( std::vector< EdgeBasedNode> & nodes);
|
||||||
void GetOriginalEdgeData( std::vector< OriginalEdgeData> & originalEdgeData);
|
void GetOriginalEdgeData( std::vector< OriginalEdgeData> & originalEdgeData);
|
||||||
short AnalyzeTurn(const NodeID u, const NodeID v, const NodeID w) const;
|
short AnalyzeTurn(const NodeID u, const NodeID v, const NodeID w) const;
|
||||||
|
@ -103,7 +103,7 @@ public:
|
|||||||
|
|
||||||
/** Default constructor. target and weight are set to 0.*/
|
/** Default constructor. target and weight are set to 0.*/
|
||||||
EdgeBasedEdge() :
|
EdgeBasedEdge() :
|
||||||
_source(0), _target(0), _edgeID(0)/*, _nameID1(0)*/, _weight(0), _forward(0), _backward(0)/*, _turnInstruction(0)*/ { assert(false); } //shall not be used.
|
_source(0), _target(0), _edgeID(0), _weight(0), _forward(false), _backward(false) { }
|
||||||
|
|
||||||
explicit EdgeBasedEdge(NodeID s, NodeID t, NodeID v, EdgeWeight w, bool f, bool b) :
|
explicit EdgeBasedEdge(NodeID s, NodeID t, NodeID v, EdgeWeight w, bool f, bool b) :
|
||||||
_source(s), _target(t), _edgeID(v), _weight(w), _forward(f), _backward(b){}
|
_source(s), _target(t), _edgeID(v), _weight(w), _forward(f), _backward(b){}
|
||||||
|
@ -42,25 +42,14 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
|||||||
|
|
||||||
#include "ExtractorStructs.h"
|
#include "ExtractorStructs.h"
|
||||||
#include "GridEdge.h"
|
#include "GridEdge.h"
|
||||||
#include "LRUCache.h"
|
|
||||||
#include "Percent.h"
|
#include "Percent.h"
|
||||||
#include "PhantomNodes.h"
|
#include "PhantomNodes.h"
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
#include "StaticGraph.h"
|
#include "StaticGraph.h"
|
||||||
#include "../Algorithms/Bresenham.h"
|
#include "../Algorithms/Bresenham.h"
|
||||||
|
|
||||||
static const unsigned MAX_CACHE_ELEMENTS = 1000;
|
|
||||||
|
|
||||||
namespace NNGrid{
|
namespace NNGrid{
|
||||||
|
|
||||||
//struct IdenticalHashFunction {
|
|
||||||
//public:
|
|
||||||
// inline unsigned operator ()(const unsigned value) const {
|
|
||||||
// return value;
|
|
||||||
// }
|
|
||||||
//};
|
|
||||||
|
|
||||||
|
|
||||||
static boost::thread_specific_ptr<std::ifstream> localStream;
|
static boost::thread_specific_ptr<std::ifstream> localStream;
|
||||||
|
|
||||||
template<bool WriteAccess = false>
|
template<bool WriteAccess = false>
|
||||||
@ -99,7 +88,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename EdgeT>
|
template<typename EdgeT>
|
||||||
void ConstructGrid(std::vector<EdgeT> & edgeList, char * ramIndexOut, char * fileIndexOut) {
|
inline void ConstructGrid(std::vector<EdgeT> & edgeList, char * ramIndexOut, char * fileIndexOut) {
|
||||||
//TODO: Implement this using STXXL-Streams
|
//TODO: Implement this using STXXL-Streams
|
||||||
#ifndef ROUTED
|
#ifndef ROUTED
|
||||||
Percent p(edgeList.size());
|
Percent p(edgeList.size());
|
||||||
@ -141,7 +130,7 @@ public:
|
|||||||
entriesInFileWithRAMSameIndex.push_back(gridEntry);
|
entriesInFileWithRAMSameIndex.push_back(gridEntry);
|
||||||
}
|
}
|
||||||
cellMap.clear();
|
cellMap.clear();
|
||||||
BuildCellIndexToFileIndexMap(indexInRamTable, cellMap);
|
BuildCellIndexToFileIndexMap(indexInRamTable, cellMap);
|
||||||
/*unsigned numberOfBytesInCell = */FillCell(entriesInFileWithRAMSameIndex, lastPositionInIndexFile, cellMap);
|
/*unsigned numberOfBytesInCell = */FillCell(entriesInFileWithRAMSameIndex, lastPositionInIndexFile, cellMap);
|
||||||
ramIndexTable[indexInRamTable] = lastPositionInIndexFile;
|
ramIndexTable[indexInRamTable] = lastPositionInIndexFile;
|
||||||
entriesInFileWithRAMSameIndex.clear();
|
entriesInFileWithRAMSameIndex.clear();
|
||||||
@ -324,7 +313,7 @@ private:
|
|||||||
return (std::fabs(d1 - d2) < 0.0001);
|
return (std::fabs(d1 - d2) < 0.0001);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned FillCell(std::vector<GridEntry>& entriesWithSameRAMIndex, const unsigned long fileOffset, boost::unordered_map< unsigned, unsigned > & cellMap ) {
|
inline unsigned FillCell(std::vector<GridEntry>& entriesWithSameRAMIndex, const unsigned long fileOffset, boost::unordered_map< unsigned, unsigned > & cellMap ) {
|
||||||
std::vector<char> tmpBuffer(32*32*4096,0);
|
std::vector<char> tmpBuffer(32*32*4096,0);
|
||||||
unsigned long indexIntoTmpBuffer = 0;
|
unsigned long indexIntoTmpBuffer = 0;
|
||||||
unsigned numberOfWrittenBytes = 0;
|
unsigned numberOfWrittenBytes = 0;
|
||||||
@ -376,7 +365,7 @@ private:
|
|||||||
return numberOfWrittenBytes;
|
return numberOfWrittenBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned FlushEntriesWithSameFileIndexToBuffer( std::vector<GridEntry> &vectorWithSameFileIndex, std::vector<char> & tmpBuffer, const unsigned long index) {
|
inline unsigned FlushEntriesWithSameFileIndexToBuffer( std::vector<GridEntry> &vectorWithSameFileIndex, std::vector<char> & tmpBuffer, const unsigned long index) const {
|
||||||
sort( vectorWithSameFileIndex.begin(), vectorWithSameFileIndex.end() );
|
sort( vectorWithSameFileIndex.begin(), vectorWithSameFileIndex.end() );
|
||||||
vectorWithSameFileIndex.erase(unique(vectorWithSameFileIndex.begin(), vectorWithSameFileIndex.end()), vectorWithSameFileIndex.end());
|
vectorWithSameFileIndex.erase(unique(vectorWithSameFileIndex.begin(), vectorWithSameFileIndex.end()), vectorWithSameFileIndex.end());
|
||||||
const unsigned lengthOfBucket = vectorWithSameFileIndex.size();
|
const unsigned lengthOfBucket = vectorWithSameFileIndex.size();
|
||||||
@ -472,7 +461,7 @@ private:
|
|||||||
localStream->read((char *)&result[currentSizeOfResult], lengthOfBucket*sizeof(_GridEdge));
|
localStream->read((char *)&result[currentSizeOfResult], lengthOfBucket*sizeof(_GridEdge));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddEdge(const _GridEdge & edge) {
|
inline void AddEdge(const _GridEdge & edge) {
|
||||||
#ifndef ROUTED
|
#ifndef ROUTED
|
||||||
std::vector<BresenhamPixel> indexList;
|
std::vector<BresenhamPixel> indexList;
|
||||||
GetListOfIndexesForEdgeAndGridSize(edge.startCoord, edge.targetCoord, indexList);
|
GetListOfIndexesForEdgeAndGridSize(edge.startCoord, edge.targetCoord, indexList);
|
||||||
@ -521,7 +510,7 @@ private:
|
|||||||
return (p-x)*(p-x) + (q-y)*(q-y);
|
return (p-x)*(p-x) + (q-y)*(q-y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetListOfIndexesForEdgeAndGridSize(const _Coordinate& start, const _Coordinate& target, std::vector<BresenhamPixel> &indexList) const {
|
inline void GetListOfIndexesForEdgeAndGridSize(const _Coordinate& start, const _Coordinate& target, std::vector<BresenhamPixel> &indexList) const {
|
||||||
double lat1 = start.lat/100000.;
|
double lat1 = start.lat/100000.;
|
||||||
double lon1 = start.lon/100000.;
|
double lon1 = start.lon/100000.;
|
||||||
|
|
||||||
|
@ -43,6 +43,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
|||||||
#include "Contractor/Contractor.h"
|
#include "Contractor/Contractor.h"
|
||||||
#include "Contractor/EdgeBasedGraphFactory.h"
|
#include "Contractor/EdgeBasedGraphFactory.h"
|
||||||
#include "DataStructures/BinaryHeap.h"
|
#include "DataStructures/BinaryHeap.h"
|
||||||
|
#include "DataStructures/DeallocatingVector.h"
|
||||||
#include "DataStructures/ExtractorStructs.h"
|
#include "DataStructures/ExtractorStructs.h"
|
||||||
#include "DataStructures/NNGrid.h"
|
#include "DataStructures/NNGrid.h"
|
||||||
#include "DataStructures/QueryEdge.h"
|
#include "DataStructures/QueryEdge.h"
|
||||||
@ -125,21 +126,14 @@ int main (int argc, char *argv[]) {
|
|||||||
INFO("Generating edge-expanded graph representation");
|
INFO("Generating edge-expanded graph representation");
|
||||||
EdgeBasedGraphFactory * edgeBasedGraphFactory = new EdgeBasedGraphFactory (nodeBasedNodeNumber, edgeList, bollardNodes, trafficLightNodes, inputRestrictions, internalToExternalNodeMapping, speedProfile, SRTM_ROOT);
|
EdgeBasedGraphFactory * edgeBasedGraphFactory = new EdgeBasedGraphFactory (nodeBasedNodeNumber, edgeList, bollardNodes, trafficLightNodes, inputRestrictions, internalToExternalNodeMapping, speedProfile, SRTM_ROOT);
|
||||||
std::vector<ImportEdge>().swap(edgeList);
|
std::vector<ImportEdge>().swap(edgeList);
|
||||||
|
|
||||||
edgeBasedGraphFactory->Run(edgeOut);
|
edgeBasedGraphFactory->Run(edgeOut);
|
||||||
std::vector<_Restriction>().swap(inputRestrictions);
|
std::vector<_Restriction>().swap(inputRestrictions);
|
||||||
std::vector<NodeID>().swap(bollardNodes);
|
std::vector<NodeID>().swap(bollardNodes);
|
||||||
std::vector<NodeID>().swap(trafficLightNodes);
|
std::vector<NodeID>().swap(trafficLightNodes);
|
||||||
NodeID edgeBasedNodeNumber = edgeBasedGraphFactory->GetNumberOfNodes();
|
NodeID edgeBasedNodeNumber = edgeBasedGraphFactory->GetNumberOfNodes();
|
||||||
std::vector<EdgeBasedEdge> edgeBasedEdgeList;
|
DeallocatingVector<EdgeBasedEdge> edgeBasedEdgeList;
|
||||||
edgeBasedGraphFactory->GetEdgeBasedEdges(edgeBasedEdgeList);
|
edgeBasedGraphFactory->GetEdgeBasedEdges(edgeBasedEdgeList);
|
||||||
|
|
||||||
// stxxl::vector<EdgeBasedEdge> externalEdgeBasedEdgeList;
|
|
||||||
// BOOST_FOREACH(EdgeBasedEdge & edge, edgeBasedEdgeList) {
|
|
||||||
// externalEdgeBasedEdgeList.push_back(edge);
|
|
||||||
// }
|
|
||||||
// std::vector<EdgeBasedEdge>().swap(edgeBasedEdgeList);
|
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* Writing info on original (node-based) nodes
|
* Writing info on original (node-based) nodes
|
||||||
*/
|
*/
|
||||||
@ -191,7 +185,7 @@ int main (int argc, char *argv[]) {
|
|||||||
contractor->Run();
|
contractor->Run();
|
||||||
INFO("Contraction took " << get_timestamp() - contractionStartedTimestamp << " sec");
|
INFO("Contraction took " << get_timestamp() - contractionStartedTimestamp << " sec");
|
||||||
|
|
||||||
std::vector< QueryEdge > contractedEdgeList;
|
DeallocatingVector< QueryEdge > contractedEdgeList;
|
||||||
contractor->GetEdges( contractedEdgeList );
|
contractor->GetEdges( contractedEdgeList );
|
||||||
delete contractor;
|
delete contractor;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user