9template <
typename... WeakPtrs>
11 : evaluator(evaluator)
14 throw std::runtime_error(
"GreedyDispatcher: missing evaluator");
16 timestamp = std::numeric_limits<BPMNOS::number>::lowest();
19template <
typename... WeakPtrs>
27template <
typename... WeakPtrs>
31 evaluatedDecisions.emplace( (reward.has_value() ? (
double)reward.value() : std::numeric_limits<double>::max() ), weak_ptrs..., decision->weak_from_this());
37 if ( !decision->timeDependent && decision->dataDependencies.empty() ) {
39 invariantEvaluations.emplace_back(weak_ptrs..., std::move(decision) );
41 else if ( decision->timeDependent && decision->dataDependencies.empty() ) {
43 timeDependentEvaluations.emplace_back(weak_ptrs..., std::move(decision) );
45 else if ( !decision->timeDependent && decision->dataDependencies.size() ) {
46 assert(decision->token);
47 BPMNOS::number instanceId = decision->token->owner->root->instance.value();
49 dataDependentEvaluations[(
long unsigned int)instanceId].emplace_back(weak_ptrs..., std::move(decision) );
51 else if ( decision->timeDependent && decision->dataDependencies.size() ) {
52 assert(decision->token);
53 BPMNOS::number instanceId = decision->token->owner->root->instance.value();
55 timeAndDataDependentEvaluations[(
long unsigned int)instanceId].emplace_back(weak_ptrs..., std::move(decision) );
59template <
typename... WeakPtrs>
62 if ( systemState->currentTime > timestamp ) {
63 timestamp = systemState->currentTime;
67 for (
auto& decisionTuple : decisionsWithoutEvaluation ) {
69 std::apply([
this,&decisionTuple](
auto&&... args) {
70 auto decision = std::get<std::shared_ptr<Decision>>(decisionTuple);
73 auto evaluation = decision->evaluate();
74 this->addEvaluation(std::forward<
decltype(args)>(args)..., evaluation);
77 decisionsWithoutEvaluation.clear();
79 for (
auto decisionTuple : evaluatedDecisions ) {
80 std::weak_ptr<Event>& event_ptr = std::get<
sizeof...(WeakPtrs)+1>(decisionTuple);
82 return event_ptr.lock();
88template <
typename... WeakPtrs>
92 dataUpdate(
static_cast<const DataUpdate*
>(observable));
96template <
typename... WeakPtrs>
98 for (
auto lhs : first ) {
99 if ( second.contains(lhs) ) {
106template <
typename... WeakPtrs>
109 for (
auto it = evaluation.begin(); it != evaluation.end(); ) {
110 auto& decisionTuple = *it;
111 std::shared_ptr<Decision>& decision = std::get<
sizeof...(WeakPtrs)>(decisionTuple);
112 if ( intersect(update->
attributes, decision->dataDependencies) ) {
113 decision->evaluation = std::nullopt;
114 std::apply([&unevaluatedDecisions](
auto&&... args) { unevaluatedDecisions.emplace_back(std::forward<
decltype(args)>(args)...); }, decisionTuple);
117 it = evaluation.erase(it);
125template <
typename... WeakPtrs>
129 if (
auto it = evaluatedDecisions.find((
long unsigned int)update->
instanceId);
130 it != evaluatedDecisions.end()
132 removeObsolete(update,it->second,unevaluatedDecisions);
137 for (
auto it = evaluatedDecisions.begin(); it != evaluatedDecisions.end(); ++it) {
138 removeObsolete(update,it->second,unevaluatedDecisions);
144template <
typename... WeakPtrs>
146 removeDependentEvaluations(update,dataDependentEvaluations,decisionsWithoutEvaluation);
147 removeDependentEvaluations(update,timeAndDataDependentEvaluations,decisionsWithoutEvaluation);
150template <
typename... WeakPtrs>
152 for (
auto& decisionTuple : timeDependentEvaluations ) {
153 std::shared_ptr<Decision>& decision = std::get<
sizeof...(WeakPtrs)>(decisionTuple);
154 decision->evaluation = std::nullopt;
155 std::apply([
this](
auto&&... args) { this->decisionsWithoutEvaluation.emplace_back(std::forward<
decltype(args)>(args)...); }, decisionTuple);
158 timeDependentEvaluations.clear();
160 for (
auto& [ instance, evaluations ] : timeAndDataDependentEvaluations ) {
161 for (
auto& decisionTuple : evaluations ) {
162 std::shared_ptr<Decision>& decision = std::get<
sizeof...(WeakPtrs)>(decisionTuple);
163 decision->evaluation = std::nullopt;
164 std::apply([
this](
auto&&... args) { this->decisionsWithoutEvaluation.emplace_back(std::forward<
decltype(args)>(args)...); }, decisionTuple);
167 timeAndDataDependentEvaluations.clear();
Represents an abstract base class for a pending Evaluator.
virtual void connect(Mediator *mediator)
Class for dispatching the event with the best evaluation.
std::shared_ptr< Event > dispatchEvent(const SystemState *systemState) override
virtual void dataUpdate(const DataUpdate *update)
GreedyDispatcher(Evaluator *evaluator)
void removeDependentEvaluations(const DataUpdate *update, std::unordered_map< long unsigned int, auto_list< WeakPtrs..., std::shared_ptr< Decision > > > &evaluatedDecisions, auto_list< WeakPtrs..., std::shared_ptr< Decision > > &unevaluatedDecisions)
void addEvaluation(WeakPtrs..., std::shared_ptr< Decision > decision, std::optional< double > reward)
void notice(const Observable *observable) override
void connect(Mediator *mediator) override
void removeObsolete(const DataUpdate *update, auto_list< WeakPtrs..., std::shared_ptr< Decision > > &evaluation, auto_list< WeakPtrs..., std::shared_ptr< Decision > > &unevaluatedDecisions)
bool intersect(const std::vector< const BPMNOS::Model::Attribute * > &first, const std::set< const BPMNOS::Model::Attribute * > &second) const
void addSubscriber(Observer *subscriber, ObservableTypes... observableTypes)
A class representing the state that the execution or simulation of a given scenario is in.
List of tuples with automatic removal of tuples containing an expired weak_ptr.
BPMNOS_NUMBER_TYPE number
const std::vector< const BPMNOS::Model::Attribute * > & attributes
const BPMNOS::number instanceId
virtual constexpr Type getObservableType() const =0