22#include <boost/format.hpp>
31 const std::vector<uint64_t> &fod_subsets,
32 const std::vector<std::string> &fod_subset_names) {
33 if (dst_common_data_.find(app_name) != dst_common_data_.end()) {
34 AWARN << boost::format(
"Dst %s was added!") % app_name;
38 BuildSubsetsIndMap(&dst_data);
41 "Dst %s: The input fod subsets"
42 " have repetitive elements.") %
47 ComputeCardinalities(&dst_data);
48 if (!ComputeRelations(&dst_data)) {
51 dst_data.
init_ =
true;
52 BuildNamesMap(fod_subset_names, &dst_data);
54 std::lock_guard<std::mutex> lock(map_mutex_);
55 dst_common_data_[app_name] = dst_data;
60 auto iter = dst_common_data_.find(app_name);
61 if (iter == dst_common_data_.end()) {
64 return iter->second.init_;
69 AERROR <<
"app_name is not available";
72 auto iter = dst_common_data_.find(app_name);
73 if (iter != dst_common_data_.end()) {
80 const uint64_t &fod_subset) {
81 auto iter0 = dst_common_data_.find(app_name);
82 ACHECK(iter0 != dst_common_data_.end());
83 auto iter = iter0->second.subsets_ind_map_.find(fod_subset);
84 ACHECK(iter != iter0->second.subsets_ind_map_.end());
90 auto iter = dst_common_data_.find(app_name);
91 ACHECK(iter != dst_common_data_.end());
92 return iter->second.fod_subsets_[ind];
97 for (
size_t i = 0; i < dst_data->
fod_subsets_.size(); ++i) {
102void DstManager::FodCheck(DstCommonData *dst_data) {
104 for (
auto fod_subset : dst_data->fod_subsets_) {
107 dst_data->fod_loc_ = dst_data->fod_subsets_.size();
108 auto find_res = dst_data->subsets_ind_map_.insert(
109 std::make_pair(fod, dst_data->fod_subsets_.size()));
110 if (find_res.second) {
111 dst_data->fod_subsets_.push_back(fod);
113 dst_data->fod_loc_ = find_res.first->second;
117void DstManager::ComputeCardinalities(DstCommonData *dst_data) {
118 auto count_set_bits = [](uint64_t fod_subset) {
121 fod_subset &= (fod_subset - 1);
126 dst_data->fod_subset_cardinalities_.reserve(dst_data->fod_subsets_.size());
127 for (
auto fod_subset : dst_data->fod_subsets_) {
128 dst_data->fod_subset_cardinalities_.push_back(count_set_bits(fod_subset));
132bool DstManager::ComputeRelations(DstCommonData *dst_data) {
133 auto reserve_space = [](std::vector<std::vector<size_t>> &relations,
136 relations.resize(size);
137 for (
auto &relation : relations) {
138 relation.reserve(size);
141 reserve_space(dst_data->subset_relations_, dst_data->fod_subsets_.size());
142 reserve_space(dst_data->inter_relations_, dst_data->fod_subsets_.size());
144 dst_data->combination_relations_.clear();
145 dst_data->combination_relations_.resize(dst_data->fod_subsets_.size());
146 for (
auto &combination_relation : dst_data->combination_relations_) {
147 combination_relation.reserve(2 * dst_data->fod_subsets_.size());
149 for (
size_t i = 0; i < dst_data->fod_subsets_.size(); ++i) {
150 uint64_t fod_subset = dst_data->fod_subsets_[i];
151 auto &subset_inds = dst_data->subset_relations_[i];
152 auto &inter_inds = dst_data->inter_relations_[i];
154 for (
size_t j = 0; j < dst_data->fod_subsets_.size(); ++j) {
155 if ((fod_subset | dst_data->fod_subsets_[j]) == fod_subset) {
156 subset_inds.push_back(j);
158 uint64_t inter_res = fod_subset & dst_data->fod_subsets_[j];
160 inter_inds.push_back(j);
161 auto find_res = dst_data->subsets_ind_map_.find(inter_res);
162 if (find_res == dst_data->subsets_ind_map_.end()) {
164 "Dst: The input set "
165 "of fod subsets has no closure under the operation "
169 dst_data->combination_relations_[find_res->second].push_back(
170 std::make_pair(i, j));
177void DstManager::BuildNamesMap(
const std::vector<std::string> &fod_subset_names,
178 DstCommonData *dst_data) {
180 dst_data->fod_subset_names_.clear();
181 dst_data->fod_subset_names_.resize(dst_data->fod_subsets_.size());
182 for (
size_t i = 0; i < dst_data->fod_subsets_.size(); ++i) {
183 dst_data->fod_subset_names_[i] =
184 std::bitset<64>(dst_data->fod_subsets_[i]).to_string();
187 dst_data->fod_subset_names_[dst_data->fod_loc_] =
"unknown";
189 i < std::min(fod_subset_names.size(), dst_data->fod_subsets_.size());
191 dst_data->fod_subset_names_[i] = fod_subset_names[i];
195Dst::Dst(
const std::string &app_name) : app_name_(app_name) {
199 bba_vec_.resize(dst_data_ptr_->
fod_subsets_.size(), 0.0);
200 bba_vec_[dst_data_ptr_->
fod_loc_] = 1.0;
204void Dst::SelfCheck()
const {
206 if (dst_data_ptr_ ==
nullptr) {
208 CHECK_NOTNULL(dst_data_ptr_);
209 bba_vec_.resize(dst_data_ptr_->
fod_subsets_.size(), 0.0);
210 bba_vec_[dst_data_ptr_->
fod_loc_] = 1.0;
217 return bba_vec_[idx];
222 return bba_vec_[ind];
227 if (bba_vec.size() != dst_data_ptr_->
fod_subsets_.size()) {
228 AERROR << boost::format(
"input bba_vec size: %d != Dst subsets size: %d") %
233 for (
auto belief_mass : bba_vec) {
234 if (belief_mass < 0.0) {
235 AWARN << boost::format(
" belief mass: %lf is not valid") % belief_mass;
248 std::vector<double> bba_vec(dst_data_ptr_->
fod_subsets_.size(), 0.0);
250 for (
auto bba_map_iter : bba_map) {
251 uint64_t fod_subset = bba_map_iter.first;
252 double belief_mass = bba_map_iter.second;
253 auto find_res = subsets_ind_map.find(fod_subset);
254 if (find_res == subsets_ind_map.end()) {
255 AERROR <<
"the input bba map has invalid fod subset";
258 if (belief_mass < 0.0) {
259 AWARN << boost::format(
"belief mass: %lf is not valid. Dst name: %s") %
260 belief_mass % app_name_;
263 bba_vec[find_res->second] = belief_mass;
274 static constexpr size_t total_res_size = 10000;
275 static constexpr size_t row_res_size = 1000;
276 static auto print_row = [](
const std::string &row_header,
277 const std::vector<double> &data) {
278 std::string row_str = (boost::format(
"%19s ") % row_header).str();
279 row_str.reserve(row_res_size);
280 for (
auto flt : data) {
281 row_str += (boost::format(
"%20.6lf") % (flt * 100)).str();
287 res.reserve(total_res_size);
290 std::string header = (boost::format(
"%20s") %
" ").str();
291 header.reserve(row_res_size);
292 const std::vector<std::string> &fod_subset_names =
294 for (
const auto &fod_subset_name : fod_subset_names) {
295 header += (boost::format(
"%20s") % fod_subset_name).str();
297 res += header +
"\n";
298 res += print_row(
"belief_mass", bba_vec_);
307 auto resize_space = [](std::vector<double> &vec,
size_t size) {
309 vec.resize(size, 0.0);
311 size_t size = bba_vec_.size();
312 resize_space(support_vec_, size);
313 resize_space(plausibility_vec_, size);
314 resize_space(uncertainty_vec_, size);
315 const std::vector<std::vector<size_t>> &subset_relations =
317 const std::vector<std::vector<size_t>> &inter_relations =
319 for (
size_t i = 0; i < size; ++i) {
320 double &spt = support_vec_[i];
321 double &pls = plausibility_vec_[i];
322 double &uct = uncertainty_vec_[i];
323 const auto &subset_inds = subset_relations[i];
324 const auto &inter_inds = inter_relations[i];
326 for (
auto subset_ind : subset_inds) {
327 spt += bba_vec_[subset_ind];
329 for (
auto inter_ind : inter_inds) {
330 pls += bba_vec_[inter_ind];
340 probability_vec_.clear();
341 probability_vec_.resize(bba_vec_.size(), 0.0);
343 const std::vector<size_t> &fod_subset_cardinalities =
345 for (
size_t i = 0; i < combination_relations.size(); ++i) {
346 const auto &combination_pairs = combination_relations[i];
347 double intersection_card =
static_cast<double>(fod_subset_cardinalities[i]);
348 for (
auto combination_pair : combination_pairs) {
349 size_t a_ind = combination_pair.first;
350 size_t b_ind = combination_pair.second;
351 probability_vec_[a_ind] +=
353 static_cast<double>(fod_subset_cardinalities[b_ind]) *
359void Dst::Normalize() {
361 double mass_sum = std::accumulate(bba_vec_.begin(), bba_vec_.end(), 0.0);
362 if (mass_sum == 0.0) {
363 ADEBUG <<
"mass_sum equal 0!!";
365 for (
auto &belief_mass : bba_vec_) {
366 belief_mass /= mass_sum;
371 CHECK_EQ(lhs.app_name_, rhs.app_name_)
372 << boost::format(
"lhs Dst(%s) is not equal to rhs Dst(%s)") %
373 lhs.app_name_ % rhs.app_name_;
376 Dst res(lhs.app_name_);
377 std::vector<double> &resbba_vec_ = res.bba_vec_;
379 for (
size_t i = 0; i < resbba_vec_.size(); ++i) {
380 const auto &combination_pairs = combination_relations[i];
382 double &belief_mass = resbba_vec_[i];
384 for (
auto combination_pair : combination_pairs) {
387 belief_mass += lhs.
GetIndBfmass(combination_pair.first) *
398 Dst res(dst.app_name_);
400 if (w < 0.0 || w > 1.0) {
402 "the weight of bba %lf is not valid, return default bba") %
406 size_t fod_loc = dst.dst_data_ptr_->
fod_loc_;
407 std::vector<double> &resbba_vec_ = res.bba_vec_;
408 const std::vector<double> &bba_vec = dst.bba_vec_;
409 for (
size_t i = 0; i < resbba_vec_.size(); ++i) {
411 resbba_vec_[i] = 1.0 - w + w * bba_vec[i];
413 resbba_vec_[i] = w * bba_vec[i];
uint64_t IndToFodSubset(const std::string &app_name, const size_t &ind)
DstCommonDataPtr GetAppDataPtr(const std::string &app_name)
Get the app data ptr object
bool IsAppAdded(const std::string &app_name)
Whether app added
size_t FodSubsetToInd(const std::string &app_name, const uint64_t &fod_subset)
static DstManager * Instance()
bool AddApp(const std::string &app_name, const std::vector< uint64_t > &fod_subsets, const std::vector< std::string > &fod_subset_names=std::vector< std::string >())
double GetIndBfmass(size_t ind) const
Get the Ind Bfmass object
double GetSubsetBfmass(uint64_t fod_subset) const
Get the Subset Bfmass object
void ComputeProbability() const
void ComputeSptPlsUct() const
bool SetBbaVec(const std::vector< double > &bba_vec)
Set the Bba Vec object
std::string PrintBba() const
bool SetBba(const std::map< uint64_t, double > &bba_map)
Set the Bba object, strictly require the fod in bba_map is valid
Dst(const std::string &app_name)
Dst operator*(const Dst &dst, double w)
std::vector< size_t > fod_subset_cardinalities_
std::vector< std::vector< std::pair< size_t, size_t > > > combination_relations_
std::vector< std::vector< size_t > > subset_relations_
std::vector< std::string > fod_subset_names_
std::vector< uint64_t > fod_subsets_
std::vector< std::vector< size_t > > inter_relations_
std::map< uint64_t, size_t > subsets_ind_map_