Оценка асимптотической временной сложности алгоритма поиска с возвращением

  • Вид работы:
    Курсовая работа (т)
  • Предмет:
    Информационное обеспечение, программирование
  • Язык:
    Русский
    ,
    Формат файла:
    MS Word
    13,34 Кб
  • Опубликовано:
    2013-06-25
Вы можете узнать стоимость помощи в написании студенческой работы.
Помощь в написании работы, которую точно примут!

Оценка асимптотической временной сложности алгоритма поиска с возвращением

Задание на курсовую работу

В курсовой работе требуется формализовать поставленную задачу, разработать эффективные алгоритмы решения, реализовать алгоритм в виде программы, исследовать и оценить теоретически и экспериментально временную и емкостную сложность алгоритмов.

В качестве задачи на курсовую работу была предложена следующая комбинаторная задача:

Задаются арифметические операции, в которых цифры заменены буквами. В данной операции одна и та же буква всегда заменяет одну и ту же цифру, разные буквы представляют разные цифры. Число разрядов исходных чисел (не результат операции) - не более N. Восстановить все возможные значения букв и операций.

Исследовать асимптотическую временную сложность решения задачи в зависимости от N.

Пример: SEND MORE MONEY соответствует 9567+1085=10652.

При выполнении курсовой работы требуется:

·        Формализовать поставленную задачу (перейти от словесной неформальной постановки к математической формулировке);

·        Приспособить общие методы и алгоритмы решения к решению конкретной задачи;

·        Провести сравнительную оценку различных вариантов с целью выбора наиболее эффективных структур данных и алгоритмов обработки;

·        Исследовать и оценить теоретические и экспериментальные методы сокращения перебора в комбинаторных задачах;

·        Оценить аналитически и экспериментально эффективность предложенных в работе алгоритмов (временную и емкостную сложности);

·        Программно реализовать разработанные алгоритмы на одном из алгоритмических языков программирования.

·        Экспериментально исследовать различные способы программной реализации алгоритмов.

Анализ задания. Выводы о методах решения и путях повышения эффективности вычислений

математический алгоритм программирование данные

Рассмотрим индивидуальное задание и проанализируем методы решения. Эта задача имеет логическое ограничение на количество различных букв в строке - количество цифр 10. Поэтому, бесконечно расти, эта задача может только в размерности чисел, но здесь ограничение может быть наложено скорее возможностями программных средств, чем алгоритмом реализации.

Сама идея решения данной задачи заключается в том, что мы последовательно проходим введенную строку и заменяем все вхождения одной буквы на выбранную цифру. После расстановки цифр расставляются знаки операции, и проводится проверка (является решением или нет). Знаков операции всего 4: сложение, вычитание, умножение и деление. Знак ‘=’ ставится вместо последнего не буквенного символа. Так как выбор цифр, которые будут подставлены, выбираются последовательно необходимо запретить выбор тех же цифр. Для этого создадим таблицу размером 10×10, и введем следующие обозначения

0-  символ можно выбрать:

1-      символ выбран в этой строчке в настоящее время;

-        символ был использован в этой строчке раньше (в этой строчке использовать этот символ больше нельзя, но в следующих можно);

-        символ выбран в выше стоящей строчке;

Ввод данной таблицы обусловлен тем, что в данной задаче не возможно определить для данного узла какие значения уже подставлялись, а какие нет. В этом случае возможно повторная проверка уже пройденного пути.

I.       Формализация задачи

.1 Структуры данных для представления объектов задачи

Основная работа в алгоритме решения данной задачи происходит с исходной строкой и лишь на конечном этапе производится перевод чисел записанных в строке в числовую форму.

Для алгоритма поиска с возвращением обычно решением является вектор(a1, a2,…), но в нашем случае таким решением будет строка с полностью замененными буквами и подставленными знаками, которая и выводится на экран, в том случае если она верна.

Выбор следующего шага выполняется по таблице описанной выше. Так же выполняется подстановка знаков. При продвижении в глубину в строке проставляются 3 в тех столбцах, где в предыдущей строке стоит 3 или 1, и эти цифры уже не могут быть выбраны.

1.2 Анализ ограничений и усовершенствований. Аналитические и/или экспериментальные оценки

Основное ограничение в этой задаче указано в самом задании. Это ограничение связано в однозначном соответствии букв и цифр.

Второе ограничение накладывается на количество знаков, оно влияет на количество пройденных вершин и соответственно на время работы алгоритма. В данной работе это ограничение равно 4. Максимальное число узлов дерева равно 10!. И рассчитывается по формуле:

