Backport from Monav
This commit is contained in:
		
							parent
							
								
									c6f6a7baed
								
							
						
					
					
						commit
						afaca23f12
					
				| @ -43,19 +43,16 @@ class Contractor { | |||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
| 
 | 
 | ||||||
|     union _MiddleName { |     struct _EdgeBasedContractorEdgeData { | ||||||
|         NodeID middle; |  | ||||||
|         NodeID nameID; |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     struct _EdgeData { |  | ||||||
|         unsigned distance; |         unsigned distance; | ||||||
|         unsigned originalEdges : 29; |         unsigned originalEdges; | ||||||
|         bool shortcut : 1; |         unsigned via; | ||||||
|         bool forward : 1; |         unsigned nameID1; | ||||||
|         bool backward : 1; |         unsigned nameID2; | ||||||
|         short type:6; |         bool shortcut; | ||||||
|         _MiddleName middleName; |         bool forward; | ||||||
|  |         bool backward; | ||||||
|  |         short turnType; | ||||||
|     } data; |     } data; | ||||||
| 
 | 
 | ||||||
|     struct _HeapData { |     struct _HeapData { | ||||||
| @ -64,7 +61,7 @@ private: | |||||||
|         _HeapData( bool t ) : target(t) {} |         _HeapData( bool t ) : target(t) {} | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     typedef DynamicGraph< _EdgeData > _DynamicGraph; |     typedef DynamicGraph< _EdgeBasedContractorEdgeData > _DynamicGraph; | ||||||
|     typedef BinaryHeap< NodeID, NodeID, int, _HeapData> _Heap; |     typedef BinaryHeap< NodeID, NodeID, int, _HeapData> _Heap; | ||||||
|     typedef _DynamicGraph::InputEdge _ImportEdge; |     typedef _DynamicGraph::InputEdge _ImportEdge; | ||||||
| 
 | 
 | ||||||
| @ -118,8 +115,9 @@ public: | |||||||
|             } |             } | ||||||
| #endif | #endif | ||||||
|             edge.data.shortcut = false; |             edge.data.shortcut = false; | ||||||
|             edge.data.middleName.nameID = i->name(); |             edge.data.nameID1 = i->nameID1(); | ||||||
|             edge.data.type = i->type(); |             edge.data.nameID2 = i->nameID2(); | ||||||
|  |             edge.data.turnType = i->turnType(); | ||||||
|             edge.data.forward = i->isForward(); |             edge.data.forward = i->isForward(); | ||||||
|             edge.data.backward = i->isBackward(); |             edge.data.backward = i->isBackward(); | ||||||
|             edge.data.originalEdges = 1; |             edge.data.originalEdges = 1; | ||||||
| @ -129,7 +127,7 @@ public: | |||||||
|             edge.data.backward = i->isForward(); |             edge.data.backward = i->isForward(); | ||||||
|             edges.push_back( edge ); |             edges.push_back( edge ); | ||||||
|         } |         } | ||||||
| //        std::vector< InputEdge >().swap( inputEdges ); //free memory
 |         //        std::vector< InputEdge >().swap( inputEdges ); //free memory
 | ||||||
