You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

98 lines
4.4 KiB

#include "SubsetEnumerator.h"
#include "storm/adapters/RationalFunctionAdapter.h"
#include "storm/utility/eigen.h"
namespace storm {
namespace storage {
namespace geometry {
template< typename DataType>
SubsetEnumerator<DataType>::SubsetEnumerator(uint_fast64_t n, uint_fast64_t k, DataType const& data, SubsetFilter subsetFilter) : n(n), k(k), data(data), filter(subsetFilter){
//Intentionally left empty
}
template< typename DataType>
SubsetEnumerator<DataType>::~SubsetEnumerator(){
//Intentionally left empty
}
template< typename DataType>
std::vector<uint_fast64_t> const& SubsetEnumerator<DataType>::getCurrentSubset(){
return this->current;
}
template< typename DataType>
bool SubsetEnumerator<DataType>::setToFirstSubset(){
if(n < k) return false;
//set the upper boundaries first.
upperBoundaries.clear();
upperBoundaries.reserve(k);
for(uint_fast64_t bound = (n - k); bound < n; ++bound){
upperBoundaries.push_back(bound);
}
//now set the current subset to the very first one
current.clear();
current.reserve(k);
uint_fast64_t newItem = 0;
while(current.size()!= k && newItem<=upperBoundaries[current.size()]){
//Check if it is okay to add the new item...
if(filter(current, newItem, data)){
current.push_back(newItem);
}
++newItem;
}
//Note that we only insert things into the vector if it is "okay" to do so.
//Hence, we have failed iff we were not able to insert k elements.
return current.size() == k;
}
template< typename DataType>
bool SubsetEnumerator<DataType>::incrementSubset(){
//The currentSelection will be the numbers that are already inside of our new subset.
std::vector<uint_fast64_t> currentSelection(current);
currentSelection.pop_back();
uint_fast64_t pos = k-1;
while (true){
//check whether we can increment at the current position
if(current[pos] == upperBoundaries[pos]){
if(pos==0){
//we already moved to the very left and still can not increment.
//Hence, we are already at the last subset
return false;
}
currentSelection.pop_back();
--pos;
} else {
++current[pos];
//check if the new subset is inside our filter
if(filter(currentSelection, current[pos], data)){
//it is, so add it and go on with the position on the right
currentSelection.push_back(current[pos]);
++pos;
if(pos == k){
//we are already at the very right.
//Hence, we have found our new subset of size k
return true;
}
//initialize the value at the new position
current[pos] = current[pos-1];
}
}
}
}
template< typename DataType>
bool SubsetEnumerator<DataType>::trueFilter(std::vector<uint_fast64_t> const&, uint_fast64_t const&, DataType const&) {
return true;
}
template class SubsetEnumerator<std::nullptr_t>;
template class SubsetEnumerator<std::vector<StormEigen::Matrix<double, StormEigen::Dynamic, 1>>>;
template class SubsetEnumerator<std::vector<StormEigen::Matrix<storm::RationalNumber, StormEigen::Dynamic, 1>>>;
template class SubsetEnumerator<StormEigen::Matrix<double, StormEigen::Dynamic, StormEigen::Dynamic>>;
template class SubsetEnumerator<StormEigen::Matrix<storm::RationalNumber, StormEigen::Dynamic, StormEigen::Dynamic>>;
}
}
}