, где n - число различных букв в строке.

1.3 Разработка алгоритмов решения задачи

В данном пункте описаны алгоритмы для решения поставленной задачи. Сначала приведем сам алгоритм, а потом разберем его.

Алгоритм 1. Итерационный алгоритм поиска с возвращением.

Алгоритм 1 является модификацией общего итерационного алгоритма поиска с возвращением. Суть самого алгоритма описывать не буду, разберу лишь некоторые процедуры.


Этот алгоритм представляет модификацию общего рекурсивного алгоритма поиска с возвращением для решения данной задачи. Процедуры использованный в данном алгоритме аналогичны, использованным в итерационном алгоритме.


Процедура Copy позволяет избежать выбора уже выбранных ранее цифр.


Эта процедура выполняет подстановку знаков и проверку верна ли строка. Она представляет собой поиск с возвращением и похожа на основной алгоритм. Эти две процедуры были разделены по той причине, что они подставляют символы вместо различных символов. Основной алгоритм подставляет вместо буквенных символов цифры, а процедура Podstan подставляет вместо не буквенных символов знаки операций.


Процедура Vozvrat делает обратный шаг, она возвращает последние замененные символы на место и отмечает обратный шаг в таблице.

II.      Оценка асимптотической временной сложности алгоритма (Метод Монте-Карло)

Вычисление по методу Монте-Карло можно использовать для оценки эффективности алгоритма поиска с возвращением путём сравнения его с эталоном, полученным для задачи с меньшей размерностью.

В данной работе этот метод используется для исследования асимптотической временной сложности решения задачи в зависимости от количества различных букв в строке и количества знаков операций.

Размер задачи

Метод Монте-Карло

Фактичкески

Число Букв

Число символов

Число узлов

Порядок роста

Число узлов

Время (мс)

Порядок роста

6

1

8231241


7921100

2140


6

2

8763254

1,06

8543802

2391

1,11

3

9245687

1,05

9234561

2641

1,10

6

4

10632540

1,15

10045678

2857

1,08


Данная таблица показывает рост времени и пройденных узлов при увеличение количества знаков при одном и том же числе различных букв.

Размер задачи

Метод Монте-Карло

Фактичкески

Число Букв

Число символов

Число узлов

Порядок роста

Число узлов

Время (мс)

Порядок роста

7

1

3546211


3211300

9406


8

2

10542136

2,9

9864100

35328

3,7

9

3

25874961

2,4

24660250

83218

2,5

10

4

36844794

1,4

36990375

125512

1,5


Данная таблица показывает рост времени и пройденных узлов при одновременном увеличение количества знаков и различных букв.

Размер задачи

Метод Монте-Карло

Фактичкески

Число Букв

Число символов

Число узлов

Порядок роста

Число узлов

Время (мс)

Порядок роста

1

1

51


50

0


2

1

472

9

0


3

1

3751

8

3700

15


4

1

26135

7

26020

63

4

5

1

157564

6

157060

453

7

6

1

793451

5

792100

2106

4,7

7

1

3324578

4,1

3211300

9844

4,4

8

1

10065487

3

9864100

33047

3,5

9

1

21789546

2

20750500

74078

2,4

10

1

34589744

1,5

33492900

108203

1,4


Данная таблица показывает рост времени и пройденных узлов при увеличение количества различных букв, при одном и том же количестве знаков.

III. Программная реализация алгоритма

3.1 Реализация данных

При реализации данных использовались следующие структуры:      Byval[11][10] - Таблица хранения уже пройденного путиsstr[27] = "abcdefghijklmnopqrstuvwxyz"; - массив элементов распознаваемых как букваZnak[4][4] - Таблица хранения пройденного пути для операций

char* isch_str - исходная строка с которой проводятся все операции

Так же для удобства работы был создан стек под эту программу

struct stac

{nom;sym;

};

В которую записываются все символы заменяемые в строке.

Следующая подставляемая цифра выбирается следующим образом:

Берется первый элемент, помеченный 0 в данной строке (зависит от Glub) и помечается 1.

3.2 Реализация алгоритмов

Рассмотрим подробнее программную реализацию алгоритма.

- различных буквенных символов должно быть не более 10

- не должно быть два подряд идущих не буквенных символов, и всего не буквенных символов не должно быть не более 4.(procedure Proverka и Prover)

