@ -1,5 +1,6 @@
# include "shortestPaths.h"
# include "shortestPaths.h"
# include "graph.h"
# include "graph.h"
# include "constants.h"
namespace storm {
namespace storm {
namespace utility {
namespace utility {
@ -8,15 +9,16 @@ namespace storm {
ShortestPathsGenerator < T > : : ShortestPathsGenerator ( std : : shared_ptr < models : : sparse : : Model < T > > model ) : model ( model ) {
ShortestPathsGenerator < T > : : ShortestPathsGenerator ( std : : shared_ptr < models : : sparse : : Model < T > > model ) : model ( model ) {
// FIXME: does this create a copy? I don't need one, so I should avoid that
// FIXME: does this create a copy? I don't need one, so I should avoid that
transitionMatrix = model - > getTransitionMatrix ( ) ;
transitionMatrix = model - > getTransitionMatrix ( ) ;
numStates = model - > getNumberOfStates ( ) ;
// TODO: init various things we'll need later
// - predecessors
computePredecessors ( ) ;
computePredecessors ( ) ;
// - Dijkstra (giving us SP-predecessors, SP-distances)
// gives us SP-predecessors, SP-distances
performDijkstra ( ) ;
performDijkstra ( ) ;
// - SP-successors
computeSPSuccessors ( ) ;
computeSPSuccessors ( ) ;
// - shortest paths
// constructs the recursive shortest path representations
initializeShortestPaths ( ) ;
initializeShortestPaths ( ) ;
}
}
@ -26,9 +28,10 @@ namespace storm {
template < typename T >
template < typename T >
void ShortestPathsGenerator < T > : : computePredecessors ( ) {
void ShortestPathsGenerator < T > : : computePredecessors ( ) {
graphPredecessors . resize ( model - > getN umberOf States( ) ) ;
graphPredecessors . resize ( n umStates) ;
for ( int i = 0 ; i < transitionMatrix . getRowCount ( ) ; i + + ) {
assert ( numStates = = transitionMatrix . getRowCount ( ) ) ;
for ( state_t i = 0 ; i < numStates ; i + + ) {
// what's the difference? TODO
// what's the difference? TODO
//auto foo = transitionMatrix.getRowGroupEntryCount(i);
//auto foo = transitionMatrix.getRowGroupEntryCount(i);
//auto bar = transitionMatrix.getRowGroupSize(i);
//auto bar = transitionMatrix.getRowGroupSize(i);
@ -41,21 +44,52 @@ namespace storm {
template < typename T >
template < typename T >
void ShortestPathsGenerator < T > : : performDijkstra ( ) {
void ShortestPathsGenerator < T > : : performDijkstra ( ) {
auto result = storm : : utility : : graph : : performDijkstra ( * model , transitionMatrix , model - > getInitialStates ( ) ) ;
shortestPathDistances = result . first ;
shortestPathPredecessors = result . second ;
// FIXME: fix bad predecessor result for initial states (either here, or by fixing the Dijkstra)
// the existing Dijkstra isn't working anyway AND
// doesn't fully meet our requirements, so let's roll our own
T inftyDistance = storm : : utility : : zero < T > ( ) ;
T zeroDistance = storm : : utility : : one < T > ( ) ;
shortestPathDistances . resize ( numStates , inftyDistance ) ;
shortestPathPredecessors . resize ( numStates , boost : : optional < state_t > ( ) ) ;
// set serves as priority queue with unique membership
// default comparison on pair actually works fine if distance is the first entry
std : : set < std : : pair < T , state_t > > dijkstraQueue ;
for ( state_t initialState : model - > getInitialStates ( ) ) {
shortestPathDistances [ initialState ] = zeroDistance ;
dijkstraQueue . emplace ( zeroDistance , initialState ) ;
}
while ( ! dijkstraQueue . empty ( ) ) {
state_t currentNode = ( * dijkstraQueue . begin ( ) ) . second ;
dijkstraQueue . erase ( dijkstraQueue . begin ( ) ) ;
for ( auto const & transition : transitionMatrix . getRowGroup ( currentNode ) ) {
state_t otherNode = transition . getColumn ( ) ;
// note that distances are probabilities, thus they are multiplied and larger is better
T alternateDistance = shortestPathDistances [ currentNode ] * transition . getValue ( ) ;
if ( alternateDistance > shortestPathDistances [ otherNode ] ) {
shortestPathDistances [ otherNode ] = alternateDistance ;
shortestPathPredecessors [ otherNode ] = boost : : optional < state_t > ( currentNode ) ;
dijkstraQueue . emplace ( alternateDistance , otherNode ) ;
}
}
}
}
}
template < typename T >
template < typename T >
void ShortestPathsGenerator < T > : : computeSPSuccessors ( ) {
void ShortestPathsGenerator < T > : : computeSPSuccessors ( ) {
shortestPathSuccessors . resize ( model - > getNumberOfStates ( ) ) ;
shortestPathSuccessors . resize ( n umStates) ;
for ( int i = 0 ; i < model - > getNumberOfStates ( ) ; i + + ) {
state_t predecessor = shortestPathPredecessors [ i ] ;
for ( state_t i = 0 ; i < numStates ; i + + ) {
if ( shortestPathPredecessors [ i ] ) {
state_t predecessor = shortestPathPredecessors [ i ] . get ( ) ;
shortestPathSuccessors [ predecessor ] . push_back ( i ) ;
shortestPathSuccessors [ predecessor ] . push_back ( i ) ;
}
}
}
}
}
template < typename T >
template < typename T >
void ShortestPathsGenerator < T > : : initializeShortestPaths ( ) { }
void ShortestPathsGenerator < T > : : initializeShortestPaths ( ) { }