BPMN-OS
BPMN for optimization and simulation
Loading...
Searching...
No Matches
BestLimitedChoice.cpp
Go to the documentation of this file.
1#include "BestLimitedChoice.h"
6#include <cassert>
7//#include <iostream>
8
9using namespace BPMNOS::Execution;
10
15
22
23
24void BestLimitedChoice::notice(const Observable* observable) {
26 assert( dynamic_cast<const DecisionRequest*>(observable) );
27 auto request = static_cast<const DecisionRequest*>(observable);
28 // create pseudo decision
29 auto decision = std::make_shared<ChoiceDecision>(request->token, Values(), evaluator);
30 decisionsWithoutEvaluation.emplace_back( request->token->weak_from_this(), request->weak_from_this(), decision );
31 }
32 else {
33 GreedyDispatcher::notice(observable);
34 }
35}
36
37std::shared_ptr<Event> BestLimitedChoice::dispatchEvent( [[maybe_unused]] const SystemState* systemState ) {
38//std::cout << "BestLimitedChoice::dispatchEvent" << std::endl;
39 if ( systemState->currentTime > timestamp ) {
40 timestamp = systemState->currentTime;
41 clockTick();
42 }
43
44 for ( auto& [ token_ptr, request_ptr, _ ] : decisionsWithoutEvaluation ) {
45 auto request = request_ptr.lock();
46 assert( request );
47 // forget previous decision and find new best decision for the request
48 auto decision = determineBestChoices( request );
49 if ( decision ) {
50 addEvaluation( token_ptr, request_ptr, std::move(decision), decision->evaluation );
51 }
52 }
54
55 for ( auto [ cost, token_ptr, request_ptr, event_ptr ] : evaluatedDecisions ) {
56//std::cerr << "Best choice decision " << event_ptr.lock()->jsonify() << " evaluated with " << cost << std::endl;
57 return event_ptr.lock();
58 }
59
60//std::cerr << "No evaluated choice decision" << std::endl;
61 return nullptr;
62}
63
64std::shared_ptr<Decision> BestLimitedChoice::determineBestChoices(std::shared_ptr<const DecisionRequest> request) {
65 auto token = request->token;
66 assert( token->node );
67 assert( token->node->represents<BPMNOS::Model::DecisionTask>() );
68 assert( token->node->extensionElements->represents<BPMNOS::Model::ExtensionElements>() );
69 auto extensionElements = token->node->extensionElements->as<BPMNOS::Model::ExtensionElements>();
70 assert( extensionElements->choices.size() );
71
72 BPMNOS::Values status = token->status;
73 BPMNOS::Values data = *token->data;
74 BPMNOS::Values globals = token->globals;
75 std::vector< BPMNOS::Values > alternativeChoices;
77 tmp.resize(extensionElements->choices.size());
78 determineAlternatives( alternativeChoices, extensionElements, status, data, globals, tmp );
79
80 std::shared_ptr<Decision> bestDecision = nullptr;
81 for ( auto& choices : alternativeChoices ) {
82 auto decision = std::make_shared<ChoiceDecision>(token,choices,evaluator);
83 decision->evaluate();
84 if (
85 decision->evaluation.has_value() &&
86 ( !bestDecision || decision->evaluation.value() < bestDecision->evaluation.value() )
87 ) {
88 bestDecision = decision;
89 }
90 }
91
92 // determine best alternative
93 return bestDecision;
94}
95
96
97void BestLimitedChoice::determineAlternatives( std::vector<BPMNOS::Values>& alternatives, const BPMNOS::Model::ExtensionElements* extensionElements, BPMNOS::Values& status, BPMNOS::Values& data, BPMNOS::Values& globals, BPMNOS::Values& choices, size_t index ) {
98 assert(index < choices.size());
99 auto& choice = extensionElements->choices[index];
100
101 auto choose = [&](BPMNOS::number value) -> void {
102 choices[index] = value;
103 choice->attributeRegistry.setValue(choice->attribute, status, data, globals, choices[index]);
104 if ( index + 1 == choices.size() ) {
105 alternatives.push_back(choices);
106 }
107 else {
108 determineAlternatives(alternatives, extensionElements, status, data, globals, choices, index + 1);
109 }
110 };
111
112 if ( !choice->enumeration.empty() ) {
113 // iterate through all given alternatives
114 for (auto value : choice->getEnumeration(status,data,globals) ) {
115 choose(value);
116 }
117 }
118 else if ( choice->lowerBound.has_value() && choice->upperBound.has_value() ) {
119 auto [min,max] = choice->getBounds(status,data,globals);
120 if ( min == max ) {
121 choose(min);
122 }
123 else if ( min < max ) {
124 choose(min);
125 choose(max);
126 }
127 }
128}
void notice(const Observable *observable) override
void connect(Mediator *mediator) override
std::shared_ptr< Event > dispatchEvent(const SystemState *systemState) override
Represents an abstract base class for a pending Evaluator.
Definition Evaluator.h:15
Class for dispatching the event with the best evaluation.
void addEvaluation(WeakPtrs..., std::shared_ptr< Decision > decision, std::optional< double > reward)
void notice(const Observable *observable) override
void connect(Mediator *mediator) override
void addSubscriber(Observer *subscriber, ObservableTypes... observableTypes)
Definition Notifier.h:16
A class representing the state that the execution or simulation of a given scenario is in.
Definition SystemState.h:21
Class representing a task in which one or more choices have to be made.
Class holding extension elements representing execution data for nodes.
std::vector< std::unique_ptr< Choice > > choices
BPMNOS_NUMBER_TYPE number
Definition Number.h:42
Represents a pending decision.
Represents an abstract base class for a class that is an event listener and notifier.
Definition Mediator.h:13
virtual constexpr Type getObservableType() const =0