Procedure Rabota - основная процедура в которой и происходит основная работа.

Procedure Pystot - процедура просматривающая таблицу Byval и определяющая есть ли еще цифру доступные к вставке.

Procedure Sled - процедура выбирающая еще не использованную цифру.

Procedure NextPo - выбор следующей не заменненой буквы. Проходя по строке и сравнивая каждый символ со строкой sstr первый символ который есть в sstr выбирается на замену.

Procedure Podstano - процедура подставляет знаки и выполняет окончательную проверку строки. Если строка верна то она выводится на экран.

Все процедуры разработаны для итерационного варианта реализации алгоритм поиска с возвращением. Хотя итерационный и рекурсивный вариант похожи и переход от одного варианта реализации к другому не займет много времени и не потребует больших изменений в тексте программы. Автор выбрал для программной реализации итерационный вариант в силу того, что рекурсивный вариант требует больше памяти, несколько сложнее для реализации и в силу личных предпочтений автора.

3.3 Исследование способов программирования

Программа была реализована на языке высокого уровня Microsoft Visual C++ 6.0 d в виде одного модуля

Размеры исходного файла: 6кбайт

Размеры исполняемого файла: 208 кбайт

Приведу пример работы данной задачи

asd fgh sderg

*184=67528

*028=14392

Выводы по работе

В данной курсовой работе в соответствие с заданием были разработаны и исследованы алгоритмы решения поставленной комбинаторной задачи. Как основа алгоритма решения были взят общий итерационный алгоритм поиска с возвращением. Отличительной чертой задачи предложенной на курсовой проект является то, что она имеет логические ограничения, и поэтому не способна расти до бесконечности, так же в этой задаче не удалось найти способов сокращения перебора, но нужно заметить, что для данной задачи они не очень важны, так как наибольшее время работы программы 2 минуты (при изменение разрядности это время будет не значительно увеличиваться). Но время работы порядка 1 часа получить не получится.

Результатом данной курсовой работы является пояснительная записка, приложение к пояснительной записке, в котором содержится листинг программы, и сама программа.

Приложение

#include <iostream.h>

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#include <ctype.h>

#include <Windows.h>

#include <conio.h>isch_str[30];sstr[27] = "abcdefghijklmnopqrstuvwxyz";chisla[10]= {1,1,1,1,1,1,1,1,1,1};Chisl[11] = "1234567890";cfstr[27];Znaki[5]="+-*/";     Byval[11][10]= {{0,0,0,0,0,0,0,0,0,0},

{0,0,0,0,0,0,0,0,0,0},

{0,0,0,0,0,0,0,0,0,0},

{0,0,0,0,0,0,0,0,0,0},

{0,0,0,0,0,0,0,0,0,0},

{0,0,0,0,0,0,0,0,0,0},

{0,0,0,0,0,0,0,0,0,0},

{0,0,0,0,0,0,0,0,0,0},

{0,0,0,0,0,0,0,0,0,0},

{0,0,0,0,0,0,0,0,0,0},

{0,0,0,0,0,0,0,0,0,0}};Znak[4][4]={{0,0,0,0},

{0,0,0,0},

{0,0,0,0},

{0,0,0,0}

};Ukaz;Zna;Chis;Pustota=0;Prisn=1;okr;Ver=0;start,end;stac

{nom;sym;

};STAC[15];POPS()

{-;(STAC[Ukaz]);

}PUSHS(stac Elm)

{[Ukaz]=Elm;++;(0);

}Proverka(char* str)

{(cfstr,0,27);(int i=0, j = 0; i < (int)strlen(str); i++) ((strchr(sstr,str[i])) && !cfstr[str[i]-97])

{++;[str[i]-97] = 1;

};(int a=0; a<(int)strlen(str);a++)(!(strchr(sstr,str[a]))) Zna++;j;

}Prover(char* str)

{        Pre=0,kod;(int i=0; i<(int)strlen(str)-1;i++)

{=str[i];((!((kod>96)&&(kod<123)))&&(Pre)) return(0);if (!((kod>96)&&(kod<123)))Pre=1;Pre=0;

}(int j=(int)strlen(str)-2;j>=0;j--)      (!strchr(sstr,str[j])) {str[j]='=';return(1);}(0);

}Podstan(char* str, char chr,char chrz)

{(int i=0; i<(int)strlen(str); i++)(str[i]==chr) str[i]=chrz;(0);

}Vozvrat(char* str,int Glub)

