Факультет компьютерных технологий и информатикиx

advertisement
МИНОБРНАУКИ РОССИИ
Федеральное государственное бюджетное образовательное учреждение
высшего профессионального образования
“Санкт-Петербургский государственный электротехнический университет
“ЛЭТИ” им. В.И. Ульянова (Ленина)”
(СПбГЭТУ)
Факультет компьютерных технологий и информатики (ФКТИ)
Кафедра МОЭВМ
Отчёт по лабораторной работе №1
по дисциплине «Построение и анализ алгоритмов»
Выполнил: студент группы 1303
Леонтьев Ю.А.
Проверил: аспирант кафедры МОЭВМ
Романенко Д.А.
г. Санкт-Петербург
2013 г.
ЗАДАНИЕ
Вариант 10. Сортировка массивов слиянием (простое слияние).
Необходимо генерировать исходные данные, одним из подходящих способов:
Генерация: при случайной генерации задаются тип элементов, размер массива,
диапазон значений элементов.
Визуализация: Можно использовать любые простейшие графические средства, в
крайнем случае, в этом задании можно использовать вывод в консоль
Указания.
Основной упор в задании делается на проведение экспериментального испытания
(исследования) алгоритма (программной реализации). При
этом оценивается
эффективность алгоритма (его вариаций, разновидностей, модификаций). Основной
показатель эффективности в этих заданиях - это время выполнения. Время выполнения
должно измеряться, во-первых, с использованием компьютерного таймера. Во-вторых,
требуется в ходе выполнения программы подсчитывать количество произведенных
базовых операций алгоритма, например, операций сравнения и операций присваивания
(перемещения элементов).
Во всех случаях рекомендуется провести сравнения (по тем показателям, по
которым это возможно) с каким-либо «эталонным» алгоритмом (реализацией), например,
с системной функцией qsort или с какой-либо ещё библиотечной функцией.
ОПИСАНИЕ АЛГОРИТМА
Шаг 1. Исходный файл f разбивается на два вспомогательных файла f1 и f2.
Шаг 2. Вспомогательные файлы f1 и f2 сливаются в файл f, при этом одиночные элементы
образуют упорядоченные пары.
Шаг 3. Полученный файл f вновь обрабатывается, как указано в шагах 1 и 2. При этом
упорядоченные пары переходят в упорядоченные четверки.
Шаг 4. Повторяя шаги, сливаем четверки в восьмерки и т.д., каждый раз удваивая длину
слитых последовательностей до тех пор, пока не будет упорядочен целиком весь файл
Признаками конца сортировки простым слиянием являются следующие условия:

длина серии не меньше количества элементов в файле (определяется после фазы
слияния);

количество серий равно 1 (определяется на фазе слияния).

