Добавил:
Кафедра ВТ Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

4 семестр / 930(4)

.docx
Скачиваний:
25
Добавлен:
08.06.2022
Размер:
95.22 Кб
Скачать

МИНОБРНАУКИ РОССИИ

Санкт-Петербургский государственный

электротехнический университет

«ЛЭТИ» им. В.И. Ульянова (Ленина)

Кафедра вычислительной техники

Отчет по лабораторной работе №4

по дисциплине «Алгоритмы и структуры данных»

Студент гр. 930

Преподаватель

Колинько П.Г.

Тема: Измерение временной сложности алгоритма в эксперименте на ЭВМ Вариант 35

Содержание

Цель работы ................................................................................................. 3

Задание ........................................................................................................... 3

Описание эксперимента ………………....................................................... 3

Результаты эксперимента ……………………............................................. 3

Таблицы …………………………………………………………………...... 4

Вывод ............................................................................................................. 6

Текст программы ........................................................................................... 7

Цель работы

    1. Экспериментальное подтверждение (опровержение) теоретической временной сложности алгоритмов работы с множествами и последовательностями.

    2. Задание

    3. На основе программы, составленной по лабораторной работе №3, выполнить статистический эксперимент по измерению фактической временной сложности алгоритма обработки данных, провести анализ.

    4. Описание эксперимента

Для проведения эксперимента программа из лабораторной работы №3 была модифицирована следующим образом:

  • Все операции с множествами и последовательностями выполнялись в цикле, изменяющим мощности множеств от 10 до 5000 элементов с шагом 10;

  • Каждую итерацию производился замер времени выполнения операций с помощью библиотеки chrono;

  • Для повышения достоверности эксперимента каждую итерацию определялась средняя мощность множества;

Теоретическая временная сложность определяется по «худшей» операции. Самое большее - O(n log n) - в операциях с последовательностями, где осуществляются произвольные вставки в дерево (с помощью функции Функция SUBST) сложностью O(log n) каждая.

Результаты эксперимента

По результатам эксперимента был получен файл, содержащий 501 пару данных. Этот файл был обработан программой RG41 и результаты помещены в файл Microsoft Excel.

Результаты работы программы RG41 (501 точка)

Результаты статистической обработки (из файла out.txt)

Результаты расчета отношений выборочных дисперсий

Отношение дисперсий

Проанализировав таблицы, мы можем сделать вывод, что соответствующая сложность “ Квадратичная регрессия-1 ” (O(n log n)).

На графике мы видим, что практически все экспериментальные данные попадают в границы доверительного интервала ±3 СКО.

Вывод

В результате выполнения данной курсовой работы мы научились рассчитывать с помощью программы RG41 временную сложность и выяснили, что экспериментальная и теоретическая оценка временной сложности получились примерно схожи. Экспериментально подтвержденное значение временной сложности операций над множествами и последовательностями O(n log n).

Текст программы

//MySTL.cpp

//(c)lgn, 28.04/11.05.16/27.01.17/05.02.18/05.02.19

#include <time.h>

#include <chrono>

#include <fstream>

#include <string>

#include <set>

#include <vector>

#include <iterator>

#include <algorithm>

#include <iostream>

using namespace std;

using MySet = set<int>;

using MyIt = set<int>::iterator;

using MySeq = vector<MyIt>;

const int lim = 16;

class MyCont {

int power;

char tag;

MySet setA;

MySeq Sequence;

MyCont& operator = (const MyCont &) = delete;

MyCont& operator = (MyCont &&) = delete;

public:

MyCont ( int, char );

MyCont (const MyCont &);

MyCont (MyCont &&);

MyCont& operator |= (const MyCont &);

MyCont operator | (const MyCont & rgt) const

{ MyCont result(*this); return (result |= rgt); }

MyCont& operator -= (const MyCont &);

MyCont operator - (const MyCont & rgt) const

{ MyCont result(*this); return (result -= rgt); }

MyCont& operator ^= (const MyCont &);

MyCont operator ^ (const MyCont & rgt) const

{ MyCont result(*this); return (result ^= rgt); }

void Merge (const MyCont &);

void Concat(const MyCont & rgt);

void Subst (const MyCont &, size_t);

void Change (const MyCont &, size_t);

void Show ( ) const;

size_t Power( ) const { return Sequence.size( ); }

};

MyCont::MyCont( int p = 0, char t = 'R') : power(p), tag(t)

{ for(int i = 0; i < power; ++i)

{ Sequence.push_back(setA.insert(rand()%lim).first); }

}

MyCont::MyCont (MyCont && source) //Копия "с переносом"

: power(source.power), tag(source.tag),

setA(move(source.setA)), Sequence(move(source.Sequence)) { }

MyCont::MyCont (const MyCont & source) //Конструктор копии