{Pr;ch,cho;pos;=POPS();=Pr.sym;=Pr.nom;=str[pos];(int j=pos; j<=(int)strlen(str);j++)        

{if(str[j]==cho) str[j]=ch;}(int i=0; i<10; i++)[Glub][i]=0;

{for (int b=0; b<10; b++)(Byval[Glub-1][b]==1) Byval[Glub-1][b]=2;

}(0);

}Proverca(char* str,int Glub)

{(1);

}NextPo(char* str, int po)

{        for(int i=0; i<(int)strlen(str);i++ )(strchr(sstr,str[i])) return(i);(-1);

}Pystot(char* str, int Glub)

{        (int j=10,a=0; a<10; a++)(Byval[Glub][a]) j--;(j);

}Copy(int Glub, char ch1)

{(Glub==0) Byval[Glub][ch1-48]=1;{for(int i=0;i<=10;i++)((Byval[Glub-1][i]==1)||(Byval[Glub-1][i]==3)) Byval[Glub][i]=3;}(0);

}Sled(int Glub)

}Pys(int zn)

{(int j=4,i=0; i<=4;i++)=Znak[zn][i];(j);

}Vyb(char* str, int p)

{(int i=p+1; i<(int)strlen(str);i++)(!(strchr(Chisl,str[i]))) return(i);(-1);

}V(int zn)

{(int i=0; i<4; i++)(!Znak[zn][i])

{Znak[zn][i]=1;(i){(0):return('+'); break;(1):return('-'); break;(2):return('*'); break;(3):return('/'); break;

}

}(0);

}Voz(char* str)

{        stac pred;=POPS();[pred.nom]=pred.sym;(0);

}PROVERKA(char* str,int zn)

{        int pos=0;ch;dw1=atof(str),dw2;i=0;(zn<Zna) return(0);(pos<(int)strlen(str))

{(isdigit(str[pos])) pos++;=str[pos];+=1;=atoi(str+pos);(ch)

{('='):if (dw1==dw2) cout<<str<<endl; Pustota=1;return(1);('+'):dw1+=dw2; break;('-'):dw1-=dw2; break;('*'):dw1*=dw2; break;('/'):if (!(dw2==0))dw1/=dw2; break;

}

}(0);

}Podstano(char* str, int Glub)

{zn=0,p=0,Pri=1;Per;ch;++;(Chis>Glub)return(0);(zn>=0)

{((Pri)&&(Pys(zn)))

{p=Vyb(str,p);.nom=p;.sym=str[p];(Per);=V(zn);++;(str[p]!='=')

{str[p]=ch;++;(zn==1)

{ for(int a=3;a>=0;a--)(Znak[0][a]==1){ Znak[1][a]=1; ;}}(!(zn==1)) {for(int i=0;i<4;i++)[zn][i]=Znak[zn-1][i];}

}(PROVERKA(str,zn)) Pri=0;

}(zn!=0) Voz(str);(int b=0; b<4;b++)[zn][b]=0;-;=1;=0;

}=0;(0);

}Rabota(char* str)

{        int Nomerchis=0; //Íîìåð ïîñëåäíåãî çàìåííåíîãî ñèìâîëà

memset(chisla,1,10);* isch=str;ch,ch1;                        

int po=0,k=1,Nu=0,Glub=0;            //Ex-ïðèçíàê âûõîäà

stac Per;(Glub>=0)

{((Prisn)&&(Pystot(str,Glub)))

{(po!=-1)

{=str[po];.nom=po;.sym=ch;(Per);=Sled(Glub);(ch1!=0)Podstan(str,ch,ch1);++;(Glub,ch1);(str,Glub);}=NextPo(str,po);

}(str,Glub);-;=1;

}        (0);

}main()

{<<”Введите строку”<< endl;(isch_str,30,stdin);=Proverka(isch_str);(Chis>10) {cout<<”Неправильная строка"<<endl; getch();exit(0);}(!(Prover(isch_str))) {cout<<"Неправильная строка"<<endl; ();exit(0);}=GetTickCount();=2;(isch_str);=GetTickCount();=start;(!Pustota) cout<<"Нет вариантов";<<"Перебор закончен"<<endl;<<"Время "<<end<<endl;<<"Вершин "<<Ver<<endl;<<"Press any key"<< endl;();(0);

}

Похожие работы на - Оценка асимптотической временной сложности алгоритма поиска с возвращением

 

Не нашли материал для своей работы?
Поможем написать уникальную работу
Без плагиата!