Почему время одинаковое, хотя должно возрастать (сложность O(n^2) )
Почему время одинаковое, хотя должно возрастать (сложность O(n^2) ) и как исправить?
#include <iostream>
#include <vector>
#include <random>
#include <ctime>
#include <algorithm>
#include <chrono>
#include <cstdlib>
using namespace std::chrono;
double meanTime(double* t, int n) {
double s{0};
for (int j{1}; j < 10; j += 1) s += t[j];
double aTime = s / 10;
std::cout << "\t [" << aTime << "] \t";
return aTime;
}
//Измерение std для пунктов a, b и c
double stdTime(double* t, double mean) {
double s{0};
for (int j{1}; j < 10; j += 1) s += (t[j] - mean) * (t[j] - mean);
double sTime = sqrt(s / 10);
std::cout << "[" << sTime << "]";
return sTime;
}
// a. Функция, сортирующая целые числа (int), которые размещены в векторе.
void SelectionSort(std::vector<int> &a) {
for (int startIndex = 0; startIndex < a.size() - 1; ++startIndex)
{
int smallestIndex = a.at(startIndex);
for (int currentIndex = startIndex + 1; currentIndex < a.size(); ++currentIndex)
{
if(a.at(currentIndex) < a.at(smallestIndex)) smallestIndex = currentIndex;
}
std::swap(a.at(startIndex), a.at(smallestIndex));
}
}
int RandomNumber2() { return (std::rand() % 100); }
void FillVector(std::vector<int>& a) {
std::srand(unsigned(std::time(0)));
std::generate(a.begin(), a.end(), RandomNumber2);
}
double measureTime(std::vector<int>& a, int n) {
FillVector(a);
steady_clock::time_point t1 = steady_clock::now();
SelectionSort(a);
steady_clock::time_point t2 = steady_clock::now();
duration<double> time_span = duration_cast<duration<double>>(t2 - t1);
return time_span.count();
}
void Experiment(std::vector<int> &a, int n, double* means, double* stds) {
FillVector(a);
double* times = new double[10000];
std::cout << "\n\nFor b: " << std::endl;
for (int k{ 0 }; k <= 53; k++) std::cout << "-";
std::cout << "\nArgument" << " | " << "Average time" << " | " << "Standard deviation of time |" << std::endl;
for (int k{ 0 }; k <= 53; k++) std::cout << "-";
for (size_t i = 1000; i < 10000; i+=1000) {
std::cout << "\n[" << i << "]" << " ";
for (size_t j = 0; j < 10; ++j) {
times[j] = measureTime(a, i);
}
means[i] = meanTime(times, i);
stds[i] = stdTime(times, means[i]);
}
}
int main() {
double* means = new double[10000];
double* stds = new double[10000];
int n{1000};
std::vector<int> a(n);
Experiment(a, n, means, stds);
return 0;
}
Ответы (1 шт):
Вся проблема в том, что сортируется один и тот же массив. Поэтому и не удивительно, что время всегда одно и тоже. Не верите? Следите за руками.
Вначале в main создается вектор на 1000 элементов и отдается на сортировку
int n{1000};
std::vector<int> a(n);
Experiment(a, n, means, stds);
идем в Experiment. Там мы наполняем вектор с помощью FillVector и вызываем разные сортировки
for (size_t i = 1000; i < 10000; i+=1000) {
for (size_t j = 0; j < 10; ++j) {
times[j] = measureTime(a, i);
как видим, желаемый сортировочный размер передается, но массив то один и тот же и размер у него один и тот же. Что же нас ждет в measureTime?
А там мы снова наполняем вектор и сортируем его
FillVector(a);
steady_clock::time_point t1 = steady_clock::now();
SelectionSort(a);
steady_clock::time_point t2 = steady_clock::now();
Но вот только переданный размер никак не учувствует. То есть, сортируется всегда один и тот же массив. Что и совпадает с результатами эксперимента.
Кстати, функция Experiment никак не использует второй параметр n, который хранит размер.
Поэтому, переписываем main вот так
int main() {
double* means = new double[10000];
double* stds = new double[10000];
int n{10000};
std::vector<int> a(n);
Experiment(a, means, stds);
return 0;
}
А также поправим SelectionSort
void SelectionSort(std::vector<int> &a,int n) {
for (int startIndex = 0; startIndex < n - 1; ++startIndex)
{
int smallestIndex = a.at(startIndex);
for (int currentIndex = startIndex + 1; currentIndex < n; ++currentIndex)
{
if(a.at(currentIndex) < a.at(smallestIndex)) smallestIndex = currentIndex;
}
std::swap(a.at(startIndex), a.at(smallestIndex));
}
}
Он теперь сортирует только первые n элементов. Ну и конечно позвать нужно правильно
SelectionSort(a,n);
И теперь сразу красота
| Argument | Average time | Standard deviation of time |
|---|---|---|
| [1000] | [0.000519672] | [6.13428e-05] |
| [2000] | [0.00196968] | [0.000208873] |
| [3000] | [0.00436231] | [0.000462013] |
| [4000] | [0.00774595] | [0.000818419] |
| [5000] | [0.0120397] | [0.00127067] |
| [6000] | [0.0172718] | [0.00182428] |
| [7000] | [0.0234652] | [0.00247646] |
| [8000] | [0.0305999] | [0.00322635] |
| [9000] | [0.0386905] | [0.00408018] |
В процессе чтения кода не покидало ощущение, что код написан двумя программистами совершенно разной квалификации.