task_18775x

advertisement
ТЕМАТИКА КУРСОВЫХ РАБОТ
по дисциплине «Программирование»
для студентов направления МОАИС, 5 блок
Варианты индивидуальных заданий:
Выберите вариант задания и впишите свою фамилию
Задание
ФИО
исполнителя
1. Найти все истоки и стоки данного орграфа.
2. Задана система односторонних дорог. Найти путь, соединяющий города А и В
и не проходящий через заданное множество городов.
3. По системе односторонних дорог определить, есть ли в ней город, из которого
можно добраться до каждого из остальных городов, проезжая не более 100
км.
4. Определить, можно ли в заданной системе односторонних дорог проехать из
города А в город В таким образом, чтобы посетить город С и не проезжать
никакой дороги более одного раза.
5. Найти в графе все вершины, недостижимые из заданной вершины.
6. Известно, что заданный граф - не дерево. Выяснить, можно ли из него удалить
одну вершину (вместе с инцидентными ей ребрами) так, чтобы в результате
получилось дерево.
7. Определить количество компонент связности в дополнении заданного графа.
8. Изобразить графически заданный планарный граф так, чтобы его ребра не
пересекались.
9. Определить, является ли заданный граф двудольным.
10. По заданной матрице смежности графа определить, является ли граф
уникурсальным и если да, то получить путь обхода узлов.
11. Определить станцию пересадки в московском метро, если задаются
начальная и конечная станции маршрута. Итоговый путь должен отнимать
минимальное время( считать, что на пересадку тратится 5 мин, а на проезд
между двумя станциями 2 мин).
12. В системе двусторонних дорог для каждой пары городов указать длину
кратчайшего пути между ними.
13. Задана система двусторонних дорог. N - периферией называется множество
городов, расстояние от которых до выделенного города(столицы) больше N.
Определить N-периферию для заданного N.
14. Выяснить, имеется ли в заданном графе эйлеров путь или эйлеров цикл, и
найти эйлеров цикл (если он есть).
15. Выяснить, имеется ли в заданном графе гамильтонов цикл, и найти его (если
он есть).
16. Система двусторонних дорог называется трисвязной, если для любой четверки
разных городов A,B,C,D существуют два различных пути из A в D , причем,
один из них проходит через В, а другой - через С. Определить, является ли
трисвязной данная система двусторонних дорог.
17. Из заданных n предметов выбрать такие, чтобы суммарный вес был менее 30
кг, а стоимость - наибольшей. Напечатать суммарную стоимость выбранных
предметов. Указание. Определим дерево вариантов следующим образом: На
очередном ходе i=1, 2,..., n будем рассматривать предмет с номером i, а
вариантов j хода i всегда будет два: j=0 означает брать предмет, j=1 означает
не брать его. Получится двоичное дерево, все ветви которого имеют длину n.
При рассмотрении вариантов важно прекращать перебор, как только станет
Этот вариант
выполнить.
ясно, что он не представляет интереса. При движении вперед мы пытаемся
добавить предмет (если вес меньше 30). В этом случае мы идем по левой
ветке. Если же предмет добавить нельзя, то мы его не берем (т. е. движемся
по правой ветке, отбрасывая все дерево вариантов, идущих влево). В обоих
случаях продолжаем двигаться вперед пока не будет рассмотрен последний
предмет. Если все предметы рассмотрены, то вариант получен. Он
сравнивается со стоимостью и начинается движение назад и т. д.
18. На одной из клеток шахматной доски стоит конь. Составить программу,
выполняющую обход конем шахматной доски. Ни одну из клеток конь не
может проходить дважды, но на каждой клетке он обязан побывать. Выдать
сообщение, если обхода не существует.
19. Найти кратчайший путь передвижения коня по шахматной доске,
соединяющий два заданных поля доски или выдать информацию об
отсутствии пути.
20. Найти кратчайший путь передвижения слона по шахматной доске,
соединяющий два заданных поля доски.
21. Найти кратчайший путь передвижения ферзя по шахматной доске,
соединяющий два заданных поля доски.
22. Для любого заданного конечного множества выдать множество всех его
подмножеств.
23. В файле находится безошибочная запись арифметического выражения в
инфиксной форме. Получить префиксную и постфиксную формы этого
выражения и вычислить его значение.
24. В файле находится безошибочная запись арифметического выражения в
инфиксной форме. Без преобразования в постфиксную форму этого
выражения вычислить его значение.
25. Задан лабиринт, составленный из комнат, у каждой из которых имеется не
менее одной и не более трех дверей, соединяющих между собой различные
комнаты. Одна из дверей называется входом в лабиринт, другая - выходом.
Найти кратчайший путь от входа в лабиринт к его выходу.
26. Лабиринт задан массивом a(n*n), в котором элемент a(k,m)=0, если клетка
(k,m) «проходима», и a(k,m)=1, если клетка (k,m) «непроходима».Начальное
положение путника задано в «проходимой» клетке (i,j). Путник может
перемещаться по проходимым клеткам, имеющим общую сторону. Путник
выходит из лабиринта, когда попадает в граничную клетку( т.е. в клетку
(k,m),где k или m равны 1 или n. Выяснить, может ли путник выйти из
лабиринта. Если да - распечатать путь.
27. Проверить, является ли заданная логическая формула правильной ДНФ.
28. Построить синтаксический анализатор для первого способа определения
понятия логическая формула.
29. Построить синтаксический анализатор для понятия ДНФ (дизъюнктивная
нормальная форма)
30. Проверить, является ли заданная ДНФ совершенной.
31. Вычислить значение заданной логической формулы, не содержащей
переменных.
32. Вычислить значение заданной ДНФ для заданных значений входящих в нее
переменных.
33. Заданную логическую формулу преобразовать в эквивалентную ДНФ.
Теоретические сведения
Основные понятия, используемые в заданиях и рекомендуемые алгоритмы.
Граф задается множеством вершин Х={х1, х2, ..., хn} и множеством ребер А = {a1, a2, ...,am}
и обозначается как G(X,A). Между вершинами и ребрами определено отношение
инцидентности, причем каждое ребро инцидентно ровно двум вершинам, другими
словами, каждое ребро соединяет две вершины, эти две вершины называются
смежными. Ребра, инцидентные одной и той же вершине, также называются смежными.
Степень вершины равна числу ребер, инцидентных ей. Список степеней вершин графа
называют его степенной последовательностью.
Рисунок 1 - Пример графа
На рис.1. приведен пример графа. В этом графе шесть вершин и семь ребер, степень
вершин 1-4 равна трем, а вершин 5-6 равна единице.
Часть графа G =(X, A) - это такой граф G’=(X’, A’), что X
XиA
A. Подграфом графа
G=(X,A) называется такая его часть G’, которая вместе со всякой парой вершин u, v
содержит и ребро, их соединяющее, если только оно есть в G.
Например, граф без ребер 1 2 3
является частью графа G (рис.1.), но не его подграфом;
граф
является подграфом графа G. Множество вершин графа называется независимым, если
никакие две вершины из этого множества не смежны (т.е. подграф, порожденный этим
множеством вершин, является пустым). Множество вершин графа называется кликой,
если любые две входящие в него вершины смежны.
Если граф ориентированный (его называют кратко орграф), то ребра называют дугами.
Описание орграфа: Дано множество вершин Х и правило Г, которое показывает, как эти
вершины между собой связаны. Соответствие Г задает отображение множества X в X, а
граф обозначается G=(X,Г).
Г(х2)={х1,х3}
Г(х3)={х1}
Г(х4
Г(х5)={х4}, т.е. Г(хi) - множество таких вершин хj
дуга (хi,хj). Г-1(хi) - множество вершин хk для которых в G существует дуга (хk,хi)
называется обратным соответствием. Для неориентированных графов Г -1(хi) = Г(хi) для
всех хi
Изображение графов. При изображении графов важно лишь то, что каждое ребро
соединяет какие-либо две из заданных точек. Ребро можно изображать отрезками
прямых или криволинейными дугами, длины этих линий и другие геометрические
характеристики несущественны. Линии, изображающие ребра графа, могут пересекаться,
но точки пересечения не являются вершинами. Ребро может соединять некоторую
вершину саму с собой, такое ребро называется петлей.
Применение графов. Особенно часто графы используют при анализе функционирования
систем. С отдельными компонентами изучаемой системы удобно связывать вершины
графа, а с парой взаимодействующих компонент - его ребра. Построенный таким образом
граф называют структурным графом системы.
Маршрутом в графе называется такая последовательность ребер (аi, aj, ..., an), что
каждые два соседние ребра имеют общую инцидентную вершину. Одно и то же ребро
может встречаться в маршруте несколько раз. Вершины, инцидентные ребрам маршрута,
кроме начальной и конечной называются внутренними или промежуточными. Пусть
маршрут (аi, aj, ..., an) имеет начало х0 и конец хn. Тогда его называют соединяющим
вершины х0 и хn. Число ребер маршрута называют его длиной. Любой отрезок маршрута
М сам является маршрутом. Он называется участком маршрута М.
Расстояние между двумя вершинами - это длина кратчайшего пути, соединяющего эти
вершины.
Связные компоненты графа. Вершины хi, хj графа G называются связанными, если
существует маршрут М с началом в хi и концом в хj. Отношение связанности вершин
определяет разбиение множества вершин графа на непересекающиеся подмножества.
Вершины одного и того же подмножества связаны друг с другом, а вершины различных
подмножеств не связаны между собой. Граф G называется связным, если все его
вершины связаны между собой. Поэтому все подграфы графа G связны и называются
связными компонентами рассматриваемого графа. Мостом графа называется такое
ребро, удаление которого увеличивает число компонент связности графа.
Цепи и циклы. Если х0=хn, маршрут называют циклическим. Маршрут называется
цепью, если каждое ребро встречается в нем не более одного раза, и простой цепью,
если любая вершина графа G инцидентна не более чем двум ее ребрам. Циклический
маршрут называют циклом, если он является цепью, и простым циклом, когда это
простая цепь. Участок цепи или цикла является цепью, а участок простой цепи или
простого цикла - простой цепью. Эйлер обратился к общей задаче, касающейся графов: в
каких случаях в конечном графе можно найти такой цикл, в котором каждое ребро графа
участвовало бы один раз? Граф, который можно обрисовать, не прерывая и не повторяя
ребер, называют уникурсальным. Граф уникурсальный тогда и только тогда, когда число
вершин, степени которых нечетны, не более двух.
Теорема. Связный граф, степени всех вершин которого четны, обладает эйлеровым
циклом.
Гамильтоновы циклы определяются для конечных связных графов аналогичным
образом, но только по отношению к вершинам: простой цикл называется
гамильтоновым, если он проходит через каждую вершину графа
Типы графов. Граф G=(Х,А) называется полным, если для любой пары хi и хj Х
существует ребро (хi,xj). Полный неориентированный граф, построенный на n вершинах
обозначается Кn .
Рисунок 2 - Граф К5
Для произвольного графа G=(Х,А) определим дополнительный граф (или дополнение)
принято обозначать его G. Этот граф будет содержать ребра, без которых исходный граф
нельзя считать полным. Пример графа и его дополнения смотрите на рис.3.
Рисунок 3
Теорема. Множество вершин графа является кликой тогда и только тогда, когда оно
независимо в дополнительном графе. Граф G=(Х, А) называется симметричным, если
для любого ребра (хi, xj) существует ребро (xj,xi). Граф G=(Х,А) называется
антисимметричным, если для любого ребра (хi,xj
j,xi
Очевидно, что в антисимметричном графе нет петель. Неориентированный граф
называется двудольным, если множество Х его вершин может быть разбито на Ха и Хв
так, что каждое ребро имеет один конец в Ха, а другой в Хв. Если при этом любые две
вершины, входящие в разные доли, смежны, то граф называется полным двудольным.
Полный двудольный граф, доли которого состоят из p и из q вершин, обозначается
символом Kp,q.
Задача о трех домах и трех колодцах. Имеются три дома 1,2,3 и три колодца 4,5,6.
Каждый хозяин пользуется любым из трех колодцев. В некоторый момент обитатели
домов решили проложить дорожки до колодцев так, чтобы исключить встречи на
дорожках, т.е. чтобы дорожки не пересекались. Оказалось, что все попытки нарисовать
девять непересекающихся дорожек заканчиваются неудачей.
Рисунок 4 - Двудольный граф К3,3
Теорема. Граф является двудольным тогда и только тогда, когда он не содержит циклов
нечетной длины.
Мультиграфом называется граф, в котором пара вершин соединяется несколькими
различными ребрами (дугами). Граф G=(Х,А) называется плоским, если он может быть
нарисован на плоскости таким образом, чтобы произвольные две дуги графа не
пересекались друг с другом. Существует утверждение, что почти все графы не являются
плоскими.
Теорема Понтрягина-Куратовского. Граф плоский тогда и только тогда, когда он не
содержит подграфов К5 или К3,3.
Грани плоского графа. Гранью плоского графа называется часть плоскости, каждая пара
точек которой может быть соединена жордановой кривой, не пересекающей ребра графа.
Границей грани будем считать множество ребер, принадлежащих этой грани. Эти ребра
образуют цикл, называемый минимальным циклом. На графе имеется еще и
максимальный цикл С1, окружающий весь граф со всеми его гранями. Если
рассматривать часть плоскости, лежащую вне С1, тоже как грань графа с границей С1, то
получим единственную неограниченную грань. Проиллюстрируем все это на графе рис.5.
Рисунок 5 - Грани плоского графа
Это граф с 10 гранями, занумерованными числами от I до Х. Грань I, например, имеет в
качестве границы цикл, состоящий из ребер (1,2), (2,11), (11,10), (10,1), а грань VIII
ограничена только двумя ребрами, соединяющими вершины 10 и 12. Ребра
максимального цикла С1 проходят по всем вершинам от 1 до 10 по порядку, а затем
возвращаются назад к 1. Неограниченная грань X представляет собой совокупность всех
точек, лежащих вне С1. Обозначим через n, m, и f - соответственно число вершин, ребер и
граней плоского графа.
Теорема Эйлера. Для всякого связного плоского графа верно равенство n - m + f =.2.
Другими словами, число f не зависит от способа укладки (n, m) – графа на плоскости.
Деревом называется связный граф без циклов.
Корневое дерево - это связный орграф без циклов, удовлетворяющий условиям:
1) имеется единственная вершина, называемая корнем, в которую не входит ни одна
дуга;
2) к каждой некорневой вершине ведет ровно одна дуга.
Вершины, из которых не выходит ни одна дуга, называются листьями.
Система дорог - это размеченный мультиграф, в котором вершины соответствуют
городам, а ребра - дорогам. Односторонним дорогам соответствуют дуги, а двусторонним
- ребра. Каждой дороге приписано некоторое положительное число - длина дороги. Граф,
у которого каждой дуге приписано некоторое значение, называется взвешенным графом
(или сетью). Источник орграфа - это вершина, от которой достижимы все остальные
вершины. Сток орграфа - это вершина, достижимая со всех других вершин.
Матрицы, ассоциированные с графом.
Матрица, каждый элемент которой равен нулю или единице, называется бинарной.
Пусть G=(Х,А) - граф с n вершинами (Х={1,2,...,n}). Определим бинарную матрицу B=B(G)
размера n*n, положив
B(G) называется матрицей смежности графа G. Это симметричная матрица с нулями на
диагонали. Число единиц в строке равно степени соответствующей вершины.
Аналогично определяется матрица инцидентности. Пусть G=(n,m) - граф, т.е. граф с n
вершинами (X={1,...,n}) и m ребрами A={а1,...,аm}. Определим бинарную n*m матрицу
I=I(G) следующим образом:
Матрица I называется матрицей инцидентности графа G. В каждом ее столбце ровно
две единицы, равных столбцов нет.
Для ориентированных графов определение матрицы инцидентности видоизменяется:
Для компьютерного представления графов вместо матриц часто лучше использовать
список ребер. Для описания каждого ребра требуется по две ячейки памяти (по одной на
каждую концевую вершину ребра).
Во многих случаях лучшим решением оказывается представление графа с помощью
однонаправленных списков инцидентности: каждой вершине ставится в соответствие
список вершин, смежных с ней. Выбор того или иного способа задания графа зависит от
конкретной решаемой задачи.
Утверждения
Графы (орграфы) изоморфны тогда и только тогда, когда их матрицы инцидентности
получаются друг из друга произвольными перестановками строк и столбцов.
Графы (орграфы) изоморфны тогда и только тогда, когда их матрицы смежности
получаются друг из друга одинаковыми перестановками строк и столбцов.
Алгоритмы
Алгоритм распознавания двудольности графа (основан на алгоритме «поиска в
ширину»)
Начинаем с произвольной вершины и припишем ей номер 0; каждой вершине из
окружения данной вершины припишем номер 1; рассмотрим теперь поочередно
окружения всех вершин с номерами 1 и каждой из входящих в эти окружения вершин, еще
не занумерованных, припишем номер 2; продолжая подобным образом, занумеруем все
вершины (если граф связен). Отнесем ко множеству М все вершины с четными номерами,
а ко множеству К - остальные и рассмотрим порожденные подграфы G(M) и G(K); если
они пусты (достаточно проверить, что все пары вершин с равными номерами не смежны),
то граф двудольный; в противном случае - нет.
Алгоритм Флери нахождения эйлерова цикла в графе. Начав с любой вершины u,
присвоим каждому ребру (u,v) номер 1; вычеркнем это ребро и перейдем в вершину v;
пусть в результате выполнения предыдущего шага мы присвоили некоторому ребру
номер k и перешли к вершине w; выберем произвольное ребро, инцидентное этой
вершине (причем, мост выберем только тогда, когда других возможностей нет); присвоим
этому ребру номер k+1 и вычеркнем его; процесс закончится, когда все ребра графа
будут вычеркнуты (т.е. занумерованы).
Обходы дерева в глубину и в ширину
Обход дерева в глубину. При обходе дерева в глубину, вершины дерева посещаются в
соответствии со следующей рекурсивной процедурой: сначала посетить корень дерева;
затем, если корень рассматриваемого дерева не является листом, то сначала для левого,
а затем для правого потомка рекурсивно обратиться к процедуре обхода в глубину.
Например, для дерева, показанного на рис.6 ,вершины будут проходиться в следующем
порядке: A, B, C, D, E, F, K, L, J, H, I.
Рисунок 6
Если использовать стек S для хранения текущего пути по дереву, т.e. пути, который
начинается в корне дерева и кончается в вершине, посещаемой в данный момент, то
можно построить нерекурсивный алгоритм для обхода дерева в глубину:
Создать пустой стек S.
Посетить корень дерева и поместить его в пустой стек S.
WHILE Стек S не пуст
DO BEGIN
Пусть p -вершина, находящаяся на верху стека S;
IF Сыновья вершины p еще не посещались
THEN Посетить старшего сына вершины p и поместить его в стек S
ELSE BEGIN
Удалить вершину p из стека S;
IF p имеет братьев
THEN Посетить брата вершины p и поместить его в стек S
END
END
Обход дерева в ширину. Способ обхода дерева в ширину осуществляет посещение
вершин дерева слева направо, уровень за уровнем вниз от корня. Таким образом, при
обходе в ширину изображенного на рис. 6 дерева вершины будут проходиться в
следующем порядке: A, B, H, C, D, I, E, J,F, K, L.
Алгоритм для обхода дерева в ширину.
Создать пустую очередь Q. Поместить в нее корень дерева.
WHILE очередь Q не пуста
DO BEGIN
Выбрать из очереди Q первую вершину, обработать ее, а всех ее сыновей поместить в
очередь. END
Обход графа в глубину. Модифицируем алгоритм обхода бинарного дерева в глубину
таким образом, чтобы его можно было использовать для систематического обхода всех
вершин произвольного графа. Предположим, что зафиксирован некоторый линейный
порядок на множестве всех вершин графа и что множество вершин, смежных со всякой
вершиной графа, также линейно упорядочено:
while Имеется хотя бы одна непосещенная вершина
do begin
Пусть p – первая (т.е. минимальная) из непосещенных вершин;
Посетить вершину p и поместить ее в пустой стек S;
while стек S не пуст
do begin
Пусть p -вершина, находящаяся на вершине стека S;
if У вершины p есть непосещенные смежные вершины
then begin
Пусть q - первая непосещенная вершина из вершин, смежных вершине p;
Пройти по ребру (p,q),посетить вершину q и поместить ее в стек S
end
else
Удалить вершину p из стека S
end
end
В результате работы алгоритма пройденные ребра графа образуют вместе с
посещенными вершинами одно или несколько деревьев. Если приписать пройденным
ребрам ориентацию в соответствии с тем направлением, в каком они проходятся при
выполнении алгоритма, то мы получим совокупность корневых деревьев, причем их
корнями будут служить все те вершины, которые в процессе работы алгоритма
помещались в пустой стек.
Исчерпывающий поиск в конечном множестве. Во многих задачах, формулируемых в
виде вопросов» сколько существует способов...», «определить, есть ли способ...» и т.д.
требуется осуществить исчерпывающий поиск в конечном множестве всех возможных
решений.
Поиск с возвращением. Рассмотрим общий случай, когда решение задачи имеет вид
вектора (a1,a2,...), длина которого не определена, но ограничена сверху некоторым
(известным или неизвестным) числом r, а каждое ai является элементом некоторого
конечного линейно упорядоченного множества Ai. Таким образом, при исчерпывающем
поиске в качестве возможных решений мы рассматриваем элементы множеств
A1xA2x...xAi
ограничениям, определяющим решение задачи. В качестве начального частичного
решения берется пустой вектор ( ) и на основе имеющихся ограничений выясняется,
какие элементы из A1 являются кандидатами для их рассмотрения в качестве a1
(множество таких элементов обозначим S1).В качестве a1 выбирается наименьший
элемент множества S1, что приводит к частичному решению (a1). В общем случае
ограничения, описывающие решение, говорят о том, из какого подмножества Sk
множества Ak выбираются кандидаты для расширения частичного решения от (a1,a2,...,ak1) до (a1,a2,...,ak). Если частичное решение (a1,a2,...,ak-1) не предоставляет других
возможностей для выбора нового ak (т.е. у частичного решения (a1,a2,...,ak-1) либо нет
кандидатов для расширения, либо все кандидаты к данному моменту уже использованы),
то происходит возврат и осуществляется выбор нового элемента a k-1 из Sk-1. Если новый
элемент ak-1 выбрать нельзя, т.е. к данному моменту множество Sk-1 уже пусто, то
происходит еще один возврат и делается попытка выбрать новый элемент ak-2 и т.д.
Процесс поиска с возвращением удобно описывать в терминах обхода в глубину дерева
поиска, которое строится следующим образом. Корень дерева поиска (нулевой уровень)
соответствует пустому вектору, являющемуся начальным частичным решением. Для
-го уровня, являющиеся сыновьями некоторой вершины p,
соответствуют частичным решениям) (a1,a2,...,ak-1,ak), где (a1,a2,...,ak-1) – это то частичное
решение, которое соответствует вершине p, а ak k; при этом упорядоченность сыновей
вершины p отражает упорядоченность соответствующих элементов ak в Sk.
Метод ветвей и границ. Использование анализа с целью сокращения множества
возможных решений называется поиском с ограничениями или с отсечениями ветвей. В
методе ветвей и границ ограничения основываются на предположении, что на множестве
возможных и частичных решений задана некоторая функция цены и что нужно найти
оптимальное решение, т.е. решение с наименьшей ценой. Функция цены должна
обладать тем свойством, что цена любого частичного решения не превышает цены
любого расширения этого частичного решения. Это свойство позволяет отбрасывать
любое частичное решение в процессе поиска, если его цена больше цены ранее
вычисленного решения.
Алгоритм поиска:
минимум := бесконечность{*максимальное представимое число*};
k:=1;
Вычислить S1;
WHILE k>0 DO BEGIN WHILE (Не пусто Sk) AND (цена < минимум)
DO BEGIN {*Продвижение*}
В качестве ak взять наименьший элемент из Sk, удалив его из Sk;
цена:=ЦЕНА(a1,a2,...,ak-1,ak);
IF (a1,a2,...,ak-1,ak) является решением AND(цена < минимум)
THEN BEGIN
минимум:=цена;
Хранить далее (a1,a2,...,ak-1,ak),как решение с наименьшей ценой
END;
IF k < r
THEN BEGIN k:=k+1; Вычислить Sk;
END;
END; {*Возврат*}
k:=k-1;
Цена:=ЦЕНА(a1,a2,...,ak-1,ak);
END;
При применении метода ветвей и границ рекомендуется использовать технику
перестройки дерева поиска, с тем чтобы решения, близкие к оптимальному, находились
на ранних этапах поиска.
Порождение комбинаторных объектов. Порождение комбинаторных объектов
основывается на поиске с возвращением. Однако, во многих случаях порождаемые
объекты настолько просты, что целесообразно применять специальные приемы, один из
которых состоит из трех компонент: построения начального объекта, преобразования
текущего объекта в следующий и условия окончания. Для многих классов комбинаторных
объектов удается найти так называемый порядок минимального изменения,
минимизирующий объем работы по переходу от текущего элемента к соседнему.
В качестве примера рассмотрим порождение сочетаний из n элементов по k. Будем
представлять сочетания в виде вектора C=(c1,c2,...ck), где ci < ci+1 для любого i.
Начинается порождение с сочетания (1,2,...,k). Каждое следующее сочетание строится из
предыдущего с помощью таких действий: в ходе просмотра текущего сочетания справа
налево в нем находится самый первый элемент, который еще не достиг своего
максимального значения; этот элемент увеличивается на единицу, а всем элементам
справа от него последовательно присваиваются новые наименьшие возможные значения.
Пример: Сочетания из шести по три:
((123),(124),(125),(126)),((134),(135),(136)),((145),(146)),((156)),((234),(235),(236)),((245),(246
)),((256)),((345),(346)),((356)), ((456)).
Другим примером может служить процесс построения перестановок из n элементов. Если
n > 1 то из последовательности перестановок П1, П2,..., Пr, для множества 1,2,...,n-1
строится последовательность перестановок для n элементов за счет расширения каждой
из (n-1)! Перестановок Пi вставкой элемента n на каждое из n возможных мест
(«промежутков» между элементами Пi), справа налево при нечетном i или слева направо
при четном i. Порождение всех подмножеств множества [a 1, a2,... , an] можно свести к
порождению всех n-разрядных двоичных наборов, а именно: ai принадлежит
подмножеству тогда и только тогда, когда i-й разряд набора равен единице.
Управление с помощью таблицы решений. Реализацию этого алгоритма покажем на
примере вычисления арифметического выражения. На этом примере покажем технику
синтаксического разбора (расчленения выражения на отдельные элементы),
преобразование строк символов в значения, а также применение таблиц решений,
нередко встречающемся в системном программировании. При чтении текстового
выражения каждому виду элементов присвоим целый код:
Элементы выражения:
Символ
Код
Конец строки
0
(
1
+
2
3
*
4
/
5
)
6
цифра (из отдельных цифр 7
собирается
число
и
присваивается код 7)
.
8
пробел
9 (игнорируется)
прочее
20 (признак ошибки)
Программа должна быть способна откладывать выполнение некоторых операций до тех
пор, пока оно не будет разрешено правилами приоритетов операций. Это реализуется с
помощью стеков и таблицы переходов. Один стек будет служить для хранения операций,
которые ввиду правил приоритетов не могут быть исполнены при их обнаружении. В
другом стеке будут храниться промежуточные результаты (стек результатов). Если
обнаруженный при сканировании выражения элемент является числом, то он заносится в
стек результатов. Если элемент является операцией, то эта операция сопоставляется с
предыдущей, находящейся на вершине стека операций. В зависимости от их приоритетов
следует выполнить одно из следующих четырех действий:
1. Поместить новую операцию в стек и перейти к сканированию нового элемента.
2. Извлечь верхнюю операцию из стека операций. Извлечь два верхних числа из стека
результатов. Выполнить над ними извлеченную операцию. Поместить результат в стек
результатов. Поместить новую операцию в стек операций и перейти к сканированию
нового элемента. 3.Извлечь верхнюю операцию из стека операций и продолжать
сканирование (это действие используется для удаления скобок). 4.Извлечь верхнюю
операцию из стека операций. Извлечь два верхних числа из стека результатов.
Выполнить над ними извлеченную операцию, поместив результат в стек результатов.
Вместо продолжения сканирования, повторить одно из четырех действий, используя тот
же текущий элемент и новую верхнюю операцию из стека операций. Закодируем эти
решения в виде таблицы решений и будем из нее выбирать требуемые действия.
Пример: Вычислить 40*6+10*9.
Упрощение логических формул.
Язык записи логических формул.
Существует несколько способов записи логических формул:
1-ый способ:
2-й способ задания логических формул - их запись в виде дизъюнктивных нормальных
форм (ДНФ)
ДНФ называется правильной, если для каждой ее элементарной конъюнкции выполнено
следующее условие: все буквы переменных, встречающиеся в этой элементарной
конъюнкции, различны (ХУ -правильная ДНФ, а X NOT X - неправильная ДНФ).
Правильная ДНФ называется совершенной ДНФ (СДНФ), если каждая элементарная
конъюнкция содержит все переменные ДНФ.
Для представления логических формул на языке Паскаль предлагается использовать
древовидную структуру, однако вершины этого дерева - вариантные записи:
Предполагаем, что в текстовом файле написано несколько формул, разделенных между
собой запятыми. Если в записи формулы встречаются ошибки, ее упрощение
оказывается невозможным. Надо напечатать соответствующее сообщение об ошибке,
пропустить все символы ошибочной формулы и так продолжать до конца файла.
Для считывания формул введем понятие лексема. Под лексемой будем понимать всякую
последовательность
символов,
начинающуюся(
возможно
пустой)
подпоследовательностью пробелов и заканчивающуюся
1) либо символом, отличным от буквы,
2) либо непустой последовательностью не более чем из шести букв и следующим за ней
пробелом.
В случае 1) - это могут быть символы (запятая, круглые скобки). Если другие символы, то
это признак ошибки в формуле.
В случае 2) - это могут быть переменные, операции NOT, AND, OR, константы TRUE,
FALSE, а также другие последовательности, которые являются ошибочными. Надо
считывать по одной лексеме, распечатывать ее для контроля ввода и классифицировать
ее.
Литература
1.В.В. Подбельский, С. С. Фомин «Программирование на языке Си». М., «Финан-сы и
статистика», 2005.
2. В. В. Подбельский «Язык Си++». М., «Финансы и статистика», 2005.
3. Т. А. Павловская «С/С++. Программирование на языке высокого уровня». СПб., Питер,
2005.
4. А. Ахо, Д. Хопкрофт, Д. Ульман «Структуры данных и алгоритмы». М., изд. Вильямс,
2003.
5. Б. Керниган, Д. Риччи «Язык программирования Си». М., 1992.
6. А.В.Крячков, И.В.Сухинина, В.К. Томшин, Программирование на С и С++, практикум ,
изд-во Радио и связь,1997
7. Касьянов В. Н., Сабельфельд В. К., Сборник заданий по практикуму на ЭВМ. М.: Наука,
1986.
8. Вирт Н., Алгоритмы + структуры данных = программы. М.: Мир, 1985.
9. Кнут Д., Искусство программирования для ЭВМ. Т1 Основные алгоритмы. М.: Мир,
1976.
10. Гудман С., Хидетнтеми С., Введение в разработку и анализ алгоритмов. М.: Мир 1981
Download