Browse Source
Merge branch 'dft-approximation' of https://sselab.de/lab9/private/git/storm into dft-approximation
Merge branch 'dft-approximation' of https://sselab.de/lab9/private/git/storm into dft-approximation
Former-commit-id: 595c5e7891
main
22 changed files with 883 additions and 321 deletions
-
82src/builder/DftExplorationHeuristic.cpp
-
179src/builder/DftExplorationHeuristic.h
-
2src/builder/DftSmtBuilder.cpp
-
1src/builder/ExplicitDFTModelBuilder.cpp
-
328src/builder/ExplicitDFTModelBuilderApprox.cpp
-
57src/builder/ExplicitDFTModelBuilderApprox.h
-
4src/generator/DftNextStateGenerator.cpp
-
58src/modelchecker/dft/DFTModelChecker.cpp
-
7src/modelchecker/dft/DFTModelChecker.h
-
6src/settings/modules/DFTSettings.cpp
-
203src/storage/BucketPriorityQueue.cpp
-
73src/storage/BucketPriorityQueue.h
-
16src/storage/bisimulation/BisimulationDecomposition.cpp
-
8src/storage/bisimulation/BisimulationDecomposition.h
-
28src/storage/bisimulation/DeterministicModelBisimulationDecomposition.cpp
-
10src/storage/bisimulation/DeterministicModelBisimulationDecomposition.h
-
14src/storage/bisimulation/NondeterministicModelBisimulationDecomposition.cpp
-
8src/storage/bisimulation/NondeterministicModelBisimulationDecomposition.h
-
61src/storage/dft/DFTState.cpp
-
55src/storage/dft/DFTState.h
-
2src/storm-dyftee.cpp
-
2src/utility/bitoperations.h
@ -0,0 +1,203 @@ |
|||||
|
#include "src/storage/BucketPriorityQueue.h"
|
||||
|
#include "src/utility/macros.h"
|
||||
|
#include "src/adapters/CarlAdapter.h"
|
||||
|
|
||||
|
#include <cmath>
|
||||
|
|
||||
|
namespace storm { |
||||
|
namespace storage { |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
BucketPriorityQueue<ValueType>::BucketPriorityQueue(size_t nrBuckets, double lowerValue, double ratio) : lowerValue(lowerValue), logBase(std::log(ratio)), nrBuckets(nrBuckets), nrUnsortedItems(0), buckets(nrBuckets), currentBucket(nrBuckets) { |
||||
|
compare = ([this](HeuristicPointer a, HeuristicPointer b) { |
||||
|
return *a < *b; |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
void BucketPriorityQueue<ValueType>::fix() { |
||||
|
if (currentBucket < nrBuckets && nrUnsortedItems > buckets[currentBucket].size() / 10) { |
||||
|
// Fix current bucket
|
||||
|
std::make_heap(buckets[currentBucket].begin(), buckets[currentBucket].end(), compare); |
||||
|
nrUnsortedItems = 0; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
bool BucketPriorityQueue<ValueType>::empty() const { |
||||
|
return currentBucket == nrBuckets && immediateBucket.empty(); |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
std::size_t BucketPriorityQueue<ValueType>::size() const { |
||||
|
size_t size = immediateBucket.size(); |
||||
|
for (size_t i = currentBucket; currentBucket < nrBuckets; ++i) { |
||||
|
size += buckets[i].size(); |
||||
|
} |
||||
|
return size; |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
typename BucketPriorityQueue<ValueType>::HeuristicPointer const& BucketPriorityQueue<ValueType>::top() const { |
||||
|
if (!immediateBucket.empty()) { |
||||
|
return immediateBucket.back(); |
||||
|
} |
||||
|
STORM_LOG_ASSERT(!empty(), "BucketPriorityQueue is empty"); |
||||
|
return buckets[currentBucket].front(); |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
void BucketPriorityQueue<ValueType>::push(HeuristicPointer const& item) { |
||||
|
if (item->isExpand()) { |
||||
|
immediateBucket.push_back(item); |
||||
|
return; |
||||
|
} |
||||
|
size_t bucket = getBucket(item->getPriority()); |
||||
|
if (bucket < currentBucket) { |
||||
|
currentBucket = bucket; |
||||
|
nrUnsortedItems = 0; |
||||
|
} |
||||
|
buckets[bucket].push_back(item); |
||||
|
if (bucket == currentBucket) { |
||||
|
// Insert in first bucket
|
||||
|
if (AUTOSORT) { |
||||
|
std::push_heap(buckets[currentBucket].begin(), buckets[currentBucket].end(), compare); |
||||
|
} else { |
||||
|
++nrUnsortedItems; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
void BucketPriorityQueue<ValueType>::update(HeuristicPointer const& item, double oldPriority) { |
||||
|
STORM_LOG_ASSERT(!item->isExpand(), "Item is marked for expansion"); |
||||
|
size_t newBucket = getBucket(item->getPriority()); |
||||
|
size_t oldBucket = getBucket(oldPriority); |
||||
|
|
||||
|
if (oldBucket == newBucket) { |
||||
|
if (currentBucket < newBucket) { |
||||
|
// No change as the bucket is not sorted yet
|
||||
|
} else { |
||||
|
if (AUTOSORT) { |
||||
|
// Sort first bucket
|
||||
|
fix(); |
||||
|
} else { |
||||
|
++nrUnsortedItems; |
||||
|
} |
||||
|
} |
||||
|
} else { |
||||
|
// Move to new bucket
|
||||
|
STORM_LOG_ASSERT(newBucket < oldBucket, "Will update to higher bucket"); |
||||
|
if (newBucket < currentBucket) { |
||||
|
currentBucket = newBucket; |
||||
|
nrUnsortedItems = 0; |
||||
|
} |
||||
|
// Remove old entry by swap-and-pop
|
||||
|
if (buckets[oldBucket].size() >= 2) { |
||||
|
// Find old index by linear search
|
||||
|
// Notice: using a map to rememeber index was not efficient
|
||||
|
size_t oldIndex = 0; |
||||
|
for ( ; oldIndex < buckets[oldBucket].size(); ++oldIndex) { |
||||
|
if (buckets[oldBucket][oldIndex]->getId() == item->getId()) { |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
STORM_LOG_ASSERT(oldIndex < buckets[oldBucket].size(), "Id " << item->getId() << " not found"); |
||||
|
std::iter_swap(buckets[oldBucket].begin() + oldIndex, buckets[oldBucket].end() - 1); |
||||
|
} |
||||
|
buckets[oldBucket].pop_back(); |
||||
|
// Insert new element
|
||||
|
buckets[newBucket].push_back(item); |
||||
|
if (newBucket == currentBucket) { |
||||
|
if (AUTOSORT) { |
||||
|
// Sort in first bucket
|
||||
|
std::push_heap(buckets[currentBucket].begin(), buckets[currentBucket].end(), compare); |
||||
|
} else { |
||||
|
++nrUnsortedItems; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
template<typename ValueType> |
||||
|
void BucketPriorityQueue<ValueType>::pop() { |
||||
|
if (!immediateBucket.empty()) { |
||||
|
immediateBucket.pop_back(); |
||||
|
return; |
||||
|
} |
||||
|
STORM_LOG_ASSERT(!empty(), "BucketPriorityQueue is empty"); |
||||
|
std::pop_heap(buckets[currentBucket].begin(), buckets[currentBucket].end(), compare); |
||||
|
buckets[currentBucket].pop_back(); |
||||
|
if (buckets[currentBucket].empty()) { |
||||
|
// Find next bucket with elements
|
||||
|
for ( ; currentBucket < nrBuckets; ++currentBucket) { |
||||
|
if (!buckets[currentBucket].empty()) { |
||||
|
nrUnsortedItems = buckets[currentBucket].size(); |
||||
|
if (AUTOSORT) { |
||||
|
fix(); |
||||
|
} |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
typename BucketPriorityQueue<ValueType>::HeuristicPointer BucketPriorityQueue<ValueType>::popTop() { |
||||
|
HeuristicPointer item = top(); |
||||
|
pop(); |
||||
|
return item; |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
size_t BucketPriorityQueue<ValueType>::getBucket(double priority) const { |
||||
|
STORM_LOG_ASSERT(priority >= lowerValue, "Priority " << priority << " is too low"); |
||||
|
size_t newBucket = std::log(priority - lowerValue) / logBase; |
||||
|
if (newBucket >= nrBuckets) { |
||||
|
newBucket = nrBuckets - 1; |
||||
|
} |
||||
|
if (!HIGHER) { |
||||
|
newBucket = nrBuckets-1 - newBucket; |
||||
|
} |
||||
|
//std::cout << "get Bucket: " << priority << ", " << newBucket << std::endl;
|
||||
|
STORM_LOG_ASSERT(newBucket < nrBuckets, "Priority " << priority << " is too high"); |
||||
|
return newBucket; |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
void BucketPriorityQueue<ValueType>::print(std::ostream& out) const { |
||||
|
out << "Bucket priority queue with size " << buckets.size() << ", lower value: " << lowerValue << " and logBase: " << logBase << std::endl; |
||||
|
out << "Immediate bucket: "; |
||||
|
for (HeuristicPointer heuristic : immediateBucket) { |
||||
|
out << heuristic->getId() << ", "; |
||||
|
} |
||||
|
out << std::endl; |
||||
|
out << "Current bucket (" << currentBucket << ") has " << nrUnsortedItems << " unsorted items" << std::endl; |
||||
|
for (size_t bucket = 0; bucket < buckets.size(); ++bucket) { |
||||
|
if (!buckets[bucket].empty()) { |
||||
|
out << "Bucket " << bucket << ":" << std::endl; |
||||
|
for (HeuristicPointer heuristic : buckets[bucket]) { |
||||
|
out << "\t" << heuristic->getId() << ": " << heuristic->getPriority() << std::endl; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
void BucketPriorityQueue<ValueType>::printSizes(std::ostream& out) const { |
||||
|
out << "Bucket sizes: " << immediateBucket.size() << " | "; |
||||
|
for (size_t bucket = 0; bucket < buckets.size(); ++bucket) { |
||||
|
out << buckets[bucket].size() << " "; |
||||
|
} |
||||
|
std::cout << std::endl; |
||||
|
} |
||||
|
|
||||
|
// Template instantiations
|
||||
|
template class BucketPriorityQueue<double>; |
||||
|
|
||||
|
#ifdef STORM_HAVE_CARL
|
||||
|
template class BucketPriorityQueue<storm::RationalFunction>; |
||||
|
#endif
|
||||
|
} |
||||
|
} |
@ -0,0 +1,73 @@ |
|||||
|
#ifndef STORM_STORAGE_BUCKETPRIORITYQUEUE_H_ |
||||
|
#define STORM_STORAGE_BUCKETPRIORITYQUEUE_H_ |
||||
|
|
||||
|
#include "src/builder/DftExplorationHeuristic.h" |
||||
|
#include <algorithm> |
||||
|
#include <functional> |
||||
|
#include <unordered_map> |
||||
|
#include <vector> |
||||
|
|
||||
|
namespace storm { |
||||
|
namespace storage { |
||||
|
|
||||
|
template<typename ValueType> |
||||
|
class BucketPriorityQueue { |
||||
|
|
||||
|
using HeuristicPointer = std::shared_ptr<storm::builder::DFTExplorationHeuristicProbability<ValueType>>; |
||||
|
|
||||
|
public: |
||||
|
explicit BucketPriorityQueue(size_t nrBuckets, double lowerValue, double ratio); |
||||
|
|
||||
|
void fix(); |
||||
|
|
||||
|
bool empty() const; |
||||
|
|
||||
|
std::size_t size() const; |
||||
|
|
||||
|
HeuristicPointer const& top() const; |
||||
|
|
||||
|
void push(HeuristicPointer const& item); |
||||
|
|
||||
|
void update(HeuristicPointer const& item, double oldPriority); |
||||
|
|
||||
|
void pop(); |
||||
|
|
||||
|
HeuristicPointer popTop(); |
||||
|
|
||||
|
void print(std::ostream& out) const; |
||||
|
|
||||
|
void printSizes(std::ostream& out) const; |
||||
|
|
||||
|
private: |
||||
|
|
||||
|
size_t getBucket(double priority) const; |
||||
|
|
||||
|
const double lowerValue; |
||||
|
|
||||
|
const bool HIGHER = true; |
||||
|
|
||||
|
const bool AUTOSORT = false; |
||||
|
|
||||
|
const double logBase; |
||||
|
|
||||
|
const size_t nrBuckets; |
||||
|
|
||||
|
size_t nrUnsortedItems; |
||||
|
|
||||
|
// List of buckets |
||||
|
std::vector<std::vector<HeuristicPointer>> buckets; |
||||
|
|
||||
|
// Bucket containing all items which should be considered immediately |
||||
|
std::vector<HeuristicPointer> immediateBucket; |
||||
|
|
||||
|
// Index of first bucket which contains items |
||||
|
size_t currentBucket; |
||||
|
|
||||
|
std::function<bool(HeuristicPointer, HeuristicPointer)> compare; |
||||
|
|
||||
|
}; |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#endif // STORM_STORAGE_BUCKETPRIORITYQUEUE_H_ |
Write
Preview
Loading…
Cancel
Save
Reference in new issue