| #ifdef _GLIBCXX_PARALLEL | #ifdef _GLIBCXX_PARALLEL | ||||||
|         __gnu_parallel::sort( edges.begin(), edges.end() ); |         __gnu_parallel::sort( edges.begin(), edges.end() ); | ||||||
| #else | #else | ||||||
| @ -139,9 +137,9 @@ public: | |||||||
|         for ( NodeID i = 0; i < edges.size(); ) { |         for ( NodeID i = 0; i < edges.size(); ) { | ||||||
|             const NodeID source = edges[i].source; |             const NodeID source = edges[i].source; | ||||||
|             const NodeID target = edges[i].target; |             const NodeID target = edges[i].target; | ||||||
|             const NodeID middle = edges[i].data.middleName.nameID; |             const NodeID via = edges[i].data.via; | ||||||
|             const short type = edges[i].data.type; |             const short turnType = edges[i].data.turnType; | ||||||
|             assert(type >= 0); |             assert(turnType >= 0); | ||||||
|             //remove eigenloops
 |             //remove eigenloops
 | ||||||
|             if ( source == target ) { |             if ( source == target ) { | ||||||
|                 i++; |                 i++; | ||||||
| @ -153,9 +151,11 @@ public: | |||||||
|             forwardEdge.target = backwardEdge.target = target; |             forwardEdge.target = backwardEdge.target = target; | ||||||
|             forwardEdge.data.forward = backwardEdge.data.backward = true; |             forwardEdge.data.forward = backwardEdge.data.backward = true; | ||||||
|             forwardEdge.data.backward = backwardEdge.data.forward = false; |             forwardEdge.data.backward = backwardEdge.data.forward = false; | ||||||
|             forwardEdge.data.type = backwardEdge.data.type = type; |             forwardEdge.data.turnType = backwardEdge.data.turnType = turnType; | ||||||
|             forwardEdge.data.middleName.nameID = backwardEdge.data.middleName.nameID = middle; |             forwardEdge.data.nameID1 = backwardEdge.data.nameID2 = edges[i].data.nameID1; | ||||||
|  |             forwardEdge.data.nameID2 = backwardEdge.data.nameID1 = edges[i].data.nameID2; | ||||||
|             forwardEdge.data.shortcut = backwardEdge.data.shortcut = false; |             forwardEdge.data.shortcut = backwardEdge.data.shortcut = false; | ||||||
|  |             forwardEdge.data.via = backwardEdge.data.via = via; | ||||||
|             forwardEdge.data.originalEdges = backwardEdge.data.originalEdges = 1; |             forwardEdge.data.originalEdges = backwardEdge.data.originalEdges = 1; | ||||||
|             forwardEdge.data.distance = backwardEdge.data.distance = std::numeric_limits< int >::max(); |             forwardEdge.data.distance = backwardEdge.data.distance = std::numeric_limits< int >::max(); | ||||||
|             //remove parallel edges
 |             //remove parallel edges
 | ||||||
| @ -295,12 +295,12 @@ public: | |||||||
|                         const NodeID target = _graph->GetTarget( e ); |                         const NodeID target = _graph->GetTarget( e ); | ||||||
|                         if ( target != edge.target ) |                         if ( target != edge.target ) | ||||||
|                             continue; |                             continue; | ||||||
|                         _EdgeData& data = _graph->GetEdgeData( e ); |                         _EdgeBasedContractorEdgeData& data = _graph->GetEdgeData( e ); | ||||||
|                         if ( data.distance != edge.data.distance ) |                         if ( data.distance != edge.data.distance ) | ||||||
|                             continue; |                             continue; | ||||||
|                         if ( data.shortcut != edge.data.shortcut ) |                         if ( data.shortcut != edge.data.shortcut ) | ||||||
|                             continue; |                             continue; | ||||||
|                         if ( data.middleName.middle != edge.data.middleName.middle ) |                         if ( data.via != edge.data.via ) | ||||||
|                             continue; |                             continue; | ||||||
|                         data.forward |= edge.data.forward; |                         data.forward |= edge.data.forward; | ||||||
|                         data.backward |= edge.data.backward; |                         data.backward |= edge.data.backward; | ||||||
| @ -340,7 +340,7 @@ public: | |||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         cout << "[contractor] checking sanity of generated data ..." << flush; |         cout << "[contractor] checking sanity of generated data ..." << flush; | ||||||
|         _CheckCH<_EdgeData>(); |         _CheckCH<_EdgeBasedContractorEdgeData>(); | ||||||
|         cout << "ok" << endl; |         cout << "ok" << endl; | ||||||
|         std::cout << "[contractor] max level: " << maxDepth << std::endl; |         std::cout << "[contractor] max level: " << maxDepth << std::endl; | ||||||
|     } |     } | ||||||
| @ -351,20 +351,15 @@ public: | |||||||
|         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++ ) { |             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 _EdgeData& data = _graph->GetEdgeData( edge ); |                 const _EdgeBasedContractorEdgeData& data = _graph->GetEdgeData( edge ); | ||||||
|                 Edge newEdge; |                 Edge newEdge; | ||||||
|                 newEdge.source = node; |                 newEdge.source = node; | ||||||
|                 newEdge.target = target; |                 newEdge.target = target; | ||||||
|                 newEdge.data.distance = data.distance; |                 newEdge.data.distance = data.distance; | ||||||
|                 newEdge.data.shortcut = data.shortcut; |                 newEdge.data.shortcut = data.shortcut; | ||||||
|                 if(data.shortcut) { |                 newEdge.data.via = data.via; | ||||||
|                     newEdge.data.middleName.middle = data.middleName.middle; |                 newEdge.data.nameID1 = data.nameID1; | ||||||
|                     newEdge.data.type = -1; |                 newEdge.data.nameID2 = data.nameID2; | ||||||
|                 } else { |  | ||||||
|                     newEdge.data.middleName.nameID = data.middleName.nameID; |  | ||||||
|                     newEdge.data.type = data.type; |  | ||||||
|                     assert(newEdge.data.type >= 0); |  | ||||||
|                 } |  | ||||||
| 
 | 
 | ||||||
|                 newEdge.data.forward = data.forward; |                 newEdge.data.forward = data.forward; | ||||||
|                 newEdge.data.backward = data.backward; |                 newEdge.data.backward = data.backward; | ||||||
| @ -383,6 +378,7 @@ private: | |||||||
|         _Heap& heap = data->heap; |         _Heap& heap = data->heap; | ||||||
| 
 | 
 | ||||||
|         unsigned nodes = 0; |         unsigned nodes = 0; | ||||||
|  |         unsigned targetsFound = 0; | ||||||
|         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 ); | ||||||
| @ -392,9 +388,15 @@ private: | |||||||
|             if ( distance > maxDistance ) |             if ( distance > maxDistance ) | ||||||
|                 return; |                 return; | ||||||
| 
 | 
 | ||||||
|  |             if ( heap.GetData( node ).target ) { | ||||||
|  |                 targetsFound++; | ||||||
|  |                 if ( targetsFound >= numTargets ) | ||||||
|  |                     return; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|             //iterate over all edges of node
 |             //iterate over all edges of node
 | ||||||
|             for ( _DynamicGraph::EdgeIterator edge = _graph->BeginEdges( node ), endEdges = _graph->EndEdges( node ); edge != endEdges; ++edge ) { |             for ( _DynamicGraph::EdgeIterator edge = _graph->BeginEdges( node ), endEdges = _graph->EndEdges( node ); edge != endEdges; ++edge ) { | ||||||
|                 const _EdgeData& data = _graph->GetEdgeData( edge ); |                 const _EdgeBasedContractorEdgeData& data = _graph->GetEdgeData( edge ); | ||||||
|                 if ( !data.forward ) |                 if ( !data.forward ) | ||||||
|                     continue; |                     continue; | ||||||
|                 const NodeID to = _graph->GetTarget( edge ); |                 const NodeID to = _graph->GetTarget( edge ); | ||||||
| @ -442,8 +444,8 @@ private: | |||||||
|             for ( _DynamicGraph::EdgeIterator edge = _graph->BeginEdges( node ), endEdges = _graph->EndEdges( node ); edge != endEdges; ++edge ) { |             for ( _DynamicGraph::EdgeIterator edge = _graph->BeginEdges( node ), endEdges = _graph->EndEdges( node ); edge != endEdges; ++edge ) { | ||||||
|                 const NodeID start = node; |                 const NodeID start = node; | ||||||
|                 const NodeID target = _graph->GetTarget( edge ); |                 const NodeID target = _graph->GetTarget( edge ); | ||||||
|                 const _EdgeData& data = _graph->GetEdgeData( edge ); |                 const _EdgeBasedContractorEdgeData& data = _graph->GetEdgeData( edge ); | ||||||
|                 const NodeID middle = data.middleName.middle; |                 const NodeID middle = data.via; | ||||||
|                 assert(start != target); |                 assert(start != target); | ||||||
|                 if(data.shortcut) |                 if(data.shortcut) | ||||||
|                 { |                 { | ||||||
| @ -466,7 +468,7 @@ private: | |||||||
|     template< bool Simulate > bool _Contract( _ThreadData* data, NodeID node, _ContractionInformation* stats = NULL ) { |     template< bool Simulate > bool _Contract( _ThreadData* data, NodeID node, _ContractionInformation* stats = NULL ) { | ||||||
|         _Heap& heap = data->heap; |         _Heap& heap = data->heap; | ||||||
|         for ( _DynamicGraph::EdgeIterator inEdge = _graph->BeginEdges( node ), endInEdges = _graph->EndEdges( node ); inEdge != endInEdges; ++inEdge ) { |         for ( _DynamicGraph::EdgeIterator inEdge = _graph->BeginEdges( node ), endInEdges = _graph->EndEdges( node ); inEdge != endInEdges; ++inEdge ) { | ||||||
|             const _EdgeData& inData = _graph->GetEdgeData( inEdge ); |             const _EdgeBasedContractorEdgeData& inData = _graph->GetEdgeData( inEdge ); | ||||||
|             const NodeID source = _graph->GetTarget( inEdge ); |             const NodeID source = _graph->GetTarget( inEdge ); | ||||||
|             if ( Simulate ) { |             if ( Simulate ) { | ||||||
|                 assert( stats != NULL ); |                 assert( stats != NULL ); | ||||||
| @ -482,27 +484,31 @@ private: | |||||||
|             if ( node != source ) |             if ( node != source ) | ||||||
|                 heap.Insert( node, inData.distance, _HeapData() ); |                 heap.Insert( node, inData.distance, _HeapData() ); | ||||||
|             int maxDistance = 0; |             int maxDistance = 0; | ||||||
|  |             unsigned numTargets = 0; | ||||||
| 
 | 
 | ||||||
|             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 _EdgeData& outData = _graph->GetEdgeData( outEdge ); |                 const _EdgeBasedContractorEdgeData& outData = _graph->GetEdgeData( outEdge ); | ||||||
|                 if ( !outData.forward ) |                 if ( !outData.forward ) | ||||||
|                     continue; |                     continue; | ||||||
|                 const NodeID target = _graph->GetTarget( outEdge ); |                 const NodeID target = _graph->GetTarget( outEdge ); | ||||||
|                 const int pathDistance = inData.distance + outData.distance; |                 const int pathDistance = inData.distance + outData.distance; | ||||||
|                 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 ) ); | ||||||
|                 else if ( pathDistance < heap.GetKey( target ) ) |                     numTargets++; | ||||||
|  |                 } else if ( pathDistance < heap.GetKey( target ) ) { | ||||||
|                     heap.DecreaseKey( target, pathDistance ); |                     heap.DecreaseKey( target, pathDistance ); | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|             if( Simulate ) |             if( Simulate ) | ||||||
|                 _Dijkstra( source, maxDistance, 500, data ); |                 _Dijkstra( source, maxDistance, 500, data ); | ||||||
|             else |             else | ||||||
|                 _Dijkstra( source, maxDistance, 1000, data ); |                 _Dijkstra( source, maxDistance, 1000, 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 _EdgeData& outData = _graph->GetEdgeData( outEdge ); |                 const _EdgeBasedContractorEdgeData& outData = _graph->GetEdgeData( outEdge ); | ||||||
|                 if ( !outData.forward ) |                 if ( !outData.forward ) | ||||||
|                     continue; |                     continue; | ||||||
|                 const NodeID target = _graph->GetTarget( outEdge ); |                 const NodeID target = _graph->GetTarget( outEdge ); | ||||||
| @ -521,9 +527,10 @@ private: | |||||||
|                         newEdge.data.distance = pathDistance; |                         newEdge.data.distance = pathDistance; | ||||||
|                         newEdge.data.forward = true; |                         newEdge.data.forward = true; | ||||||
|                         newEdge.data.backward = false; |                         newEdge.data.backward = false; | ||||||
|                         newEdge.data.middleName.middle = node; |                         newEdge.data.via = node; | ||||||
|                         newEdge.data.shortcut = true; |                         newEdge.data.shortcut = true; | ||||||
|                         newEdge.data.originalEdges = outData.originalEdges + inData.originalEdges; |                         newEdge.data.originalEdges = outData.originalEdges + inData.originalEdges; | ||||||
|  | 
 | ||||||
|                         data->insertedEdges.push_back( newEdge ); |                         data->insertedEdges.push_back( newEdge ); | ||||||
|                         std::swap( newEdge.source, newEdge.target ); |                         std::swap( newEdge.source, newEdge.target ); | ||||||
|                         newEdge.data.forward = false; |                         newEdge.data.forward = false; | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user