void RollModel::Roll(int min, int max, int times) { struct occurrence_t{ int value; uint count; bool operator < (const occurrence_t &o) const{ return count > o.count || (count == o.count && value < o.value); } }; beginResetModel(); m_data.resize(times); m_total = 0; m_min = GINT32_MAX; m_max = GINT32_MIN; m_mode.clear(); m_modeCount = 0; m_mean = 0.0; m_median = 0.0; QHash<int, uint> occurrences; for(int i = 0; i < times; i++){ int X = m_rng.U_Discrete(min, max); m_data[i] = X; m_total += X; if(X < m_min) m_min = X; if(X > m_max) m_max = X; if(occurrences.contains(X)) occurrences[X]++; else occurrences.insert(X, 1); } m_mean = (double)m_total/times; // Compute the median vector<int> sorted_data = m_data; std::sort(sorted_data.begin(), sorted_data.end()); int median_index = sorted_data.size() / 2; int val1 = sorted_data[median_index]; int val2 = (sorted_data.size() & 1) ? val1 : sorted_data[median_index - 1]; m_median = ((double)val1 + val2) / 2; // Compute the mode (using heap sort) Heap<occurrence_t> heap; for(int k : occurrences.keys()) heap.Push({k, occurrences[k]}); if(heap.Count()){ occurrence_t *t = heap.Top(); uint mode_count = t->count; int cnt = 0; vector<int> tmp_mode; while(t && (mode_count == t->count)){ tmp_mode.push_back(t->value); heap.Pop(); t = heap.Top(); cnt++; } // If every item is the mode, then there is no mode if(cnt < occurrences.keys().count()){ m_modeCount = mode_count; m_mode = tmp_mode; } } endResetModel(); }