Автор: Пользователь скрыл имя, 02 Марта 2013 в 19:41, дипломная работа
Целью выпускной работы является разработка алгоритмического подхода к изучению элементов комбинаторики методов их перебора.
Задачи исследования:
1) изучить литературу по теме выпускной работы;
2) провести сравнительный анализ элементов комбинаторики и правил их построения, описания алгоритмов перебора сочетаний, перестановок и размещений;
3) описать методику решения численных задач дискретного анализа;
4) подготовить рекомендации по усовершенствованию логики изложения некоторых вопросов комбинаторики.
Введение
1. Комбинаторные задачи в школьном курсе математики 9
1.1. Сочетание по m элементов из n 9
1.2. Перестановки из элементов n 11
1.3. Размещение m элементов по n позициям 14
2. Алгоритмы перебора 18
2.1. Перебор сочетаний, перестановки, размещения. 18
3. Большие числа 25
3.1. Упаковка натурального числа в виде массива 25
3.2. Сравнение больших чисел 29
3.3. Сложение и вычитание двух больших чисел 36
4. Комбинаторные алгоритмы. Сочетание 40
4.1. Генерация сочетания по его номеру 40
4.2. Сочетания с повторениями 47
5. Комбинаторные алгоритмы. Перестановки 50
5.1. Число перестановок из n элементов 50
5.2 Определение номера перестановки. Определение перестановки по номеру 52
5.3. Перестановки с повторениями 54
6. Множества и алгоритмы перебора 56
6.1. Подмножество. Перечисление подмножеств 56
6.2. Нумерация подмножеств 59
6.3. Скобочные последовательности и их нумерация 64
ЗАКЛЮЧЕНИЕ 70
ЛИТЕРАТУРА 72
В ней отсутствующие промежуточные 6х+3 заканчиваются суффиксом -иллиард (из нее мы заимствовали миллиард, который еще называется биллион).
Общий список чисел используемых в России представляю ниже:
Таблица1
Число |
Название |
Латинское числительное |
Увеличивающая приставка СИ |
Уменьшаяющая приставка СИ |
Практическое значение |
101 |
десять |
дека- |
деци- |
Число пальцев на 2 руках | |
102 |
сто |
гекто- |
санти- |
Примерно половина числа всех государств на Земле | |
103 |
тысяча |
кило- |
милли- |
Примерное число дней в 3 годах | |
106 |
миллион |
unus (I) |
мега- |
микро- |
В 5 раз больше числа капель в 10-литровом ведере воды |
109 |
миллиард (биллион) |
duo (II) |
гига- |
нано- |
Примерная численность населения Индии |
1012 |
триллион |
tres (III) |
тера- |
пико- |
1/13 внутреннего валового продукта России в рублях за 2003 год |
1015 |
квадриллион |
quattor (IV) |
пета- |
фемто- |
1/30 длины парсека в метрах |
1018 |
квинтиллион |
quinque (V) |
экса- |
атто- |
1/18 числа зерен
из легендарной награды |
1021 |
секстиллион |
sex (VI) |
зетта- |
цепто- |
1/6 массы планеты Земля в тоннах |
1024 |
септиллион |
septem (VII) |
йотта- |
йокто- |
Число молекул в 37,2 л воздуха |
1027 |
октиллион |
octo (VIII) |
неа- |
сито- |
Половина массы Юпитера в килограммах |
1030 |
нониллион |
novem (IX) |
деа- |
тредо- |
1/5 числа всех микроорганизмов на планете |
1033 |
дециллион |
decem (X) |
уна- |
рево- |
Половина массы Солнца в граммах |
Произношение чисел, идущих далее, часто различается.
Таблица2
Число |
Название |
Латинское числительное |
Практическое значение |
1036 |
андециллион |
undecim (XI) |
|
1039 |
дуодециллион |
duodecim (XII) |
|
1042 |
тредециллион |
tredecim (XIII) |
1/100 от количества молекул воздуха на Земле |
1045 |
кваттордециллион |
quattuordecim (XIV) |
|
1048 |
квиндециллион |
quindecim (XV) |
|
1051 |
сексдециллион |
sedecim (XVI) |
|
1054 |
септемдециллион |
septendecim (XVII) |
|
1057 |
октодециллион |
Столько элементарных частиц на Солнце | |
1060 |
новемдециллион |
||
1063 |
вигинтиллион |
viginti (XX) |
|
1066 |
анвигинтиллион |
unus et viginti (XXI) |
|
1069 |
дуовигинтиллион |
duo et viginti (XXII) |
|
1072 |
тревигинтиллион |
tres et viginti (XXIII) |
|
1075 |
кватторвигинтиллион |
||
1078 |
квинвигинтиллион |
||
1081 |
сексвигинтиллион |
Столько элементарных частиц во вселенной | |
1084 |
септемвигинтиллион |
||
1087 |
октовигинтиллион |
||
1090 |
новемвигинтиллион |
||
1093 |
тригинтиллион |
triginta (XXX) |
|
1096 |
антригинтиллион |
Дальнейшие названия могут быть получены либо прямым, либо обратным порядком латинских числительных (как правильно, не известно):
Я считаю, что наиболее
правильным будет второй вариант
написания, так как он более соответствует
построению числительных в латинском
языке и позволяет избежать двухсмысленностей (например в числе
трецентиллион, которое по первому написанию
является и 10903 и 10312).
Числа далее:
Первым делом была выбрана структура класса больших целых чисел. Так как число может быть как положительным, так и отрицательным было введено символьное поле, отвечающее за знак числа «+» или «–». Само число решено было записывать с помощью очереди с двусторонним доступом (deque) – контейнер из стандартной библиотеки шаблонов (STL). Очередь представляет собой динамический массив с множеством стандартных методов для его обработки. «Цифру» каждого разряда большого числа мы будем помещать в соответствующую ячейку массива. Например, число 12345, записанное с помощью deque<int> mas; будет выгледеть как набор элементов этого массива: mas[0] = 1, mas[1] = 2, mas[2] = 3, mas[3] = 4, mas[4] = 5. Также класс будет содержать некоторое количество методов, для решения поставленных задач. Класс будет иметь название BigInteger. Структура класса изображена на рисунке 3.1.
Рис. 3.1. Схема класса BigInteger
Далее перешли к разработке методов класса. Сначала для непосредственной работы с большими числами были реализованы методы для чтения числа из консоли и печати в консоль – chtenie() и vector_print(BigInteger) соответственно.
Метод chtenie() считывает в виде строки данные введенные в консоль. Затем проверяет первый символ строки на наличие знака «–». Потом посимвольно, используя вспомогательную строку, содержащую цифры («0123456789»), заносит каждую цифру в конец очереди-массива. На выходе мы получаем большое число, содержащее знак «», либо «–». Также в методе используется вспомогательный метод dell_null(BigInteger), который возвращает число, удаляя впереди стоящие ничего не значащие нули (т.е. 00123 –> 123).
Метод vector_print(BigInteger) выполняет печать в консоль числа, предварительно задействовав, описанный выше вспомогательный метод dell_null(BigInteger). Сначала происходит печать знака числа, затем, используя цикл, выполняется печать каждого элемента очереди-массива. Результаты работы методов представлены на рисунке 3.2.
Рис. 3.2. Ввод-вывод большого положительного и отрицательного числа в консоль
Затем был реализован метод сложения двух больших чисел summa (BigIneger, BigInteger). Сначала метод проверяет знаки переданных ему чисел, если знаки разные, он, немного модифицируя знаки, передает числа методу, вычисляющему разность двух больших чисел, речь о котором пойдет дальше. Если же знаки чисел одинаковые, непосредственно происходит операция их сложения. Принцип основан на сложении «столбиком». Находим «длину» минимального по разрядам числа, затем складываем поразрядно числа в пределах этой «длины», добавляя 1, если сумма на предыдущем шаге была > 9, находим остаток от деления полученного числа на 10 (int % 10) и записываем его в разряд, над которым выполнялась операция. После того, как разряды у одного из чисел закончатся, «добиваем» результирующее число цифрами из оставшихся разрядов большего числа. Естественно, чтобы произвести операцию с первым разрядом, нужно обратиться к последнему элементу нашей очереди массива. Пример сложения представлен на рисунке 3.3.
Рис. 3.3. Операция сложения
Следующей операцией над большими числами стала операция вычитания, представленная методом rasnost (BigInteger, BigInteger). Вначале метод проверяет знаки переданных ему чисел, если знаки чисел равные (с учетом знака разности), то метод передает числа методу summa (BigInteger, BigInteger). Например, 12 – (-7). Метод передаст 12 и 7 для обработки методу summa (BigInteger, BigInteger). Если знаки чисел разные, то происходит операция вычитания. Принцип основан на вычитании «столбиком». Находим число с меньшим количеством разрядов (меньшей «длиной»), ставим его вторым. И начинаем поразрядно вычитать. При этом, если в разряде первого числа значение больше, чем в разряде второго числа, прибавляем к разности этих чисел 10. Но на следующем шаге вычитаем 1 из следующего полученного результата поразрядного вычитания. Выполняем эти действия, пока не закончатся разряды наименьшего числа, затем «добиваем» результирующее число цифрами из оставшихся нетронутыми разрядов большего числа. Пример вычитания представлен на рисунке 3.4.
Рис. 3.4. Операция вычитания
После того, как были реализованы операции сложения и вычитания, перешли к написанию операции умножения, которую выполняет метод proisvedenie (BigInteger, BigInteger). Также в его основе лежит принцип умножения «столбиком». Выбираем одно из больших чисел, и поэтапно умножаем числа из каждого разряда этого большого числа, на другое большое число. В результате на каждом шаге у нас получаются «промежуточные» большие числа, суммируя которые с помощью описанного выше метода summa (BigInteger, BigInteger) мы получаем необходимый нам результат. При этом не забываем в зависимости от разряда множителя «добивать» начальные разряды «промежуточных» больших чисел нулями. Как и в предыдущих операциях при поразрядном перемножении в результат мы записываем остаток от деления на 10 и, если результат поразрядного перемножения больше либо равен 10, то на следующем шаге перемножения мы прибавляем число равное целой части от деления предыдущего результата на 10. Также для ускорения процесса перемножения были выделены особые случаи – умножение на 0 и на 1. Пример перемножения двух больших чисел представлен на рисунке 3.5.
Рис. 5.5. Операция умножения
После реализации метода перемножения двух больших чисел операции возведения числа в степень и операция взятия факториала числа не представляют большой трудности, так как могут быть выражены через умножение. Метод stepen (BigInteget, int), представляющий операцию возведения в степень большого числа, принимает в качестве аргументов само большое число и целое число, задающее степень, в которую необходимо возвести большое число. Метод вызывает операцию перемножения числа на само себя в цикле, количество шагов которого равно заданной степени. После выполнения данного цикла получаем нужную нам степень большого числа. Метод factorial(BigInteger), представляющий операцию получения факториала большого числа, мог быть выполнен двумя способами: используя рекурсию или используя итерацию, т.е. цикл. Был выбран второй вариант, так как он более производительный и не требует повторного вызова метода factorial(BigInteger), что замедляло бы работу программы. Для перемножения здесь использовалось вспомогательное большое число, которое изначально приравнивалось к числу, факториал которого нужно было найти. Затем на каждом шаге итерации оно уменьшалось на 1. На каждом шаге это число умножалось на ранее полученный результат, т.е. получалась выражение вида N!=((N*N-1)*N-2*)…*1. После выполнения данного цикла получаем факториал заданного числа.
Рисунок 3.6. Вычисление факториала 1000
Построение проекта осуществлялось в режиме Release. Технические характеристики компьютера, на котором выполнялись расчеты, представлены на рисунке 7.
Информация о работе Комбинаторные алгоритмы решения школьных задач по информатике