при однофазной сортировке второй по счету вспомогательный файл после
распределения серий остался пустым.
ПРИМЕР РАБОТЫ
АНАЛИЗ РЕЗУЛЬТАТОВ ПОЛУЧЕННЫХ С ПОМОЩЬЮ ПРОГРАММЫ
В таблице 1 представлены результаты работы программы.
Размер
массива
10
20
30
40
50
60
70
80
90
100
Время выполнения (с)
Количество итераций
0,00688288254823419
0,00705618498104741
0,00722978065023199
0,00749794490475324
0,0077339509538433
0,00786991467830376
0,00829178343192325
0,00830336625003838
0,00841929218731821
0,00829588873457396
115
266
395
607
758
906
1200
1368
1539
1709
Таблица 1
Время выполнения
функции qsort(с)
0,00302570603525965
0,00318356470961589
0,0039562413803651
0,00368255451758159
0,00394646685163025
0,00389808291947702
0,00425631947291549
0,00420744682196528
0,00409601716819452
0,00505294375034282
График зависимости времени от размера массива указан на рисунке 2
Рис.2
0.009
Время выполнения(с)
0.008
0.007
0.006
0.005
0.004
0.003
0.002
0.001
0
10 20 30 40 50 60 70 80 90 100
Время выполнения(с)
График зависимости количества итераций от количества элементов массива
представлен на рисунке 3.
Рис.3
Количество итераций
1800
1600
1400
1200
1000
Количество итераций
800
600
400
200
0
10 20 30 40 50 60 70 80 90 100
График зависимости времени выполнения программы и времени выполнения
функции qsort() от количества элементов массива представлен на рисунке 4.
Рис.4
0.009
0.008
0.007
0.006
Время Выполнения
(с)
0.005
0.004
Время выполнения
qsort
0.003
0.002
0.001
0
1
2
3
4
5
6
7
8
9 10
Количество итераций для сортировки слиянием можно найти по формуле
O(log2(n)). В таблице 2 представлены фактические и теоретические значения количества
итераций.
Таблица 2
Размер массива
10
20
30
40
50
60
70
80
90
100
O(log2(n))
33
86
147
213
282
354
429
506
584
664
Количество итераций
115
266
395
607
758
906
1200
1368
1539
1709
По данным можно сделать следующие выводы:
1. С увеличением количества элементов в массиве увеличивается время выполнения
программы и количество итераций при сортировке слиянием (простое слияние).
2. Время выполнения библиотечной функции быстрой сортировки qsort намного
быстрее.
3. Данная реализация алгоритма сортировки слиянием имеет спецификацию,
которая не позволяет вычислить количество итераций. Поэтому значительно отличаются
теоретические и практические значения количества итераций.
ИСХОДНЫЙ КОД ПРОГРАММЫ
Sort.cpp
#include
#include
#include
#include
#include
"StdAfx.h"
"sort.h"
<time.h>
<stdio.h>
<string.h>
void Str(char *name)
{
fstream fout;
fout.open(name);
while (!fout.eof())
{
getline(fout,str);
}
}
void Simple_Merging_Sort (char *name){
int a1, a2, k, i, j, kol, tmp;
int kol_ch=0;
int *A;
FILE *f, *f1, *f2;
string str1="";
kol = 0;
if ( (f = fopen(name,"r")) == NULL )
printf("\nИсходный файл не может быть прочитан...");
else {
while ( !feof(f) ) {
fscanf(f,"%d",&a1);
kol++;
kol_op++;
}
fclose(f);
kol_ch=kol-1;
A=new int[kol_ch];
int i1=0;
FILE *ft;
ft=fopen("1.txt","rt");
while ( !feof(f) )
{
fscanf(ft,"%d",&A[i1]);
i1++;
}
i1--;
fclose(ft);
str1 = "Исходный массив:\n";
Str(name);
str1+=str;
str=str1;
}
k = 1;
while ( k < kol ){
f = fopen(name,"r");
f1 = fopen("smsort_1","w");
f2 = fopen("smsort_2","w");
if ( !feof(f) ) fscanf(f,"%d",&a1);
while ( !feof(f) ){
for ( i = 0; i < k && !feof(f) ; i++ ){
kol_op++;
fprintf(f1,"%d ",a1);
fscanf(f,"%d",&a1);
}
for ( j = 0; j < k && !feof(f) ; j++ ){
kol_op++;
fprintf(f2,"%d ",a1);
fscanf(f,"%d",&a1);
}
kol_op++;
}
fclose(f2);
fclose(f1);
fclose(f);
f = fopen(name,"w");
f1 = fopen("smsort_1","r");
f2 = fopen("smsort_2","r");
if ( !feof(f1) ) fscanf(f1,"%d",&a1);
if ( !feof(f2) ) fscanf(f2,"%d",&a2);
while ( !feof(f1) && !feof(f2) ){
kol_op++;
i = 0;
j = 0;
while ( i < k && j < k && !feof(f1) && !feof(f2) ) {
if ( a1 < a2 ) {
kol_op++;
fprintf(f,"%d ",a1);
fscanf(f1,"%d",&a1);
i++;
}
else {
kol_op++;
fprintf(f,"%d ",a2);
fscanf(f2,"%d",&a2);
j++;
}
}
while ( i < k && !feof(f1) ) {
kol_op++;
fprintf(f,"%d ",a1);
fscanf(f1,"%d",&a1);
i++;
}
while ( j < k && !feof(f2) ) {
kol_op++;
fprintf(f,"%d ",a2);
fscanf(f2,"%d",&a2);
j++;
}
}
while ( !feof(f1) ) {
kol_op++;
fprintf(f,"%d ",a1);
fscanf(f1,"%d",&a1);
}
while ( !feof(f2) ) {
kol_op++;
fprintf(f,"%d ",a2);
fscanf(f2,"%d",&a2);
}
fclose(f2);
fclose(f1);
fclose(f);
k *= 2;
kol_op++;
str += "\n_______________________________\nf1 массив:\n";
str1=str;
Str("smsort_1");
str1+=str;
str=str1;
str += "\n_______________________________\nf2 массив:\n";
str1=str;
Str("smsort_2");
str1+=str;
str=str1;
str += "\n_______________________________\nслияние:\n";
str1=str;
Str("1.txt");
str1+=str;
str=str1;
}
remove("smsort_1");
remove("smsort_2");
sortq(kol_ch, A);
}
int compare(const void* first, const void* second)
{
return *((int*)first) - *((int*)second);
}
string to_string(int val) {
char buff[32];
sprintf(buff,"%d",val);
return string(buff);
}
void sortq(int kol_ch, int* A)
{
double t1 = omp_get_wtime(); // системное время до выполнения функции
string str1="";
str1="\n_______________________\nQsort:\n";
qsort(A, kol_ch, sizeof(int), compare);
for (int i=0;i<kol_ch;i++)
{
str1+=to_string(A[i]);
str1+=" ";
}
str+=str1;
double t2 = omp_get_wtime(); // время после выполнения функции
time1 = t2 - t1;
time1=time1;
}
Rand.cpp
#include
#include
#include
#include
#include
"stdafx.h"
<string>
<iostream>
<fstream>
"Form1.h"
using namespace std;
void random(int kol, int range, int min)
{
FILE *f;
f = fopen("1.txt","w");
srand(time(0));
//
int kol = 10;
//
int range =99; // Разница между минимумом и максимумом
//
int min = -100;// Левая граница нужного промежутка.
for (int i=0; i<kol;i++)
fprintf(f,"%d ",(rand() % (range+1) + min));
//int x = rand() % (range+1) + min;
//return x;
fclose(f);
}
int random_1(int kol, int range, int min)
{
if (kol>(range+1))
{
return 1; // получается то, что наш массив длинее интервала, и все разные числа быть не
могут.
}
srand(time(0));
FILE *f;
int *parr;
parr = new int[kol];
int i, j;
int dup_flag;
int rand_val, range_width= range+1;
for ( i= 0; i<kol; i++ ) {
for ( ; ; ) {
rand_val= rand() % (range+1) + min;
dup_flag= 0;
for ( j= 0; j<i; j++ ) {
if ( rand_val == parr[j] ) { dup_flag= 1; break; }
}
if ( !dup_flag ) { break; }
}
parr[i]= rand_val;
}
f = fopen("1.txt","w");
for (int k=0; k<i;k++)
fprintf(f,"%d ", parr[k]);
fclose(f);
}
Form1.h
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
string str="";
Print(str);
double t1 = omp_get_wtime(); // системное время до выполнения
Simple_Merging_Sort("1.txt");
double t2 = omp_get_wtime(); // время после выполнения
double time = t2 - t1;
richTextBox1->Text
+="\n_______________________\nВремя
выполнения:\n" + time;
richTextBox1->Text
+="\n_____________________________\nКоличество базовых операций:\n" + kol_op;
richTextBox1->Text +="\n_____________________________\nВремя
выполнения Qsort:\n" + Time_Qsort();
Вывод
При выполнении лабораторной работы были получены практические навыки работы
с различными сортировками. Была составлена программа с использованием сортировки
слиянием (простое слияние). Ошибок в её работе не обнаружено.
Download