: power(source.power), tag(source.tag) {

for (auto x : source.setA) Sequence.push_back(setA.insert(x).first);

}

void MyCont::Show( ) const {

using std::cout;

cout << "\n" << tag << ": ";

for(auto x : setA) cout << x << " "; //Выдача множества

cout << "\n < ";

for(auto x : Sequence) cout << *x << " "; //Выдача последовательности

cout << ">";

}

MyCont& MyCont::operator -= (const MyCont & rgt){ //Разность мн-в

MySet temp;

MySeq stemp;

for (auto x : setA)

if(rgt.setA.find(x) == rgt.setA.end( ))

stemp.push_back(temp.insert(x).first);

temp.swap(setA);

stemp.swap(Sequence);

return *this;

}

MyCont& MyCont::operator |= (const MyCont & rgt) { //Объединение

for (auto x : rgt.setA) Sequence.push_back(setA.insert(x).first);

return *this;

}

void MyCont::Merge(const MyCont & rgt) { //Слияние

using std::sort;

MySeq temp(rgt.Sequence), res;

auto le = [ ] (MyIt a, MyIt b)->bool { return *a < *b; };//Критерий

sort(Sequence.begin( ), Sequence.end( ), le);

sort(temp.begin( ), temp.end( ), le);

std::merge(Sequence.begin( ), Sequence.end( ), temp.begin( ), temp.end( ),

std::back_inserter(res), le); //Слияние для последовательностей...

setA.insert(rgt.setA.begin( ), rgt.setA.end( )); //... и объединение множеств

Sequence.swap(res);

}

void MyCont::Concat(const MyCont & rgt) { //Сцепление

for(auto x : rgt.Sequence) Sequence.push_back(setA.insert(*x).first);

}

void MyCont::Subst (const MyCont & rgt, size_t p)

{ //Подстановка

if(p >= Power( )) Concat(rgt);

else {

MySeq stemp(Sequence.begin( ), Sequence.begin( ) + p); //Начало

std::copy(rgt.Sequence.begin( ), rgt.Sequence.end( ), back_inserter(stemp)); //Вставка

std::copy(Sequence.begin( )+p, Sequence.end( ), back_inserter(stemp)); //Окончание

MySet temp;

Sequence.clear( );

for (auto x : stemp) Sequence.push_back(temp.insert(*x).first);

setA.swap(temp);

}

}

void MyCont::Change (const MyCont & rgt, size_t p)

{ //Замена

if(p >= Power( )) Concat(rgt);

else {

MySeq stemp(Sequence.begin( ), Sequence.begin( ) + p); //Начало

std::copy(rgt.Sequence.begin( ), rgt.Sequence.end( ), back_inserter(stemp));

//Замена

size_t q = p + rgt.Power( );

if (q < Power( ))

std::copy(Sequence.begin( )+q, Sequence.end( ), back_inserter(stemp));

//Окончание

MySet temp;

Sequence.clear( );

for (auto x : stemp) Sequence.push_back(temp.insert(*x).first);

setA.swap(temp);

}

}

int main( )

{

using namespace std::chrono;

setlocale(LC_ALL, "Russian");

srand((unsigned int)7); //Пока здесь константа, данные повторяются

// srand((unsigned int)time(nullptr)); //Разблокировать для случайных данных

auto rand = [ ] (int d) { return std::rand( )%d; }; //Лямбда-функция!

ofstream fout;

fout.open("in.txt");

for(int p = 10; p< 5000; p += 10)

{

int middle_power = 0, set_count = 0;

auto Used = [&] (MyCont & t){ middle_power += t.Power( ); ++set_count; };

MyCont A(p, 'A');

MyCont B(p, 'B');

MyCont C(p, 'C');

MyCont D(p, 'D');

MyCont E(p, 'E');

MyCont F(p, 'F');

MyCont G(p, 'G');

MyCont H(p, 'H');

MyCont R(p);

auto t1 = std::chrono::high_resolution_clock::now( );

A|B; Used(A); Used(B);

C|D; Used(C); Used(D);

(A|B)-(C|D); Used(A); Used(B); Used(C); Used(D);

((A|B)-(C|D))|E; Used(A); Used(B); Used(C); Used(D); Used(E);

R.Merge(E); Used(R); Used(E);

int c = rand(R.Power( ));

R.Subst(G, c); Used(R); Used(G);

c = rand(R.Power( ));

R.Change(H, c); Used(R); Used(H);

auto t2 = std::chrono::high_resolution_clock::now( );

auto dt = duration_cast<duration<double>>(t2-t1);

middle_power /= set_count;

fout << middle_power << ' ' << dt.count() << endl;

}

cout << "The end\n";

fout.close();

std::cin.get( );

return 0;

}

Санкт-Петербург

2021

Соседние файлы в папке 4 семестр