Optimization hacks. Saving about 10% preprocessing time and about 1-2%
space
This commit is contained in:
parent
f4cf3596c5
commit
664f133c4b
@ -42,6 +42,9 @@ class Contractor {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
struct _EdgeBasedContractorEdgeData {
|
struct _EdgeBasedContractorEdgeData {
|
||||||
|
_EdgeBasedContractorEdgeData() {}
|
||||||
|
_EdgeBasedContractorEdgeData( unsigned _distance, unsigned _originalEdges, unsigned _via, unsigned _nameID, short _turnInstruction, bool _shortcut, bool _forward, bool _backward) :
|
||||||
|
distance(_distance), originalEdges(_originalEdges), via(_via), nameID(_nameID), turnInstruction(_turnInstruction), shortcut(_shortcut), forward(_forward), backward(_backward) {}
|
||||||
unsigned distance;
|
unsigned distance;
|
||||||
unsigned originalEdges;
|
unsigned originalEdges;
|
||||||
unsigned via;
|
unsigned via;
|
||||||
@ -85,7 +88,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct _NodePartitionor {
|
struct _NodePartitionor {
|
||||||
bool operator()( std::pair< NodeID, bool > nodeData ) {
|
bool operator()( std::pair< NodeID, bool > & nodeData ) const {
|
||||||
return !nodeData.second;
|
return !nodeData.second;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -93,16 +96,16 @@ private:
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
template< class InputEdge >
|
template< class InputEdge >
|
||||||
Contractor( int nodes, std::vector< InputEdge >& inputEdges, unsigned eqf = 2, unsigned oqf = 1, unsigned df = 1) : edgeQuotionFactor(eqf), originalQuotientFactor(oqf), depthFactor(df) {
|
Contractor( int nodes, std::vector< InputEdge >& inputEdges, const double eqf = 8.4, const double oqf = 4.1, const double df = 3.)
|
||||||
|
: edgeQuotionFactor(eqf), originalQuotientFactor(oqf), depthFactor(df) {
|
||||||
std::vector< _ImportEdge > edges;
|
std::vector< _ImportEdge > edges;
|
||||||
edges.reserve( 2 * inputEdges.size() );
|
edges.reserve( 2 * inputEdges.size() );
|
||||||
for ( typename std::vector< InputEdge >::const_iterator i = inputEdges.begin(), e = inputEdges.end(); i != e; ++i ) {
|
BOOST_FOREACH(InputEdge & currentEdge, inputEdges) {
|
||||||
_ImportEdge edge;
|
_ImportEdge edge;
|
||||||
edge.source = i->source();
|
edge.source = currentEdge.source();
|
||||||
edge.target = i->target();
|
edge.target = currentEdge.target();
|
||||||
|
edge.data = _EdgeBasedContractorEdgeData( (std::max)((int)currentEdge.weight(), 1 ), 1, currentEdge.via(), currentEdge.getNameIDOfTurnTarget(), currentEdge.turnInstruction(), false, currentEdge.isForward(), currentEdge.isBackward());
|
||||||
|
|
||||||
edge.data.distance = (std::max)((int)i->weight(), 1 );
|
|
||||||
assert( edge.data.distance > 0 );
|
assert( edge.data.distance > 0 );
|
||||||
#ifdef NDEBUG
|
#ifdef NDEBUG
|
||||||
if ( edge.data.distance > 24 * 60 * 60 * 10 ) {
|
if ( edge.data.distance > 24 * 60 * 60 * 10 ) {
|
||||||
@ -110,21 +113,13 @@ if ( edge.data.distance > 24 * 60 * 60 * 10 ) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
edge.data.shortcut = false;
|
|
||||||
edge.data.nameID = i->getNameIDOfTurnTarget();
|
|
||||||
edge.data.via = i->via();
|
|
||||||
edge.data.turnInstruction = i->turnInstruction();
|
|
||||||
edge.data.forward = i->isForward();
|
|
||||||
edge.data.backward = i->isBackward();
|
|
||||||
edge.data.originalEdges = 1;
|
|
||||||
edges.push_back( edge );
|
edges.push_back( edge );
|
||||||
std::swap( edge.source, edge.target );
|
std::swap( edge.source, edge.target );
|
||||||
edge.data.forward = i->isBackward();
|
edge.data.forward = currentEdge.isBackward();
|
||||||
edge.data.backward = i->isForward();
|
edge.data.backward = currentEdge.isForward();
|
||||||
edges.push_back( edge );
|
edges.push_back( edge );
|
||||||
}
|
}
|
||||||
//remove data from memory
|
//remove data from memory
|
||||||
inputEdges.clear();
|
|
||||||
std::vector< InputEdge >().swap( inputEdges );
|
std::vector< InputEdge >().swap( inputEdges );
|
||||||
|
|
||||||
#ifdef _GLIBCXX_PARALLEL
|
#ifdef _GLIBCXX_PARALLEL
|
||||||
@ -320,14 +315,14 @@ private:
|
|||||||
while ( heap.Size() > 0 ) {
|
while ( heap.Size() > 0 ) {
|
||||||
const NodeID node = heap.DeleteMin();
|
const NodeID node = heap.DeleteMin();
|
||||||
const int distance = heap.GetKey( node );
|
const int distance = heap.GetKey( node );
|
||||||
if ( nodes++ > maxNodes )
|
if ( ++nodes > maxNodes )
|
||||||
return;
|
return;
|
||||||
//Destination settled?
|
//Destination settled?
|
||||||
if ( distance > maxDistance )
|
if ( distance > maxDistance )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ( heap.GetData( node ).target ) {
|
if ( heap.GetData( node ).target ) {
|
||||||
targetsFound++;
|
++targetsFound;
|
||||||
if ( targetsFound >= numTargets )
|
if ( targetsFound >= numTargets )
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -376,7 +371,7 @@ private:
|
|||||||
const NodeID source = _graph->GetTarget( inEdge );
|
const NodeID source = _graph->GetTarget( inEdge );
|
||||||
if ( Simulate ) {
|
if ( Simulate ) {
|
||||||
assert( stats != NULL );
|
assert( stats != NULL );
|
||||||
stats->edgesDeleted++;
|
++stats->edgesDeleted;
|
||||||
stats->originalEdgesDeleted += inData.originalEdges;
|
stats->originalEdgesDeleted += inData.originalEdges;
|
||||||
}
|
}
|
||||||
if ( !inData.backward )
|
if ( !inData.backward )
|
||||||
@ -398,16 +393,16 @@ private:
|
|||||||
maxDistance = std::max( maxDistance, pathDistance );
|
maxDistance = std::max( maxDistance, pathDistance );
|
||||||
if ( !heap.WasInserted( target ) ) {
|
if ( !heap.WasInserted( target ) ) {
|
||||||
heap.Insert( target, pathDistance, _HeapData( true ) );
|
heap.Insert( target, pathDistance, _HeapData( true ) );
|
||||||
numTargets++;
|
++numTargets;
|
||||||
} else if ( pathDistance < heap.GetKey( target ) ) {
|
} else if ( pathDistance < heap.GetKey( target ) ) {
|
||||||
heap.DecreaseKey( target, pathDistance );
|
heap.DecreaseKey( target, pathDistance );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( Simulate )
|
if( Simulate )
|
||||||
_Dijkstra( maxDistance, numTargets, 500, data );
|
|
||||||
else
|
|
||||||
_Dijkstra( maxDistance, numTargets, 1000, data );
|
_Dijkstra( maxDistance, numTargets, 1000, data );
|
||||||
|
else
|
||||||
|
_Dijkstra( maxDistance, numTargets, 2000, data );
|
||||||
|
|
||||||
for ( _DynamicGraph::EdgeIterator outEdge = _graph->BeginEdges( node ), endOutEdges = _graph->EndEdges( node ); outEdge != endOutEdges; ++outEdge ) {
|
for ( _DynamicGraph::EdgeIterator outEdge = _graph->BeginEdges( node ), endOutEdges = _graph->EndEdges( node ); outEdge != endOutEdges; ++outEdge ) {
|
||||||
const _EdgeBasedContractorEdgeData& outData = _graph->GetEdgeData( outEdge );
|
const _EdgeBasedContractorEdgeData& outData = _graph->GetEdgeData( outEdge );
|
||||||
@ -426,13 +421,7 @@ private:
|
|||||||
_ImportEdge newEdge;
|
_ImportEdge newEdge;
|
||||||
newEdge.source = source;
|
newEdge.source = source;
|
||||||
newEdge.target = target;
|
newEdge.target = target;
|
||||||
newEdge.data.distance = pathDistance;
|
newEdge.data = _EdgeBasedContractorEdgeData( pathDistance, outData.originalEdges + inData.originalEdges, node, 0, inData.turnInstruction, true, true, false);;
|
||||||
newEdge.data.forward = true;
|
|
||||||
newEdge.data.backward = false;
|
|
||||||
newEdge.data.via = node;
|
|
||||||
newEdge.data.shortcut = true;
|
|
||||||
newEdge.data.turnInstruction = inData.turnInstruction;
|
|
||||||
newEdge.data.originalEdges = outData.originalEdges + inData.originalEdges;
|
|
||||||
insertedEdges.push_back( newEdge );
|
insertedEdges.push_back( newEdge );
|
||||||
std::swap( newEdge.source, newEdge.target );
|
std::swap( newEdge.source, newEdge.target );
|
||||||
newEdge.data.forward = false;
|
newEdge.data.forward = false;
|
||||||
@ -443,7 +432,7 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( !Simulate ) {
|
if ( !Simulate ) {
|
||||||
for ( int i = insertedEdgesSize, iend = insertedEdges.size(); i < iend; i++ ) {
|
for ( int i = insertedEdgesSize, iend = insertedEdges.size(); i < iend; ++i ) {
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for ( int other = i + 1 ; other < iend ; ++other ) {
|
for ( int other = i + 1 ; other < iend ; ++other ) {
|
||||||
if ( insertedEdges[other].source != insertedEdges[i].source )
|
if ( insertedEdges[other].source != insertedEdges[i].source )
|
||||||
@ -467,15 +456,14 @@ private:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _DeleteIncomingEdges( _ThreadData* data, NodeID node ) {
|
void _DeleteIncomingEdges( _ThreadData* data, NodeID node ) {
|
||||||
std::vector< NodeID >& neighbours = data->neighbours;
|
std::vector< NodeID >& neighbours = data->neighbours;
|
||||||
neighbours.clear();
|
neighbours.clear();
|
||||||
|
|
||||||
//find all neighbours
|
//find all neighbours
|
||||||
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 u = _graph->GetTarget( e );
|
const NodeID u = _graph->GetTarget( e );
|
||||||
if ( u == node )
|
if ( u != node )
|
||||||
continue;
|
|
||||||
neighbours.push_back( u );
|
neighbours.push_back( u );
|
||||||
}
|
}
|
||||||
//eliminate duplicate entries ( forward + backward edges )
|
//eliminate duplicate entries ( forward + backward edges )
|
||||||
@ -483,11 +471,9 @@ private:
|
|||||||
neighbours.resize( std::unique( neighbours.begin(), neighbours.end() ) - neighbours.begin() );
|
neighbours.resize( std::unique( neighbours.begin(), neighbours.end() ) - neighbours.begin() );
|
||||||
|
|
||||||
for ( int i = 0, e = ( int ) neighbours.size(); i < e; ++i ) {
|
for ( int i = 0, e = ( int ) neighbours.size(); i < e; ++i ) {
|
||||||
const NodeID u = neighbours[i];
|
// const NodeID u = neighbours[i];
|
||||||
_graph->DeleteEdgesTo( u, node );
|
_graph->DeleteEdgesTo( neighbours[i], node );
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _UpdateNeighbours( std::vector< double > & priorities, std::vector< _PriorityData > & nodeData, _ThreadData* const data, NodeID node ) {
|
bool _UpdateNeighbours( std::vector< double > & priorities, std::vector< _PriorityData > & nodeData, _ThreadData* const data, NodeID node ) {
|
||||||
@ -506,7 +492,8 @@ private:
|
|||||||
std::sort( neighbours.begin(), neighbours.end() );
|
std::sort( neighbours.begin(), neighbours.end() );
|
||||||
neighbours.resize( std::unique( neighbours.begin(), neighbours.end() ) - neighbours.begin() );
|
neighbours.resize( std::unique( neighbours.begin(), neighbours.end() ) - neighbours.begin() );
|
||||||
|
|
||||||
for ( int i = 0, e = ( int ) neighbours.size(); i < e; ++i ) {
|
int neighbourSize = ( int ) neighbours.size();
|
||||||
|
for ( int i = 0, e = neighbourSize; i < e; ++i ) {
|
||||||
const NodeID u = neighbours[i];
|
const NodeID u = neighbours[i];
|
||||||
priorities[u] = _Evaluate( data, &( nodeData )[u], u );
|
priorities[u] = _Evaluate( data, &( nodeData )[u], u );
|
||||||
}
|
}
|
||||||
@ -558,9 +545,9 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<_DynamicGraph> _graph;
|
boost::shared_ptr<_DynamicGraph> _graph;
|
||||||
unsigned edgeQuotionFactor;
|
double edgeQuotionFactor;
|
||||||
unsigned originalQuotientFactor;
|
double originalQuotientFactor;
|
||||||
unsigned depthFactor;
|
double depthFactor;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CONTRACTOR_H_INCLUDED
|
#endif // CONTRACTOR_H_INCLUDED
|
||||||
|
@ -147,7 +147,7 @@ class DynamicGraph {
|
|||||||
m_edges[newFirstEdge + i ] = m_edges[node.firstEdge + i];
|
m_edges[newFirstEdge + i ] = m_edges[node.firstEdge + i];
|
||||||
makeDummy( node.firstEdge + i );
|
makeDummy( node.firstEdge + i );
|
||||||
}
|
}
|
||||||
for ( EdgeIterator i = node.edges + 1; i < newSize; i++ )
|
for ( EdgeIterator i = node.edges + 1; i < newSize; ++i )
|
||||||
makeDummy( newFirstEdge + i );
|
makeDummy( newFirstEdge + i );
|
||||||
node.firstEdge = newFirstEdge;
|
node.firstEdge = newFirstEdge;
|
||||||
}
|
}
|
||||||
@ -155,8 +155,8 @@ class DynamicGraph {
|
|||||||
Edge &edge = m_edges[node.firstEdge + node.edges];
|
Edge &edge = m_edges[node.firstEdge + node.edges];
|
||||||
edge.target = to;
|
edge.target = to;
|
||||||
edge.data = data;
|
edge.data = data;
|
||||||
m_numEdges++;
|
++m_numEdges;
|
||||||
node.edges++;
|
++node.edges;
|
||||||
return EdgeIterator( node.firstEdge + node.edges );
|
return EdgeIterator( node.firstEdge + node.edges );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,12 +39,13 @@ using namespace std;
|
|||||||
#define INFO(x) do {std::cout << "[info " << __FILE__ << ":" << __LINE__ << "] " << x << std::endl;} while(0);
|
#define INFO(x) do {std::cout << "[info " << __FILE__ << ":" << __LINE__ << "] " << x << std::endl;} while(0);
|
||||||
#define ERR(x) do {std::cerr << "[error " << __FILE__ << ":" << __LINE__ << "] " << x << std::endl; exit(-1);} while(0);
|
#define ERR(x) do {std::cerr << "[error " << __FILE__ << ":" << __LINE__ << "] " << x << std::endl; exit(-1);} while(0);
|
||||||
#define WARN(x) do {std::cerr << "[warn " << __FILE__ << ":" << __LINE__ << "] " << x << std::endl;} while(0);
|
#define WARN(x) do {std::cerr << "[warn " << __FILE__ << ":" << __LINE__ << "] " << x << std::endl;} while(0);
|
||||||
#define GUARANTEE(x,y) do { {do{ if(false == (x)) { ERR(y) } } while(0);} } while(0);
|
|
||||||
|
|
||||||
#ifdef NDEBUG
|
#ifdef NDEBUG
|
||||||
#define DEBUG(x)
|
#define DEBUG(x)
|
||||||
|
#define GUARANTEE(x,y)
|
||||||
#else
|
#else
|
||||||
#define DEBUG(x) do {std::cout << "[debug " << __FILE__ << ":" << __LINE__ << "] " << x << std::endl;} while(0);
|
#define DEBUG(x) do {std::cout << "[debug " << __FILE__ << ":" << __LINE__ << "] " << x << std::endl;} while(0);
|
||||||
|
#define GUARANTEE(x,y) do { {do{ if(false == (x)) { ERR(y) } } while(0);} } while(0);
|
||||||
#endif
|
#endif
|
||||||
#define DELETE(x) do { if(NULL != x) { delete x; x = NULL; } }while(0);
|
#define DELETE(x) do { if(NULL != x) { delete x; x = NULL; } }while(0);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user