Page MenuHomePhorge

Reliability.h
No OneTemporary

Size
34 KB
Referenced Files
None
Subscribers
None

Reliability.h

//===-- rosa/agent/Reliability.h --------------------------------*- C++ -*-===//
//
// The RoSA Framework
//
//===----------------------------------------------------------------------===//
///
/// \file rosa/agent/Reliability.h
///
/// \author Daniel Schnoell (daniel.schnoell@tuwien.ac.at)
///
/// \date 2019
///
/// \brief Definition of *reliability* *functionality*.
///
/// \note based on Maximilian Goetzinger (maxgot@utu.fi) code in
/// CAM_Dirty_include SA-EWS2_Version... inside Agent.cpp
///
/// \note By defining and setting Reliability_trace_level it is possible to
/// change the level to which it should be traced. \note All classes throw
/// runtime errors if not all things are set
///
/// \note should the Reliability be capped?
///
///
//===----------------------------------------------------------------------===//
// make combination modular
#ifndef ROSA_AGENT_RELIABILITY_H
#define ROSA_AGENT_RELIABILITY_H
#include "rosa/agent/CrossReliability.h"
#include "rosa/agent/FunctionAbstractions.hpp"
#include "rosa/agent/Functionality.h"
#include "rosa/agent/RangeConfidence.hpp"
#include <algorithm>
#include <type_traits>
#include <vector>
/// 0 everything
/// 1 vectors
/// 2 outputs
#define trace_everything 0
#define trace_vectors 1
#define trace_outputs 2
#ifndef Reliability_trace_level
#define Reliability_trace_level 0
#endif
#define trace_end "\n\n\n"
namespace rosa {
namespace agent {
/// This is a struct with a few methods that make lowlevel/highlevel Reliability
/// more readable \tparam StateType The datatype of the States \tparam
/// ReliabilityType The datatype of the Reliability
template <typename StateType, typename ReliabilityType> struct ConfOrRel {
/// making both Template Arguments readable to make a few things easier
typedef StateType _StateType;
/// making both Template Arguments readable to make a few things easier
typedef ReliabilityType _ReliabilityType;
/// The actual place where the data is stored
StateType score;
/// The actual place where the data is stored
ReliabilityType Reliability;
ConfOrRel(StateType _score, ReliabilityType _Reliability)
: score(_score), Reliability(_Reliability){};
ConfOrRel(){};
/// Pushes the Data in a Human readable form
/// \param out The stream where it is written to
/// \param c The struct itself
friend std::ostream &operator<<(std::ostream &out, const ConfOrRel &c) {
out << "Score: " << c.score << "\t Reliability: " << c.Reliability << " ";
return out;
}
/// needed or it throws an clang diagnosic error
typedef std::map<StateType, ReliabilityType>
map; // needed or it throws an clang diagnosic error
/// Filles the vector with the data inside the map
/// \param me The vector to be filled
/// \param data The data wich is to be pushed into the vector
friend std::vector<ConfOrRel> &operator<<(std::vector<ConfOrRel> &me,
map &&data) {
for (auto tmp : data) {
me.push_back(ConfOrRel(tmp.first, tmp.second));
#if Reliability_trace_level <= trace_everything
LOG_TRACE_STREAM << "\n" << ConfOrRel(tmp.first, tmp.second) << trace_end;
#endif
}
return me;
}
/// This is to push the data inside a vector in a human readable way into the
/// ostream \param out The ostream \param c The vector which is read
friend std::ostream &operator<<(std::ostream &out,
const std::vector<ConfOrRel> &c) {
std::size_t index = 0;
for (ConfOrRel data : c) {
out << index << " : " << data << "\n";
index++;
}
return out;
}
};
/// This calculates the minimum of the Reliabilities & the given value
/// \param me The vector with the Reliabilities
/// \param value The comparing value
template <typename Conf>
std::vector<Conf> min(std::vector<Conf> me,
typename Conf::_ReliabilityType value) {
static_assert(std::is_arithmetic<typename Conf::_ReliabilityType>::value);
for (auto tmp : me)
tmp.Reliability = std::min(tmp.Reliability, value);
return me;
}
/// This calculates the maximum of the Reliabilities & the given value
/// \param me The vector with the Reliabilities
/// \param value The comparing value
template <typename Conf>
std::vector<Conf> max(std::vector<Conf> me,
typename Conf::_ReliabilityType value) {
static_assert(std::is_arithmetic<typename Conf::_ReliabilityType>::value);
for (auto tmp : me)
tmp.Reliability = std::max(tmp.Reliability, value);
return me;
}
/// This calculates the average of the Reliabilities & the given value
/// \param me The vector with the Reliabilities
/// \param value The comparing value
template <typename Conf>
std::vector<Conf> average(std::vector<Conf> me,
typename Conf::_ReliabilityType value) {
static_assert(std::is_arithmetic<typename Conf::_ReliabilityType>::value);
for (auto tmp : me)
tmp.Reliability = (tmp.Reliability + value) / 2;
return me;
}
/// This calculates the average of the Reliabilities & the given value
/// \param me The vector with the Reliabilities
/// \param value The comparing value
template <typename Conf>
std::vector<Conf> mult(std::vector<Conf> me,
typename Conf::_ReliabilityType value) {
static_assert(std::is_arithmetic<typename Conf::_ReliabilityType>::value);
for (auto tmp : me)
tmp.Reliability = tmp.Reliability * value / 2;
return me;
}
/// This average's the Reliabilities of the same Scores
template <typename Conf>
std::vector<Conf> average(std::vector<Conf> A, std::vector<Conf> B) {
static_assert(std::is_arithmetic<typename Conf::_ReliabilityType>::value);
for (auto &tmp_me : A)
for (auto &tmp_other : B) {
if (tmp_me.score == tmp_other.score) {
tmp_me.Reliability = (tmp_me.Reliability + tmp_other.Reliability) / 2;
}
}
return A;
}
/// This min's the Reliabilities of the same Scores
template <typename Conf>
std::vector<Conf> min(std::vector<Conf> A, std::vector<Conf> B) {
static_assert(std::is_arithmetic<typename Conf::_ReliabilityType>::value);
for (auto &tmp_me : A)
for (auto &tmp_other : B) {
if (tmp_me.score == tmp_other.score) {
tmp_me.Reliability =
std::min(tmp_me.Reliability + tmp_other.Reliability);
}
}
return A;
}
/// This max's the Reliabilities of the same Scores
template <typename Conf>
std::vector<Conf> max(std::vector<Conf> A, std::vector<Conf> B) {
static_assert(std::is_arithmetic<typename Conf::_ReliabilityType>::value);
for (auto &tmp_me : A)
for (auto &tmp_other : B) {
if (tmp_me.score == tmp_other.score) {
tmp_me.Reliability =
std::max(tmp_me.Reliability + tmp_other.Reliability);
}
}
return A;
}
/// This mult's the Reliabilities of the same Scores
template <typename Conf>
std::vector<Conf> mult(std::vector<Conf> A, std::vector<Conf> B) {
static_assert(std::is_arithmetic<typename Conf::_ReliabilityType>::value);
for (auto &tmp_me : A)
for (auto &tmp_other : B) {
if (tmp_me.score == tmp_other.score) {
tmp_me.Reliability = tmp_me.Reliability * tmp_other.Reliability;
}
}
return A;
}
/// This is the combinator for Reliability and confidences it takes the
/// Sensor value, its "History" and feedback from \c
/// CrossCombinator to calculate different Reliabilities.
/// \tparam SensorValueType Datatype of the Sensor value ( Typically
/// double or float) \tparam StateType Datatype of the State ( Typically long or
/// int)
/// \tparam ReliabilityType Datatype of the Reliability (
/// Typically double or float)
///
/// \note more information about how it calculates
/// the Reliabilities
/// \verbatim
///----------------------------------------------------------------------------------
///
///
/// ->Reliability---> getInputReliability()
/// | |
/// | V
/// Sensor Value ---| PossibleScoreCombinationMethod -> next line
/// | A |
/// | | V
/// ->Confidence--- getPossibleScores()
///
///-----------------------------------------------------------------------------------
///
/// feedback
/// |
/// V
/// ValuesFromMaster
/// | -> History ---|
/// V | V
/// here -> FeedbackCombinatorMethod --------> HistoryCombinatorMethod->nextline
/// | |
/// V V
/// getpossibleScoresWithMasterFeedback() getPossibleScoresWithHistory()
///
///----------------------------------------------------------------------------------
///
/// here -> sort -> most likely -> mostLikelySoreAndReliability()
///
/// ---------------------------------------------------------------------------------
/// \endverbatim
/// the mentioned methods are early outs so if two ore more of them are run in
/// the same step they will be interpreted as different time steps
/// <pre>
/// Default values for Combinators:
/// InputReliabilityCombinator = combinationMin;
/// PossibleScoreCombinationMethod = PossibleScoreCombinationMethodMin;
/// FeedbackCombinatorMethod = FeedbackCombinatorMethodAverage;
/// HistoryCombinatorMethod = HistoryCombinatorMethodMax;
/// </pre>
///
///
///
template <typename SensorValueType, typename StateType,
typename ReliabilityType>
class ReliabilityAndConfidenceCombinator {
public:
static_assert(std::is_arithmetic<SensorValueType>::value,
"LowLevel: SensorValueType has to an arithmetic type\n");
static_assert(std::is_arithmetic<StateType>::value,
"LowLevel: StateType has to an arithmetic type\n");
static_assert(std::is_arithmetic<ReliabilityType>::value,
"LowLevel: ReliabilityType has to an arithmetic type\n");
/// Typedef to shorten the writing.
/// \c ConfOrRel
typedef ConfOrRel<StateType, ReliabilityType> ConfOrRel;
/// Calculates the input reliability by combining Reliability of the Sensor
/// and the Slope Reliability \param SensorValue The sensor Value \note to set
/// the combination method \c setInputReliabilityCombinator()
auto getInputReliability(SensorValueType SensorValue) {
auto inputReliability =
getReliability(SensorValue, previousSensorValue, valueSetCounter);
previousSensorValue = SensorValue;
PreviousSensorValueExists = true;
return inputReliability;
}
/// Calculates the Reliability
/// \param SensorValue The current Values of the Sensor
///
/// \return Reliability and Score of the current SensorValue
///
ConfOrRel mostLikelySoreAndReliability(SensorValueType SensorValue) {
#if Reliability_trace_level <= trace_outputs
LOG_TRACE_STREAM << "\nTrace level is set to: " << Reliability_trace_level
<< "\n"
<< "Will trace: "
<< ((Reliability_trace_level == trace_outputs)
? "outputs"
: (Reliability_trace_level == trace_vectors)
? "vectors"
: (Reliability_trace_level ==
trace_everything)
? "everything"
: "undefined")
<< trace_end;
#endif
std::vector<ConfOrRel> ActuallPossibleScores;
std::vector<ConfOrRel> possibleScores;
ReliabilityType inputReliability = getInputReliability(SensorValue);
#if Reliability_trace_level <= trace_vectors
LOG_TRACE_STREAM << "\ninput Rel: " << inputReliability << trace_end;
#endif
possibleScores << Confidence->operator()(SensorValue);
possibleScores =
PossibleScoreCombinationMethod(possibleScores, inputReliability);
possibleScores = FeedbackCombinatorMethod(possibleScores, ValuesFromMaster);
saveInHistory(possibleScores);
#if Reliability_trace_level <= trace_vectors
LOG_TRACE_STREAM << "\nActuallPossibleScores:\n"
<< possibleScores << trace_end;
LOG_TRACE_STREAM << "\npossibleScores:\n" << possibleScores << trace_end;
#endif
possibleScores.clear();
possibleScores = getAllPossibleScoresBasedOnHistory();
std::sort(possibleScores.begin(), possibleScores.end(),
[](ConfOrRel A, ConfOrRel B) -> bool {
return A.Reliability > B.Reliability;
});
#if Reliability_trace_level <= trace_outputs
LOG_TRACE_STREAM << "\noutput lowlevel: " << possibleScores.at(0)
<< trace_end;
#endif
return possibleScores.at(0);
}
/// Calculates the possible Scores
/// \param SensorValue the Sensor Value
/// \brief it combines the input reliability and the confidence of the Sensor.
/// The use combination method can be set using \c
/// setPossibleScoreCombinationMethod()
auto getPossibleScores(SensorValueType SensorValue) {
std::vector<ConfOrRel> possibleScores;
ReliabilityType inputReliability = getInputReliability(SensorValue);
// get input rel()
#if Reliability_trace_level <= trace_vectors
LOG_TRACE_STREAM << "\ninput Rel: " << inputReliability << trace_end;
#endif
possibleScores << Confidence->operator()(SensorValue);
possibleScores =
PossibleScoreCombinationMethod(possibleScores, inputReliability);
return possibleScores;
}
/// return the Possible Values with the feedback in mind
/// \param SensorValue The sensor Value
/// \brief it combines the input reliability and the confidence of the Sensor.
/// The combines them with FeedbackCombinatorMethod and returns the result.
auto getpossibleScoresWithMasterFeedback(SensorValueType SensorValue) {
std::vector<ConfOrRel> possibleScores;
ReliabilityType inputReliability = getInputReliability(SensorValue);
// get input rel()
#if Reliability_trace_level <= trace_vectors
LOG_TRACE_STREAM << "\ninput Rel: " << inputReliability << trace_end;
#endif
possibleScores << Confidence->operator()(SensorValue);
possibleScores =
PossibleScoreCombinationMethod(possibleScores, inputReliability);
// set comb method with values from master ( class :: min | max | average |
// mult | [] ()-> {} )
possibleScores = FeedbackCombinatorMethod(possibleScores, ValuesFromMaster);
return possibleScores;
}
/// returns all possible Scores and Reliabilities with the History in mind
/// \param SensorValue the Sensor value
/// how this is done is described at the class.
auto getPossibleScoresWithHistory(SensorValueType SensorValue) {
std::vector<ConfOrRel> ActuallPossibleScores;
std::vector<ConfOrRel> possibleScores;
ReliabilityType inputReliability = getInputReliability(SensorValue);
// get input rel()
#if Reliability_trace_level <= trace_vectors
LOG_TRACE_STREAM << "\ninput Rel: " << inputReliability << trace_end;
#endif
possibleScores << Confidence->operator()(SensorValue);
possibleScores =
PossibleScoreCombinationMethod(possibleScores, inputReliability);
possibleScores = FeedbackCombinatorMethod(possibleScores, ValuesFromMaster);
saveInHistory(possibleScores);
#if Reliability_trace_level <= trace_vectors
LOG_TRACE_STREAM << "\nActuallPossibleScores:\n"
<< possibleScores << trace_end;
LOG_TRACE_STREAM << "\npossibleScores:\n" << possibleScores << trace_end;
#endif
possibleScores.clear();
return getAllPossibleScoresBasedOnHistory();
}
/// feedback for this functionality most commonly it comes from a Master Agent
/// \param ValuesFromMaster The Scores + Reliability for the feedback
/// \brief This input kind of resembles a confidence but not
/// directly it more or less says: compared to the other Scores inside the
/// System these are the Scores with the Reliability that you have.
void feedback(std::vector<ConfOrRel> ValuesFromMaster) {
this->ValuesFromMaster = ValuesFromMaster;
}
//
// ----------------------Reliability and Confidence Function setters----------
//
/// This is the setter for Confidence Function
/// \param Confidence A pointer to the Functional for the \c Confidence of the
/// Sensor value
void setConfidenceFunction(
std::unique_ptr<RangeConfidence<ReliabilityType, StateType,
SensorValueType>> &Confidence) {
this->Confidence = std::move(Confidence);
}
/// This is the setter for Reliability Function
/// \param Reliability A pointer to the Functional for the Reliability
/// \brief The Reliability takes the current Sensor value and return the
/// Reliability of the value.
void setReliabilityFunction(
std::unique_ptr<Abstraction<SensorValueType, ReliabilityType>>
&Reliability) {
this->Reliability = std::move(Reliability);
}
/// This is the setter for ReliabilitySlope Function
/// \param ReliabilitySlope A pointer to the Functional for the
/// ReliabilitySlope
/// \brief The ReliabilitySlope takes the difference of the current Sensor
/// Value to the last one and tells you how likely the change is.
void setReliabilitySlopeFunction(
std::unique_ptr<Abstraction<SensorValueType, ReliabilityType>>
&ReliabilitySlope) {
this->ReliabilitySlope = std::move(ReliabilitySlope);
}
/// This is the setter for TimeConfidence Function
/// \param TimeConfidence A pointer to the Functional for the TimeConfidence
/// \brief The time function takes the position in the History with greater
/// equals older and return a Reliability of how "relevant" it is.
void setTimeConfidenceFunction(
std::unique_ptr<Abstraction<std::size_t, ReliabilityType>>
&TimeConfidence) {
this->TimeConfidence = std::move(TimeConfidence);
}
/// This is the setter for all possible States
/// \param states A vector containing all states
/// \brief This exists even though \c State Type is an arithmetic Type because
/// the states do not need to be "next" to each other ( ex. states={ 1 7 24 })
void setStates(std::vector<StateType> states) { this->States = states; }
/// This sets the Maximum length of the History
/// \param length The length
void setHistoryLength(std::size_t length) { this->HistoryMaxSize = length; }
/// This sets the Value set Counter
/// \param ValueSetCounter the new Value
/// \note This might actually be only an artifact. It is only used to get the
/// reliability from the \c ReliabilitySlope [ ReliabilitySlope->operator()(
/// (lastValue - actualValue) / (SensorValueType)valueSetCounter) ]
void setValueSetCounter(unsigned int ValueSetCounter) {
this->valueSetCounter = ValueSetCounter;
}
//
// ----------------combinator setters-----------------------------------------
//
/// This sets the combination method used by the History
/// \param Meth the method which should be used. predefined \c
/// HistoryCombinatorMethodMin() \c HistoryCombinatorMethodMax() \c
/// HistoryCombinatorMethodMult() \c HistoryCombinatorMethodAverage()
void setHistoryCombinatorMethod(ReliabilityType (*Meth)(ReliabilityType,
ReliabilityType)) {
HistoryCombinatorMethod = Meth;
}
/// sets the predefined method for the combination of the possible scores and
/// the master \param Meth the method predefined ones are
/// \c FeedbackCombinatorMethodAverage() \c FeedbackCombinatorMethodMin() \c
/// FeedbackCombinatorMethodMax() \c FeedbackCombinatorMethodMult()
void setFeedbackCombinatorMethod(std::vector<ConfOrRel> (*Meth)(
std::vector<ConfOrRel>, std::vector<ConfOrRel>)) {
FeedbackCombinatorMethod = Meth;
}
/// Sets the used combination method for Possible Scores
/// \param Meth a Pointer for the used Method. Predefined methods \c
/// PossibleScoreCombinationMethodMin() \c PossibleScoreCombinationMethodMax()
/// \c PossibleScoreCombinationMethodAverage()
void setPossibleScoreCombinationMethod(
std::vector<ConfOrRel> (*Meth)(std::vector<ConfOrRel>, ReliabilityType)) {
PossibleScoreCombinationMethod = Meth;
}
/// sets the input reliability combinator method
/// \param method the to be used method
/// \note there are predefined methods \c combinationMin() \c combinationMax()
/// \c combinationAverage()
void setInputReliabilityCombinator(
ReliabilityType (*method)(ReliabilityType, ReliabilityType)) {
InputReliabilityCombinator = method;
}
//
// ----------------predefined combinators------------------------------------
//
/// predefined Method
static ReliabilityType HistoryCombinatorMethodMin(ReliabilityType A,
ReliabilityType B) {
return std::min(A, B);
}
/// predefined Method
static ReliabilityType HistoryCombinatorMethodMax(ReliabilityType A,
ReliabilityType B) {
return std::max(A, B);
}
/// predefined Method
static ReliabilityType HistoryCombinatorMethodMult(ReliabilityType A,
ReliabilityType B) {
return A * B;
}
/// predefined Method
static ReliabilityType HistoryCombinatorMethodAverage(ReliabilityType A,
ReliabilityType B) {
return (A + B) / 2;
}
/// predefined method
static std::vector<ConfOrRel>
FeedbackCombinatorMethodAverage(std::vector<ConfOrRel> A,
std::vector<ConfOrRel> B) {
return average(A, B);
}
/// predefined method
static std::vector<ConfOrRel>
FeedbackCombinatorMethodMin(std::vector<ConfOrRel> A,
std::vector<ConfOrRel> B) {
return min(A, B);
}
/// predefined method
static std::vector<ConfOrRel>
FeedbackCombinatorMethodMax(std::vector<ConfOrRel> A,
std::vector<ConfOrRel> B) {
return max(A, B);
}
/// predefined method
static std::vector<ConfOrRel>
FeedbackCombinatorMethodMult(std::vector<ConfOrRel> A,
std::vector<ConfOrRel> B) {
return mult(A, B);
}
/// Predefined combination method for possible Scores
static std::vector<ConfOrRel>
PossibleScoreCombinationMethodMin(std::vector<ConfOrRel> A,
ReliabilityType B) {
return min(A, B);
}
/// Predefined combination method for possible Scores
static std::vector<ConfOrRel>
PossibleScoreCombinationMethodMax(std::vector<ConfOrRel> A,
ReliabilityType B) {
return max(A, B);
}
/// Predefined combination method for possible Scores
static std::vector<ConfOrRel>
PossibleScoreCombinationMethodAverage(std::vector<ConfOrRel> A,
ReliabilityType B) {
return average(A, B);
}
/// Predefined combination method for possible Scores
static std::vector<ConfOrRel>
PossibleScoreCombinationMethodMult(std::vector<ConfOrRel> A,
ReliabilityType B) {
return mult(A, B);
}
/// The predefined min combinator method
static ReliabilityType combinationMin(ReliabilityType A, ReliabilityType B) {
return std::min(A, B);
}
/// The predefined max combinator method
static ReliabilityType combinationMax(ReliabilityType A, ReliabilityType B) {
return std::max(A, B);
}
/// The predefined average combinator method
static ReliabilityType combinationAverage(ReliabilityType A,
ReliabilityType B) {
return (A + B) / 2;
}
/// The predefined average combinator method
static ReliabilityType combinationMult(ReliabilityType A, ReliabilityType B) {
return A * B;
}
private:
std::vector<std::vector<ConfOrRel>> History;
std::size_t HistoryMaxSize;
std::vector<ConfOrRel> ValuesFromMaster;
SensorValueType previousSensorValue;
unsigned int valueSetCounter;
std::vector<StateType> States;
bool PreviousSensorValueExists = false;
std::unique_ptr<RangeConfidence<ReliabilityType, StateType, SensorValueType>>
Confidence;
std::unique_ptr<Abstraction<SensorValueType, ReliabilityType>> Reliability;
std::unique_ptr<Abstraction<SensorValueType, ReliabilityType>>
ReliabilitySlope;
std::unique_ptr<Abstraction<std::size_t, ReliabilityType>> TimeConfidence;
// combination functions
ReliabilityType (*InputReliabilityCombinator)(
ReliabilityType, ReliabilityType) = combinationMin;
std::vector<ConfOrRel> (*PossibleScoreCombinationMethod)(
std::vector<ConfOrRel>,
ReliabilityType) = PossibleScoreCombinationMethodMin;
std::vector<ConfOrRel> (*FeedbackCombinatorMethod)(std::vector<ConfOrRel>,
std::vector<ConfOrRel>) =
FeedbackCombinatorMethodAverage;
ReliabilityType (*HistoryCombinatorMethod)(ReliabilityType, ReliabilityType) =
HistoryCombinatorMethodMax;
/*--------------------------------- needed Functions
* -----------------------------------------------------*/
/// returns the Reliability
/// \param actualValue The Value of the Sensor
/// \param lastValue of the Sensor this is stored in the class
/// \param valueSetCounter It has an effect on the difference of the current
/// and last value This might not be needed anymore
/// \brief it returns the combination the \c Reliability function and \c
/// ReliabilitySlope if the previous value exists. if it doesn't it only
/// returns the \c Reliability function value.
ReliabilityType getReliability(SensorValueType actualValue,
SensorValueType lastValue,
unsigned int valueSetCounter) {
ReliabilityType relAbs = Reliability->operator()(actualValue);
if (PreviousSensorValueExists) {
ReliabilityType relSlo = ReliabilitySlope->operator()(
(lastValue - actualValue) / (SensorValueType)valueSetCounter);
return InputReliabilityCombinator(relAbs, relSlo);
} else
return relAbs;
}
/// adapts the possible Scores by checking the History and combines those
/// values. currently with max
/// \brief combines the historic values with the \c TimeConfidence function
/// and returns the maximum Reliability for all Scores.
std::vector<ConfOrRel> getAllPossibleScoresBasedOnHistory() {
// iterate through all history entries
std::size_t posInHistory = 0;
std::vector<ConfOrRel> possibleScores;
for (auto pShE = History.begin(); pShE < History.end();
pShE++, posInHistory++) {
// iterate through all possible scores of each history entry
for (ConfOrRel &pSh : *pShE) {
StateType historyScore = pSh.score;
ReliabilityType historyConf = pSh.Reliability;
historyConf = historyConf * TimeConfidence->operator()(posInHistory);
bool foundScore = false;
for (ConfOrRel &pS : possibleScores) {
if (pS.score == historyScore) {
pS.Reliability =
HistoryCombinatorMethod(pS.Reliability, historyConf);
foundScore = true;
}
}
if (foundScore == false) {
ConfOrRel possibleScore;
possibleScore.score = historyScore;
possibleScore.Reliability = historyConf;
possibleScores.push_back(possibleScore);
}
}
}
return possibleScores;
}
/// saves the Scores in the History
/// \brief It checks the incoming scores if any have a Reliability greater
/// than 0.5 all of them get saved inside the History and then the
/// History get shortened to the maximal length. It only saves the Value if
/// the History is empty.
///
/// \param actualPossibleScores The Scores which should be saved
///
/// \note Does the History really make sense if the values are to small it
/// only stores something if it's empty and not if it isn't completely filled
void saveInHistory(std::vector<ConfOrRel> actualPossibleScores) {
// check if the reliability of at least one possible score is high enough
bool atLeastOneRelIsHigh = false;
for (ConfOrRel pS : actualPossibleScores) {
if (pS.Reliability > 0.5) {
atLeastOneRelIsHigh = true;
}
}
// save possible scores if at least one possible score is high enough (or if
// the history is empty)
if (History.size() < 1 || atLeastOneRelIsHigh == true) {
History.insert(History.begin(), actualPossibleScores);
// if history size is higher than allowed, save oldest element
while (History.size() > HistoryMaxSize) {
// delete possibleScoreHistory.back();
History.pop_back();
}
}
}
};
/// This is the Reliability Functionality for the highlevel Agent.
/// \brief It takes the scores and reliabilities of all connected lowlevel
/// Agents and calculates the Reliability of them together. Also it creates the
/// feedback that is needed by the \c ReliabilityForLowLevelAgents, which is a
/// kind of confidence.
///
/// \tparam StateType Datatype of the State ( Typically double or float)
/// \tparam ReliabilityType Datatype of the Reliability (
/// Typically long or int)
///
/// \note A highlevel Agent is commonly in a master slave relationship with the
/// lowlevel Agents as the master. It combines the Reliability of all connected
/// Slaves and uses that as its own Reliability.
///
/// \note more information about how the Reliability and feedback is
/// created at \c operator()()
// State Type rename
// merge cross rel/conf darein
template <typename StateType, typename ReliabilityType> class CrossCombinator {
public:
static_assert(std::is_arithmetic<StateType>::value,
"HighLevel: StateType has to be an arithmetic type\n");
static_assert(std::is_arithmetic<ReliabilityType>::value,
"HighLevel: ReliabilityType has to be an arithmetic type\n");
/// typedef To shorten the writing.
/// \c ConfOrRel
typedef ConfOrRel<StateType, ReliabilityType> ConfOrRel;
/// typedef of the input type for the operator() defined explicitly to
/// simplify interaction
///
typedef std::vector<std::tuple<id_t, StateType, ReliabilityType>> InputType;
/// The return type for the \c operator()() Method
struct returnType {
ReliabilityType CrossReliability;
std::map<id_t, std::vector<ConfOrRel>> CrossConfidence;
};
/// Calculates the Reliability and the Cross Confidences for each lowlevel
/// Agent for all of there states.
///
/// \param Values It gets the States and Reliabilities of
/// all connected Slaves inside a vector.
///
/// \return it returns a struct \c returnType containing the CrossReliability
/// and all CrossConfidence's
///
/// \brief To calculate the Reliability it combines [\c std::min() ] the \c
/// CrossReliability of all connected Agents. To calculate the feedback it
/// iterates over all Agents and their states and uses the \c CrossConfidence
/// Function to play what if with the states.
returnType operator()(
std::vector<std::tuple<id_t, StateType, ReliabilityType>> &Values) {
ReliabilityType combinedInputRel = 1;
ReliabilityType combinedCrossRel = 1;
ReliabilityType outputReliability;
std::vector<std::pair<id_t, StateType>> Agents;
std::map<id_t, std::vector<ConfOrRel>> output;
std::vector<ConfOrRel> output_temporary;
for (auto tmp : Values) {
std::pair<id_t, StateType> tmp2;
tmp2.first = std::get<0>(tmp);
tmp2.second = std::get<1>(tmp);
Agents.push_back(tmp2);
}
for (auto Value : Values) {
id_t id = std::get<0>(Value);
StateType sc = std::get<1>(Value);
ReliabilityType rel = std::get<2>(Value);
// combination method ([])
// get input reliability
combinedInputRel = std::min(combinedInputRel, rel);
// calculate the cross reliability for this slave agent
ReliabilityType realCrossReliabilityOfSlaveAgent =
CrossReliability->operator()(
{id, sc},
Agents); // AVERAGE, MULTIPLICATION, CONJUNCTION (best to worst:
// AVERAGE = CONJUNCTION > MULTIPLICATION >> )
// get cross confidence
output_temporary.clear();
for (StateType thoScore : States[id]) {
// calculate the cross reliability for this slave agent
ConfOrRel data;
data.score = thoScore;
data.Reliability = CrossConfidence->operator()(id, thoScore, Agents);
output_temporary.push_back(data);
}
output.insert({id, output_temporary});
// set combination method
// get combined cross reliability
combinedCrossRel =
std::min(combinedCrossRel, realCrossReliabilityOfSlaveAgent);
}
// combine cross reliabilites and input reliabilites of all slave agents
// NOTE: options would be multiply, average, AND (best to worst: )
// outputReliability = combinedInputRel * combinedCrossRel;
// outputReliability = (combinedInputRel + combinedCrossRel) / 2;
// set combination method
// get output reliability
outputReliability = std::min(combinedInputRel, combinedCrossRel);
return {outputReliability, output};
}
/// This is the setter for CrossReliability Function
/// \param CrossReliability A pointer to the Functional for the
/// CrossReliability
/// \brief This is needed to calculate the Reliability. It uses this on all
/// values of all lowlevel Agnets.
void setCrossReliability(
std::unique_ptr<CrossReliability<StateType, ReliabilityType>>
&CrossReliability) {
this->CrossReliability = std::move(CrossReliability);
}
/// This is the setter for CrossConfidence Function
/// \param CrossConfidence A pointer to the Functional for the \c
/// CrossConfidence \brief This is needed for the feedback for the \c
/// ReliabilityForLowLevelAgents.
void setCrossConfidence(
std::unique_ptr<CrossConfidence<StateType, ReliabilityType>>
&CrossConfidence) {
this->CrossConfidence = std::move(CrossConfidence);
}
/// This is the adder for the states
/// \param id The id of the Agent of the states
/// \param States id specific states. this will be copied So that if Slaves
/// have different States they can be used correctly.
/// \brief The States of all connected lowlevel Agents has to be known to be
/// able to iterate over them
void addStates(id_t id, std::vector<StateType> States) {
this->States.insert({id, States});
}
private:
std::unique_ptr<CrossReliability<StateType, ReliabilityType>>
CrossReliability;
std::unique_ptr<CrossConfidence<StateType, ReliabilityType>> CrossConfidence;
std::map<id_t, std::vector<StateType>> States;
};
} // namespace agent
} // namespace rosa
#endif // !ROSA_AGENT_RELIABILITY_H

File Metadata

Mime Type
text/x-c++
Expires
Sun, May 31, 4:42 PM (1 d, 19 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
330688
Default Alt Text
Reliability.h (34 KB)

Event Timeline