| 75 | } |
| 76 | |
| 77 | void DCGCalculator::CalMaxDCG(const std::vector<data_size_t>& ks, |
| 78 | const label_t* label, |
| 79 | data_size_t num_data, |
| 80 | std::vector<double>* out) { |
| 81 | std::vector<data_size_t> label_cnt(label_gain_.size(), 0); |
| 82 | // counts for all labels |
| 83 | for (data_size_t i = 0; i < num_data; ++i) { |
| 84 | ++label_cnt[static_cast<int>(label[i])]; |
| 85 | } |
| 86 | double cur_result = 0.0f; |
| 87 | data_size_t cur_left = 0; |
| 88 | int top_label = static_cast<int>(label_gain_.size()) - 1; |
| 89 | // calculate k Max DCG by one pass |
| 90 | for (size_t i = 0; i < ks.size(); ++i) { |
| 91 | data_size_t cur_k = ks[i]; |
| 92 | if (cur_k > num_data) { cur_k = num_data; } |
| 93 | for (data_size_t j = cur_left; j < cur_k; ++j) { |
| 94 | while (top_label > 0 && label_cnt[top_label] <= 0) { |
| 95 | top_label -= 1; |
| 96 | } |
| 97 | if (top_label < 0) { |
| 98 | break; |
| 99 | } |
| 100 | cur_result += discount_[j] * label_gain_[top_label]; |
| 101 | label_cnt[top_label] -= 1; |
| 102 | } |
| 103 | (*out)[i] = cur_result; |
| 104 | cur_left = cur_k; |
| 105 | } |
| 106 | } |
| 107 | |
| 108 | |
| 109 | double DCGCalculator::CalDCGAtK(data_size_t k, const label_t* label, |