Page MenuHomePhorge

No OneTemporary

Size
34 KB
Referenced Files
None
Subscribers
None
diff --git a/include/rosa/agent/CrossReliability.h b/include/rosa/agent/CrossReliability.h
index b712775..8ba5270 100644
--- a/include/rosa/agent/CrossReliability.h
+++ b/include/rosa/agent/CrossReliability.h
@@ -1,390 +1,378 @@
//===-- rosa/delux/CrossReliability.h ---------------------------*- C++ -*-===//
//
// The RoSA Framework
//
//===----------------------------------------------------------------------===//
///
/// \file rosa/delux/CrossReliability.h
///
/// \author Daniel Schnoell
///
/// \date 2019
///
/// \brief
///
/// \todo there is 1 exception that needs to be handled correctly.
/// \note the default search function is extremely slow maby this could be done
/// via template for storage class and the functions/methods to efficiently find
/// the correct LinearFunction
//===----------------------------------------------------------------------===//
#ifndef ROSA_AGENT_CROSSRELIABILITY_H
#define ROSA_AGENT_CROSSRELIABILITY_H
#include "rosa/agent/Abstraction.hpp"
#include "rosa/agent/Functionality.h"
#include "rosa/core/forward_declarations.h" // needed for id_t
#include "rosa/support/log.h" // needed for error "handling"
// nedded headers
#include <string>
#include <type_traits> //assert
#include <vector>
// for static methods
#include <algorithm>
#include <numeric>
namespace rosa {
namespace agent {
/// Calculates the Cross Reliability
/// \brief it uses the state represented by a numerical value and calculates the
/// Reliability of a given agent( represented by there id ) in connection to all
/// other given agents
///
/// \note all combination of agents and there coresponding Cross Reliability
/// function have to be specified
template <typename StateType, typename Type>
class CrossReliability : public Abstraction<StateType, Type> {
static_assert(
std::is_arithmetic<Type>::value,
"CrossReliability: <Type> has to be arithmetic type\n"); // sanitny check
static_assert(
std::is_arithmetic<StateType>::value,
"CrossReliability: <StateType> has to be arithmetic type\n"); // sanitny
// check
using Abstraction = typename rosa::agent::Abstraction<StateType, Type>;
struct Functionblock {
bool exists = false;
id_t A;
id_t B;
Abstraction *Funct;
};
/// From Maxi in his code defined as 1 can be changed by set
Type crossReliabilityParameter = 1;
/// Stored Cross Reliability Functions
std::vector<Functionblock> Functions;
/// Method which is used to combine the generated values
Type (*Method)(std::vector<Type> values) = AVERAGE;
//--------------------------------------------------------------------------------
// helper function
/// evalues the absolute distance between two values
/// \note this is actually the absolute distance but to ceep it somewhat
/// conform with maxis code
template <typename Type_t> Type_t AbsuluteValue(Type_t A, Type_t B) {
- // static_assert(std::is_arithmetic<Type_t>::value);
return ((A - B) < 0) ? B - A : A - B;
}
/// verry inefficient searchFunction
Functionblock (*searchFunction)(std::vector<Functionblock> vect,
const id_t nameA, const id_t nameB) =
[](std::vector<Functionblock> vect, const id_t nameA,
const id_t nameB) -> Functionblock {
for (Functionblock tmp : vect) {
if (tmp.A == nameA && tmp.B == nameB)
return tmp;
if (tmp.A == nameB && tmp.B == nameA)
return tmp;
}
return Functionblock();
};
/// evaluest the corisponding LinearFunction thith the score difference
/// \param nameA these two parameters are the unique identifiers
/// \param nameB these two parameters are the unique identifiers
/// for the LinerFunction
///
/// \note If the block nameA nameB doesn't exist it logs the error and returns
/// 0
/// \note it doesn't matter if they are swapped
Type getCrossReliabilityFromProfile(id_t nameA, id_t nameB,
StateType scoreDifference) {
Functionblock block = searchFunction(Functions, nameA, nameB);
if (!block.exists) {
LOG_ERROR(("CrossReliability: Block:" + std::to_string(nameA) + "," +
std::to_string(nameB) + "doesn't exist returning 0"));
return 0;
}
return block.Funct->operator()(scoreDifference);
}
public:
/// adds a Cross Reliability Profile used to get the Reliability of the state
/// difference
/// \param idA The id of the one \c Agent ( idealy the id of \c Unit to make
/// it absolutly unique )
///
/// \param idB The id of the other \c Agent
///
/// \param Function A unique pointer to an \c Abstraction it would use the difference
/// in score for its input
void addCrossReliabilityProfile(id_t idA, id_t idB,
std::unique_ptr<Abstraction> &Function) {
Abstraction *ptr = Function.release();
Functions.push_back({true, idA, idB, ptr});
}
/// sets the cross reliability parameter
void setCrossReliabilityParameter(Type val) {
crossReliabilityParameter = val;
}
/// sets the used method to combine the values
/// \param Meth The Function which defines the combination method.
/// \note Inside \c CrossReliability there are static methods defined which
/// can be used.
void setCrossReliabilityMethod(Type (*Meth)(std::vector<Type> values)) {
Method = Meth;
}
CrossReliability() : Abstraction(0) {}
~CrossReliability() {
for (auto tmp : Functions)
delete tmp.Funct;
Functions.clear();
}
/// Calculets the CrossReliability
/// \note both Main and Slaveagents are represented by there data and an
/// unique identifier
///
/// \param MainAgent defines the value pair around which the Cross Reliability
/// is calculated
/// \param SlaveAgents defines all value pairs of the connected Agents it
/// doesn't matter if Main agent exists inside this vector
Type operator()(std::pair<id_t, StateType> &&MainAgent,
std::vector<std::pair<id_t, StateType>> &SlaveAgents);
/// predefined combination method
static Type CONJUNCTION(std::vector<Type> values) {
- // static_assert(std::is_arithmetic<Type>::value); // sanitny check
return *std::min_element(values.begin(), values.end());
}
/// predefined combination method
static Type AVERAGE(std::vector<Type> values) {
- // static_assert(std::is_arithmetic<Type>::value); // sanitny check
return std::accumulate(values.begin(), values.end(), 0.0) / values.size();
}
/// predefined combination method
static Type DISJUNCTION(std::vector<Type> values) {
- // static_assert(std::is_arithmetic<Type>::value); // sanitny check
return *std::max_element(values.begin(), values.end());
}
};
template <typename StateType, typename Type>
inline Type CrossReliability<StateType, Type>::
operator()(std::pair<id_t, StateType> &&MainAgent,
std::vector<std::pair<id_t, StateType>> &SlaveAgents) {
- // static_assert(std::is_arithmetic<Type>::value); // sanitny check
- // static_assert(std::is_arithmetic<StateType>::value); // sanitny check
Type crossReliabiability;
std::vector<Type> values;
for (std::pair<id_t, StateType> SlaveAgent : SlaveAgents) {
if (SlaveAgent.first == MainAgent.first)
continue;
if (MainAgent.second == SlaveAgent.second)
crossReliabiability = 1;
else
crossReliabiability =
1 / (crossReliabilityParameter *
AbsuluteValue(MainAgent.second, SlaveAgent.second));
// profile reliability
Type crossReliabilityFromProfile = getCrossReliabilityFromProfile(
MainAgent.first, SlaveAgent.first,
AbsuluteValue(MainAgent.second, SlaveAgent.second));
values.push_back(
std::max(crossReliabiability, crossReliabilityFromProfile));
}
return Method(values);
}
/// Calculates the \c CrossConfidence
/// \brief It uses the a theoretical state represented by a numerical value and
/// calculates the Reliability of a given agent[ represented by there id ] in
/// connection to all other given agents this can be used to get a Confidence of
/// the current state
///
/// \note all combination of agents and there coresponding \c CrossReliability
/// function have to be specified
template <typename StateType, typename Type>
class CrossConfidence : public Abstraction<StateType, Type> {
static_assert(std::is_arithmetic<Type>::value,
"CrossConfidence: <Type> has to be an arithmetic type\n");
static_assert(std::is_arithmetic<StateType>::value,
"CrossConfidence: <StateType> has to be an arithmetic type\n");
using Abstraction = typename rosa::agent::Abstraction<StateType, Type>;
struct Functionblock {
bool exists = false;
id_t A;
id_t B;
Abstraction *Funct;
};
/// From Maxi in his code defined as 1 can be changed by set
Type crossReliabilityParameter = 1;
/// Stored Cross Reliability Functions
std::vector<Functionblock> Functions;
/// Method which is used to combine the generated values
Type (*Method)(std::vector<Type> values) = AVERAGE;
//--------------------------------------------------------------------------------
// helper function
/// evalues the absolute distance between two values
/// \note this is actually the absolute distance but to ceep it somewhat
/// conform with maxis code
template <typename Type_t> Type_t AbsuluteValue(Type_t A, Type_t B) {
- // static_assert(std::is_arithmetic<Type_t>::value);
return ((A - B) < 0) ? B - A : A - B;
}
/// verry inefficient searchFunction
Functionblock (*searchFunction)(std::vector<Functionblock> vect,
const id_t nameA, const id_t nameB) =
[](std::vector<Functionblock> vect, const id_t nameA,
const id_t nameB) -> Functionblock {
for (Functionblock tmp : vect) {
if (tmp.A == nameA && tmp.B == nameB)
return tmp;
if (tmp.A == nameB && tmp.B == nameA)
return tmp;
}
return Functionblock();
};
/// evaluest the corisponding LinearFunction thith the score difference
/// \param nameA these two parameters are the unique identifiers
/// \param nameB these two parameters are the unique identifiers
/// for the LinerFunction
///
/// \note it doesn't matter if they are swapped
Type getCrossReliabilityFromProfile(id_t nameA, id_t nameB,
StateType scoreDifference) {
Functionblock block = searchFunction(Functions, nameA, nameB);
if (!block.exists) {
LOG_ERROR(("CrossReliability: Block:" + std::to_string(nameA) + "," +
std::to_string(nameB) + "doesn't exist returning 0"));
return 0;
}
return block.Funct->operator()(scoreDifference);
}
public:
/// adds a Cross Reliability Profile used to get the Reliability of the state
/// difference
/// \param idA The id of the one \c Agent ( idealy the id of \c Unit to make
/// it absolutly unique )
///
/// \param idB The id of the other \c Agent
///
/// \param Function A unique pointer to an \c Abstraction it would use the difference
/// in score for its input
void addCrossReliabilityProfile(id_t idA, id_t idB,
std::unique_ptr<Abstraction> &Function) {
Abstraction *ptr = Function.release();
Functions.push_back({true, idA, idB, ptr});
}
/// sets the cross reliability parameter
void setCrossReliabilityParameter(Type val) {
crossReliabilityParameter = val;
}
/// sets the used method to combine the values
/// \param Meth The Function which defines the combination method.
/// \note Inside \c CrossReliability there are static methods defined which
/// can be used.
void setCrossReliabilityMethod(Type (*Meth)(std::vector<Type> values)) {
Method = Meth;
}
CrossConfidence() : Abstraction(0) {}
~CrossConfidence() {
for (auto tmp : Functions)
delete tmp.Funct;
Functions.clear();
}
Type operator()(id_t MainAgent, StateType TheoreticalValue,
std::vector<std::pair<id_t, StateType>> &SlaveAgents);
/// predefined combination method
static Type CONJUNCTION(std::vector<Type> values) {
- // static_assert(std::is_arithmetic<Type>::value); // sanitny check
return *std::min_element(values.begin(), values.end());
}
/// predefined combination method
static Type AVERAGE(std::vector<Type> values) {
- // static_assert(std::is_arithmetic<Type>::value); // sanitny check
return std::accumulate(values.begin(), values.end(), 0.0) / values.size();
}
/// predefined combination method
static Type DISJUNCTION(std::vector<Type> values) {
- // static_assert(std::is_arithmetic<Type>::value); // sanitny check
return *std::max_element(values.begin(), values.end());
}
};
/// Calculats the CrossConfidence of the main agent compared to all other Agents
/// \param MainAgent The id of the Main agent
/// \param TheoreticalValue The throretical value it should use for calculation
/// \param SlaveAgents The numerical Representation of all other Slave Agents
template <typename StateType, typename Type>
inline Type CrossConfidence<StateType, Type>::
operator()(id_t MainAgent, StateType TheoreticalValue,
std::vector<std::pair<id_t, StateType>> &SlaveAgents) {
- // static_assert(std::is_arithmetic<Type>::value); // sanitny check
- // static_assert(std::is_arithmetic<StateType>::value); // sanitny check
Type crossReliabiability;
std::vector<Type> values;
for (std::pair<id_t, StateType> SlaveAgent : SlaveAgents) {
if (SlaveAgent.first == MainAgent)
continue;
if (TheoreticalValue == SlaveAgent.second)
crossReliabiability = 1;
else
crossReliabiability =
1 / (crossReliabilityParameter *
AbsuluteValue(TheoreticalValue, SlaveAgent.second));
// profile reliability
Type crossReliabilityFromProfile = getCrossReliabilityFromProfile(
MainAgent, SlaveAgent.first,
AbsuluteValue(TheoreticalValue, SlaveAgent.second));
values.push_back(
std::max(crossReliabiability, crossReliabilityFromProfile));
}
return Method(values);
}
} // End namespace agent
} // End namespace rosa
#endif // ROSA_AGENT_CROSSRELIABILITY_H
\ No newline at end of file
diff --git a/include/rosa/agent/Reliability.h b/include/rosa/agent/Reliability.h
index 7041f9f..5cd434d 100644
--- a/include/rosa/agent/Reliability.h
+++ b/include/rosa/agent/Reliability.h
@@ -1,514 +1,507 @@
//===-- rosa/agent/Reliability.h --------------------------------*- C++ -*-===//
//
// The RoSA Framework
//
//===----------------------------------------------------------------------===//
///
/// \file rosa/agent/Reliability.h
///
/// \author Daniel Schnoell (danielschnoell@tuwien.ac.at)
///
/// \date 2019
///
/// \brief Definition of *reliability* *functionality*.
///
/// \note By defining and seeting 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
///
//===----------------------------------------------------------------------===//
#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 adds the Reliabilities of the same Scores
/// \param me The vector to wich is written to
/// \param other The other data vector
friend std::vector<ConfOrRel> operator+=(std::vector<ConfOrRel> &me,
std::vector<ConfOrRel> other) {
static_assert(std::is_arithmetic<ReliabilityType>::value);
for (auto& tmp_me : me)
for (auto& tmp_other : other) {
if (tmp_me.score == tmp_other.score) {
tmp_me.Reliability = tmp_me.Reliability + tmp_other.Reliability;
}
}
return me;
}
/// This is to push the data inside a vector in a humanreadable 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 Reliabilites
/// \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 is the Reliability Functionality for a low level Agent
/// \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)
///
/// use the \c operator() to get the reliability and \c feedback() the
/// information from the master back to this
template <typename SensorValueType, typename StateType,
typename ReliabilityType>
class LowLevel {
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 Conf/ Reliability
/// \param SensorValue The current Values of the Sensor
///
/// \return Reliability of the current Value
ConfOrRel operator()(SensorValueType SensorValue) {
- // static_assert(std::is_arithmetic<SensorValueType>::value);
- // static_assert(std::is_arithmetic<StateType>::value);
- // static_assert(std::is_arithmetic<ReliabilityType>::value);
#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 =
getRelibility(SensorValue, previousSensorValue, valueSetCounter);
#if Reliability_trace_level <= trace_vectors
LOG_TRACE_STREAM << "\ninput Rel: " << inputReliability << trace_end;
#endif
possibleScores << Confidence->operator()(SensorValue);
possibleScores = min(possibleScores, inputReliability);
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 {
- //static_assert(std::is_arithmetic<ReliabilityType>::value);
return A.Reliability > B.Reliability;
});
previousSensorValue = SensorValue;
PreviousSensorValueExists = true;
#if Reliability_trace_level <= trace_outputs
LOG_TRACE_STREAM << "\noutput lowlevel: " << possibleScores.at(0)
<< trace_end;
#endif
return possibleScores.at(0);
}
/// Needed feedback from the Master
/// \param ValuesFromMaster The Scores + Reliability from the Master for this
/// Agent
void feedback(std::vector<ConfOrRel> ValuesFromMaster) {
this->ValuesFromMaster = ValuesFromMaster;
}
/// This is the setter for Confidence Function
/// \param Confidence A pointer to the Functional for the Confidence
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
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
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
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 vertor containing all states
void setStates(std::vector<StateType> states) { this->States = states; }
/// This sets the Maximum length of the Histpory
/// \param length The length
void setHistoryLength(std::size_t length) { this->HistoryMaxSize = length; }
/// This sets the Value set Counter
/// \param ValueSetCounter the new Value
void setValueSetCounter(unsigned int ValueSetCounter) {
this->valueSetCounter = ValueSetCounter;
}
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;
/*--------------------------------- needed Funktions
* -----------------------------------------------------*/
/// 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
ReliabilityType getRelibility(SensorValueType actualValue,
SensorValueType lastValue,
unsigned int valueSetCounter) {
- // static_assert(std::is_arithmetic<ReliabilityType>::value);
ReliabilityType relAbs = Reliability->operator()(actualValue);
if (PreviousSensorValueExists) {
ReliabilityType relSlo = ReliabilitySlope->operator()(
(lastValue - actualValue) / (SensorValueType)valueSetCounter);
// calculate signal input reliability
// NOTE: options would be multiply, average, AND (best to worst:
// average = AND > multiply) rel = relAbs * relSlo; rel = (relAbs +
// relSlo)/2;
return std::min(relAbs, relSlo);
} else
return relAbs;
}
/// adabts the possible Scores by checking the History and combines those
/// values currently with max
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;
// combine each history score with the confidence of time
// NOTE: multiplication, AND, or average would be alternatives (best to
// worst: multiplication = AND = average)
historyConf = historyConf * TimeConfidence->operator()(posInHistory);
// historyConf = (historyConf + TimeConfidence(posInHistory)) / 2;
// historyConf = std::min(historyConf, TimeConfidence(posInHistory));
bool foundScore = false;
for (ConfOrRel &pS : possibleScores) {
if (pS.score == historyScore) {
// calculate confidence for score
// NOTE: multiplication, AND, or average would be alternatives (best
// to worst: AND >> average = multiplication ) pS->confOrRel =
// pS->confOrRel * historyConf; pS->confOrRel = (pS->confOrRel +
// historyConf) / 2;
pS.Reliability = std::max(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
/// \param actualPossibleScores The Scores which should be saved
///
/// \note Does the History realy make sence if the values are to smal it only
/// stores something if its empty and not if it isn't completly 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, savo oldest element
while (History.size() > HistoryMaxSize) {
// delete possibleScoreHistory.back();
History.pop_back();
}
}
}
};
/// This is the Reliability Functionality for the Highlevel Agent
/// \tparam StateType Datatype of the State (
/// Typically double or float) \tparam ReliabilityType Datatype of the
/// Reliability ( Typically long or int)
///
/// use the () operator to calculate the Reliability and all cross confidences
/// for all slaves.
template <typename StateType, typename ReliabilityType> class HighLevel {
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;
/// The return type for the \c HighLevel::operator() Method
struct returnType {
ReliabilityType CrossReliability;
std::map<id_t, std::vector<ConfOrRel>> CrossConfidence;
};
/// Calculates the Reliability and the Cross Confidenceses for each slave 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
returnType operator()(
std::vector<std::tuple<id_t, StateType, ReliabilityType>> &Values) {
- // static_assert(std::is_arithmetic<StateType>::value);
- // static_assert(std::is_arithmetic<ReliabilityType>::value);
StateType EWS = 0;
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);
EWS = EWS + sc;
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 >> )
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({std::get<0>(Value), output_temporary});
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;
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
void setFunction(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 CrossConfidence
void setFunction(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 spezific states. this will be copied So that if Slaves
/// have different States they can be used correctly.
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-diff
Expires
Sun, Mar 16, 5:12 AM (1 d, 11 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
129101
Default Alt Text
(34 KB)

Event Timeline