Browse Source

Fixed some issues for state elimination when the provided row is not equal to the column (as possible for mdps).

main
TimQu 10 years ago
parent
commit
da90719097
  1. 8
      src/storm/solver/stateelimination/EliminatorBase.cpp
  2. 39
      src/storm/solver/stateelimination/NondeterministicModelStateEliminator.cpp
  3. 28
      src/storm/solver/stateelimination/NondeterministicModelStateEliminator.h
  4. 9
      src/storm/solver/stateelimination/StateEliminator.cpp
  5. 28
      src/storm/transformer/SparseParametricModelSimplifier.cpp

8
src/storm/solver/stateelimination/EliminatorBase.cpp

@ -61,11 +61,11 @@ namespace storm {
entryIt->setValue(storm::utility::simplify((ValueType) (entryIt->getValue() * columnValue))); entryIt->setValue(storm::utility::simplify((ValueType) (entryIt->getValue() * columnValue)));
} }
} }
updateValue(column, columnValue);
updateValue(row, columnValue);
} }
// Now substitute the row entries in all other rows that contain an element whose column is the current row. // Now substitute the row entries in all other rows that contain an element whose column is the current row.
FlexibleRowType& elementsWithEntryInColumnEqualRow = transposedMatrix.getRow(row);
FlexibleRowType& elementsWithEntryInColumnEqualRow = transposedMatrix.getRow(column);
// In case we have a constrained elimination, we need to keep track of the rows that keep their value // In case we have a constrained elimination, we need to keep track of the rows that keep their value
// in the column equal to the current row. // in the column equal to the current row.
@ -169,7 +169,7 @@ namespace storm {
predecessorForwardTransitions = std::move(newSuccessors); predecessorForwardTransitions = std::move(newSuccessors);
STORM_LOG_TRACE("Fixed new next-state probabilities of predecessor state " << predecessor << "."); STORM_LOG_TRACE("Fixed new next-state probabilities of predecessor state " << predecessor << ".");
updatePredecessor(predecessor, multiplyFactor, column);
updatePredecessor(predecessor, multiplyFactor, row);
STORM_LOG_TRACE("Updating priority of predecessor."); STORM_LOG_TRACE("Updating priority of predecessor.");
updatePriority(predecessor); updatePriority(predecessor);
@ -187,7 +187,7 @@ namespace storm {
// Delete the current state as a predecessor of the successor state only if we are going to remove the // Delete the current state as a predecessor of the successor state only if we are going to remove the
// current state's forward transitions. // current state's forward transitions.
if (clearRow) { if (clearRow) {
FlexibleRowIterator elimIt = std::find_if(successorBackwardTransitions.begin(), successorBackwardTransitions.end(), [&](storm::storage::MatrixEntry<typename storm::storage::FlexibleSparseMatrix<ValueType>::index_type, typename storm::storage::FlexibleSparseMatrix<ValueType>::value_type> const& a) { return a.getColumn() == column; });
FlexibleRowIterator elimIt = std::find_if(successorBackwardTransitions.begin(), successorBackwardTransitions.end(), [&](storm::storage::MatrixEntry<typename storm::storage::FlexibleSparseMatrix<ValueType>::index_type, typename storm::storage::FlexibleSparseMatrix<ValueType>::value_type> const& a) { return a.getColumn() == row; });
STORM_LOG_ASSERT(elimIt != successorBackwardTransitions.end(), "Expected a proper backward transition from " << successorEntry.getColumn() << " to " << column << ", but found none."); STORM_LOG_ASSERT(elimIt != successorBackwardTransitions.end(), "Expected a proper backward transition from " << successorEntry.getColumn() << " to " << column << ", but found none.");
successorBackwardTransitions.erase(elimIt); successorBackwardTransitions.erase(elimIt);
} }

39
src/storm/solver/stateelimination/NondeterministicModelStateEliminator.cpp

@ -0,0 +1,39 @@
#include "storm/solver/stateelimination/NondeterministicModelStateEliminator.h"
#include "storm/utility/macros.h"
#include "storm/utility/constants.h"
#include "storm/exceptions/InvalidArgumentException.h"
namespace storm {
namespace solver {
namespace stateelimination {
template<typename ValueType>
NondeterministicModelStateEliminator<ValueType>::NondeterministicModelStateEliminator(storm::storage::FlexibleSparseMatrix<ValueType>& transitionMatrix, storm::storage::FlexibleSparseMatrix<ValueType>& backwardTransitions, std::vector<ValueType>& rowValues)
: StateEliminator<ValueType>(transitionMatrix, backwardTransitions), rowValues(rowValues) {
STORM_LOG_THROW(transitionMatrix.getRowCount() == backwardTransitions.getColumnCount() && transitionMatrix.getColumnCount() == backwardTransitions.getRowCount(), storm::exceptions::InvalidArgumentException, "Invalid matrix dimensions of forward/backwards transition matrices.");
STORM_LOG_THROW(rowValues.size() == transitionMatrix.getRowCount(), storm::exceptions::InvalidArgumentException, "Invalid size of row value vector");
// Intentionally left empty
}
template<typename ValueType>
void NondeterministicModelStateEliminator<ValueType>::updateValue(storm::storage::sparse::state_type const& row, ValueType const& loopProbability) {
rowValues[row] = storm::utility::simplify((ValueType) (loopProbability * rowValues[row]));
}
template<typename ValueType>
void NondeterministicModelStateEliminator<ValueType>::updatePredecessor(storm::storage::sparse::state_type const& predecessorRow, ValueType const& probability, storm::storage::sparse::state_type const& row) {
rowValues[predecessorRow] = storm::utility::simplify((ValueType) (rowValues[predecessorRow] + storm::utility::simplify((ValueType) (probability * rowValues[row]))));
}
template class NondeterministicModelStateEliminator<double>;
#ifdef STORM_HAVE_CARL
template class NondeterministicModelStateEliminator<storm::RationalNumber>;
template class NondeterministicModelStateEliminator<storm::RationalFunction>;
#endif
} // namespace stateelimination
} // namespace storage
} // namespace storm

28
src/storm/solver/stateelimination/NondeterministicModelStateEliminator.h

@ -0,0 +1,28 @@
#ifndef STORM_SOLVER_STATEELIMINATION_NONDETERMINISTICMODELSTATEELIMINATOR_H_
#define STORM_SOLVER_STATEELIMINATION_NONDETERMINISTICMODELSTATEELIMINATOR_H_
#include "storm/solver/stateelimination/StateEliminator.h"
namespace storm {
namespace solver {
namespace stateelimination {
template<typename ValueType>
class NondeterministicModelStateEliminator : public StateEliminator<ValueType> {
public:
NondeterministicModelStateEliminator(storm::storage::FlexibleSparseMatrix<ValueType>& transitionMatrix, storm::storage::FlexibleSparseMatrix<ValueType>& backwardTransitions, std::vector<ValueType>& rowValues);
// Instantiaton of virtual methods.
virtual void updateValue(storm::storage::sparse::state_type const& row, ValueType const& loopProbability) override;
virtual void updatePredecessor(storm::storage::sparse::state_type const& predecessorRow, ValueType const& probability, storm::storage::sparse::state_type const& row) override;
protected:
std::vector<ValueType>& rowValues;
};
} // namespace stateelimination
} // namespace storage
} // namespace storm
#endif // STORM_SOLVER_STATEELIMINATION_NONDETERMINISTICMODELSTATEELIMINATOR_H_

9
src/storm/solver/stateelimination/StateEliminator.cpp

@ -7,7 +7,7 @@
#include "storm/utility/stateelimination.h" #include "storm/utility/stateelimination.h"
#include "storm/utility/macros.h" #include "storm/utility/macros.h"
#include "storm/utility/constants.h" #include "storm/utility/constants.h"
#include "storm/utility/macros.h"
#include "storm/exceptions/IllegalArgumentException.h"
#include "storm/exceptions/InvalidStateException.h" #include "storm/exceptions/InvalidStateException.h"
namespace storm { namespace storm {
@ -24,7 +24,12 @@ namespace storm {
template<typename ValueType> template<typename ValueType>
void StateEliminator<ValueType>::eliminateState(storm::storage::sparse::state_type state, bool removeForwardTransitions) { void StateEliminator<ValueType>::eliminateState(storm::storage::sparse::state_type state, bool removeForwardTransitions) {
STORM_LOG_TRACE("Eliminating state " << state << "."); STORM_LOG_TRACE("Eliminating state " << state << ".");
this->eliminate(state, state, removeForwardTransitions);
if(this->matrix.hasTrivialRowGrouping()) {
this->eliminate(state, state, removeForwardTransitions);
} else {
STORM_LOG_THROW(this->matrix.getRowGroupSize(state) == 1, storm::exceptions::IllegalArgumentException, "Invoked state elimination on a state with multiple choices. This is not supported.");
this->eliminate(this->matrix.getRowGroupIndices()[state], state, removeForwardTransitions);
}
} }
template class StateEliminator<double>; template class StateEliminator<double>;

28
src/storm/transformer/SparseParametricModelSimplifier.cpp

@ -5,7 +5,7 @@
#include "storm/models/sparse/Dtmc.h" #include "storm/models/sparse/Dtmc.h"
#include "storm/models/sparse/Mdp.h" #include "storm/models/sparse/Mdp.h"
#include "storm/models/sparse/StandardRewardModel.h" #include "storm/models/sparse/StandardRewardModel.h"
#include "storm/solver/stateelimination/PrioritizedStateEliminator.h"
#include "storm/solver/stateelimination/NondeterministicModelStateEliminator.h"
#include "storm/storage/FlexibleSparseMatrix.h" #include "storm/storage/FlexibleSparseMatrix.h"
#include "storm/utility/vector.h" #include "storm/utility/vector.h"
@ -116,32 +116,30 @@ namespace storm {
} }
// Find the states that are to be eliminated // Find the states that are to be eliminated
std::vector<uint_fast64_t> statesToEliminate;
storm::storage::BitVector keptStates(sparseMatrix.getRowGroupCount(), true);
storm::storage::BitVector keptRows(sparseMatrix.getRowCount(), true);
storm::storage::BitVector selectedStates = considerForElimination;
for (auto state : considerForElimination) { for (auto state : considerForElimination) {
if (sparseMatrix.getRowGroupSize(state) == 1 && (!rewardModelName.is_initialized() || storm::utility::isConstant(actionRewards[sparseMatrix.getRowGroupIndices()[state]]))) { if (sparseMatrix.getRowGroupSize(state) == 1 && (!rewardModelName.is_initialized() || storm::utility::isConstant(actionRewards[sparseMatrix.getRowGroupIndices()[state]]))) {
bool hasOnlyConstEntries = true;
for (auto const& entry : sparseMatrix.getRowGroup(state)) { for (auto const& entry : sparseMatrix.getRowGroup(state)) {
if(!storm::utility::isConstant(entry.getValue())) { if(!storm::utility::isConstant(entry.getValue())) {
hasOnlyConstEntries = false;
selectedStates.set(state, false);
break; break;
} }
} }
if (hasOnlyConstEntries) {
statesToEliminate.push_back(state);
keptStates.set(state, false);
keptRows.set(sparseMatrix.getRowGroupIndices()[state], false);
}
} else {
selectedStates.set(state, false);
} }
} }
// invoke elimination and obtain resulting transition matrix // invoke elimination and obtain resulting transition matrix
storm::storage::FlexibleSparseMatrix<typename SparseModelType::ValueType> flexibleMatrix(sparseMatrix); storm::storage::FlexibleSparseMatrix<typename SparseModelType::ValueType> flexibleMatrix(sparseMatrix);
storm::storage::FlexibleSparseMatrix<typename SparseModelType::ValueType> flexibleBackwardTransitions(sparseMatrix.transpose(), true); storm::storage::FlexibleSparseMatrix<typename SparseModelType::ValueType> flexibleBackwardTransitions(sparseMatrix.transpose(), true);
storm::solver::stateelimination::PrioritizedStateEliminator<typename SparseModelType::ValueType> stateEliminator(flexibleMatrix, flexibleBackwardTransitions, statesToEliminate, actionRewards);
stateEliminator.eliminateAll();
storm::storage::SparseMatrix<typename SparseModelType::ValueType> newTransitionMatrix = flexibleMatrix.createSparseMatrix(keptRows, keptStates);
storm::solver::stateelimination::NondeterministicModelStateEliminator<typename SparseModelType::ValueType> stateEliminator(flexibleMatrix, flexibleBackwardTransitions, actionRewards);
for(auto state : selectedStates) {
stateEliminator.eliminateState(state, true);
}
selectedStates.complement();
auto keptRows = sparseMatrix.getRowIndicesOfRowGroups(selectedStates);
storm::storage::SparseMatrix<typename SparseModelType::ValueType> newTransitionMatrix = flexibleMatrix.createSparseMatrix(keptRows, selectedStates);
// obtain the reward model for the resulting system // obtain the reward model for the resulting system
std::unordered_map<std::string, typename SparseModelType::RewardModelType> rewardModels; std::unordered_map<std::string, typename SparseModelType::RewardModelType> rewardModels;
@ -150,7 +148,7 @@ namespace storm {
rewardModels.insert(std::make_pair(*rewardModelName, typename SparseModelType::RewardModelType(boost::none, std::move(actionRewards)))); rewardModels.insert(std::make_pair(*rewardModelName, typename SparseModelType::RewardModelType(boost::none, std::move(actionRewards))));
} }
return std::make_shared<SparseModelType>(std::move(newTransitionMatrix), model.getStateLabeling().getSubLabeling(keptStates), std::move(rewardModels));
return std::make_shared<SparseModelType>(std::move(newTransitionMatrix), model.getStateLabeling().getSubLabeling(selectedStates), std::move(rewardModels));
} }

Loading…
Cancel
Save