Uploaded by ppcmiha

3.2 МУ к практическим занятиям ДМ

advertisement
Министерство образования и науки Российской Федерации
Федеральное Государственное Бюджетное Образовательное Учреждение
Высшего Профессионального Образования
«КУБАНСКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНОЛОГИЧЕСКИЙ
УНИВЕРСИТЕТ»
(КубГТУ)
Кафедра компьютерных технологий и информационной безопасности
ВЫПОЛНЕНИЕ ПРАКТИЧЕСКИХ ЗАДАНИЙ
Методические указания по выполнению практических заданий по
дисциплине «Дискретная математика» для студентов дневной формы
обучения по направлению подготовки
090900.62 – Информационная
безопасность
Краснодар
2014
Составитель: канд. техн. наук, Т.Т. Зангиев
Дискретная математика: методические рекомендации по выполнению
практических заданий для студентов очной формы обучения направления
090900.62 Информационная безопасность/ Сост.: Т.Т. Зангиев; Кубан. гос.
технол. ун-т. Каф. компьютерных технологий и информационной
безопасности. – Краснодар: 2014.-129 с.
Методические указания предназначены для выполнения практических
работ по дисциплине «Дискретная математика » для студентов дневной
формы обучения по направлению подготовки 090900.62 – Информационная
безопасность.
В методических указаниях приведена методика проведения
практических занятий по дисциплине «Дискретная математика». Содержание
практической работы включает в себя основной теоретический материал,
цели и задачи данного задания, варианты заданий, указания для выполнения
заданий и примеры решение основных типовых задач.
2
Содержание
1.
Тема. Множества и отношения. Практическое задание №1
Операции над множествами.
4
2. Тема. Основы теории графов. Практическое задание №2 Задание
графов, матрицы инцидентности и смежности.
16
3.
Тема. Основы теории графов.. Практическое задание №3
Определение изоморфности графов
32
4.
Тема. Основы теории графов. Практическое задание №4
Кратчайший путь в графе.
43
5.
Тема. Основы теории графов. Практическое задание №5
Построение графа наименьшей длины.
60
6.
Тема. Сети и потоки. Практическое задание №6 Максимальный
поток в сети.
75
7.
Тема. Сети и потоки. Практическое задание №7 Максимальные
паросочетания.
90
8.
Тема. Конечные автоматы. Практическое задание №8 Решение
задач на эмуляторе машины Поста
100
9.
Тема. Конечные автоматы. Практическое задание №9 Решение
задач на эмуляторе машины Тьюринга
107
10.
Тема. Конечные автоматы. Практическое задание №10
Построение минимальных автоматов
114
3
Тема. Множества и отношения. Практическое занятие №1 Операции
над множествами.
1.ОБЩИЕ СВЕДЕНИЯ
1.1.Основные определения Понятие множества является одним из тех
фундаментальных понятий
математики, которым трудно дать четкое определение, используя
элементарные понятия. Поэтому мы ограничимся описательным
объяснением понятия множества. Множеством называется совокупность
определенных вполне различаемых объектов, рассматриваемых как единое
целое.
Можно говорить о множестве стульев в комнате, множестве людей, живущих
в г. Краснодаре, множестве студентов в группе, множестве натуральных
чисел, множестве букв в алфавите, множестве состояний системы и т.п. При
этом о множестве можно вести речь только тогда, когда элементы множества
различимы между собой. Например, нельзя говорить о множестве капель в
стакане воды, так как невозможно четко и ясно указать каждую отдельную
каплю.
Отдельные объекты, из которых состоит множество, называются
элементами множества. Так, число 3–элемент множества натуральных
чисел, а буква б–элемент множества букв русского алфавита.
Множества бывают конечными и бесконечными. Множество называется
конечным, если число его элементов конечно, т. е. если существует
натуральное число N, являющееся числом элементов множества. Множество
называется бесконечным, если оно содержит бесконечное число элементов
соответственно.
Для того чтобы оперировать с конкретными множествами, нужно уметь их
задавать.
Существует два способа задания множеств: перечисление и
описание.Задание множества способом перечисления соответствует
перечислению всех элементов, составляющих множество. Так, множество
отличников группы можно задать, перечислив студентов, которые учатся на
отлично, например {Иванов, Петров, Сидоров}. Такой способ удобен при
рассмотрении конечных множеств, содержащих небольшое число элементов,
но иногда он может применяться и для задания бесконечных множеств,
например {2, 4, 6, 8 ...}. Естественно, что такая запись применима, если
вполне ясно, что понимается под многоточием.
Описательный способ задания множества состоит в том, что указывается
характерное свойство, которым обладают все элементы множества. Так, если
М–множество студентов группы, то множество А отличников этой группы
запишется в виде
А ={XМ: X — отличник группы},
4
что читается следующим образом: множество А состоит из элементов X
множества М, обладающих тем свойством, что X является отличником
группы.
В тех случаях, когда не вызывает сомнений, из какого множества берутся
элементы X, указание о принадлежности X множеству М можно не делать.
При этом множество А запишется в виде А={X: X—отличник группы}.
Приведем несколько примеров задания множеств методом описания:
{X : X — четное} — множество четных чисел;
{X : X2–1 =0} — множество {+ 1, –1}.
Пусть С–множество целых чисел. Тогда {XС:0<X<=7) есть множество {1,
2, 3, 4, 5, 6, 7}
Важным понятием теории множеств является понятие пустого множества.
Пустым множеством называется множество, не содержащее ни одного
элемента. Пустое множество обозначается 0. Пустое множество будем
условно относить к конечным множествам.
Рассмотрим теперь вопрос о равенстве множеств. Два множества называются
равными, если они состоят из одних и тех же элементов, т. е. представляют
собой одно и то же множество. Множества Х и Y не равны, если либо в
множестве Х есть элементы, не принадлежащие Y, либо в множестве Y есть
элементы, не принадлежащие X. Легко видеть, что для любых множеств X, Y
и Z:
Х=Х;
если X=Y, то Y=X;
если X=Y и Y=Z, то X=Z.
Из определения равенства множеств вытекает, что порядок элементов в
множестве несуществен. Так, например, множества {3, 4, 5, 6} и {4, 5, 6, 3}
представляют собой одно и то же множество.
При рассмотрении различных множеств часто приходится говорить о числе
элементов множества. Для того чтобы это понятие было 'вполне
определенным, нужно условиться, что в множестве не бывает одинаковых
элементов.
Запись {2, 2, 3, 5} следует рассматривать как некорректную и заменить ее на
{2, 3, 5}. Так множество простых делителей числа 60 равно {2, 3, 5}.
1.2.Понятие подмножества
Множество Х является подмножеством множества Y, если любой элемент
множества Х принадлежит и множеству Y. Пусть Y—множество студентов
группы, а Х—множество отличников той же группы. Так как каждый
отличник группы является в то же время студентом этой группы, то
множество Х является подмножеством множества Y.
Над множествами можно производить действия, которые во многом
напоминают действия сложения и умножения в элементарной алгебре.
1.3.Объединение множеств
5
Объединением множеств Х и Y называется множество, состоящее из всех тех
и только тех элементов, которые принадлежат хотя бы одному из множеств
X, Y, т. е. принадлежат Х или принадлежат Y(обозначается через
Х  Y)(рис. 1).
Пусть имеется два множества: М1 с элементами {a, b, c, d} и М2 с элементами
{b, c, e, p}. Объединением множеств М1 и М2 является множество M3,
элементами которого будут как элементы множества М1, так и М2. В
дальнейшем будем писать: М1={a, b, c, d}, М2={b, c, e, p},
M3= М1 М2={a, b, c, d, e, p}.
В общем виде результат объединения множеств А и В записывается так:
А x|x А или x В}.
Пример 1. Если Х={1, 2, 3. 4. 5} и Y={2. 4, 6, 7}, то XY = {1, 2, 3, 4, 5, 6, 7}.
Пример 2. Если X–множество отличников в группе, а Y–множество
студентов, проживающих в общежитии, то XY–множество студентов,
которые или учатся на отлично или проживают в общежитии.
Пример 3. Рассмотрим два круга, приведенных на рисунке. Если Х–
множество точек левого круга, а Y–множество точек правого круга, то X Y
представляет собой заштрихованную область, ограниченную обоими
кругами.
Рис 1. Объединение множеств
6
Понятие объединения можно распространить и на большее число множеств.
Обозначим через ={X1,... ...,Хn} совокупность n множеств X1,...,Xn,
называемую иногда системой множеств. Объединение этих множеств
представляет собой множество, состоящее из всех тех и только тех
элементов, которые принадлежат хотя бы одному из множеств системы .
Для объединения множеств справедливы коммутативный и ассоциативный
законы
XY=YX;
(XY)  Z=X (Y Z)=X Y Z,
справедливость которых вытекает из того, что левая и правая части равенств
состоят из одних и тех же элементов. Далее
X0=X
Это также очевидное соотношение, так как пустое множество не содержит
элементов, а значит Х и Х  0 состоят из одних и тех же элементов. Видно,
что пустое множество 0 играет роль нуля в алгебре множеств.
1.4.Пересечение множеств
Пересечением множеств (рис. 2) Х и Y называется множество, состоящее из
всех тех и только тех элементов, которые принадлежат как множеству X, так
и множеству Y (обозначается через Х  Y).
Пересечением множеств М1 и М2 является множество М4, элементами
которого будут элементы, принадлежащие одновременно как множеству М1,
так и множеству М2. Для предыдущего примера М4= М1 М2={b, c}. В
общем виде результат пересечение множеств А и В записывается так:
А В={x| x А и x В}
Пример 4. Для множества Х и Y в примере 1 X  У={2,4}.
Пример 5. Для множеств Х и Y в примере 2 XY— множество отличников
группы, проживающих в общежитии.
Операция пересечения позволяет установить ряд соотношений между двумя
множествами.
Множества Х и Y называются непересекающимися (рис. 3), если они не
имеют общих элементов, т. е. если
Рис 2. Пересечение множеств
Рис 3. Непересекающиеся
множества XY=0
7
Пример 6. Непересекающимися множествами являются:
1) множества {1, 2, 3} и {4, 5, 6};
2) множество отличников и множество неуспевающих студентов в
группе.
Говорят, что множества Х и Y находятся в общем положении, если
выполняются три условия:
существует элемент множества X, не принадлежащий Y;
существует элемент множества Y, не принадлежащий X;
существует элемент, принадлежащий как X, так и Y.
Понятие пересечения можно распространить и на большее чем два
число множеств. Рассмотрим систему множеств ={X1,...,Xn}. Пересечение
этих множеств представляет собой множество, элементы которого
принадлежат каждому из множеств системы .
Нетрудно видеть, что пересечение множеств обладает коммутативным
свойством
XY=YX
и ассоциативным
(XY) Z=X (Y Z)=X Y Z
Заметим также, что имеет место соотношение Х0=0
1.5.Разность множеств
Разностью множеств А и В называется множество всех тех и только тех
элементов А, которые не содержатся в В. В общем виде разность
обозначается: А/В={x| x А и x ∉ В}.
Рис 4. Разность множеств
Данная операция в отличие от операций объединения и пересечения
определяется только для двух множеств. Разностью множеств Х и Y (рис. 4)
называется множество, состоящее из всех тех и только тех элементов,
которые принадлежат Х и не принадлежат Y (обозначается через Х \ Y).
Пример 7. Для множеств Х и Y примера 1 X\У={1, 3, 5}, Y\X={6, 7}. Если X
и Y—множества из примера 2, то X\У—множество отличников, не
проживающих в общежитии.
2.6.Универсальное множество
8
В алгебре множеств роль единицы играет множество, удовлетворяющее
условию ХI=X
Это соотношение означает, что пересечение или «общая часть»
множества I и множества Х для любого множества Х совпадает с самим этим
множеством. Но это возможно лишь в том случае, если множество I
содержит все элементы, из которых может состоять множество X, так что
любое множество Х полностью содержится в множестве I. Множество I,
удовлетворяющее этому условию, называется полным, или универсальным,
или единичным.
Исходя из сказанного, можно дать следующее определение универсального
множества. Если в некотором рассмотрении участвуют только подмножества
некоторого фиксированного множества I, то это самое большое множество I
называется универсальным множеством.
Следует отметить, что в различных конкретных рассмотрениях роль
универсального множества могут играть различные множества. Так, при
рассмотрении множеств студентов в группе (отличники; студенты,
получающие стипендию: студенты, проживающие в общежитии, и т.п.) роль
универсального множества играет множество студентов в группе.
Универсальное множество удобно изображать графически в виде множества
точек прямоугольника. Отдельные области внутри этого прямоугольника
будут означать различные подмножества универсального множества.
Изображение множеств в виде областей в прямоугольнике, представляющем
универсальное множество, называется диаграммой Эйлера–Венна.
Универсальное множество обладает интересным свойством, которое не имеет
аналогии в обычной алгебре, а именно, для любого множества Х справедливо
соотношение
ХI=I.
Действительно, объединение ХI представляет собой множество, в которое
входят как все элементы множества X, так и все элементы множества I. Но
множество I уже включает в себя все элементы множества X, так что ХI
будет состоять из тех же элементов, что и I, т.е. представляет собой само
универсальное множество I.
1.7.Дополнение множества
Множество ~X, определяемое из соотношения ~X=I\Х,
называется дополнением множества Х (до универсального множества I). На
диаграмме (см.рис.) множество Х представляет собой незаштрихованную
область.
Пример 8. Если I={1, 2, 3, 4, 5, 6, 7} и X={3, 5 7}, то ~X={1,2,4,6}. X и
~X не имеют общих элементов, так что Х~X =0.
9
Рис 5. Дополнение множества
Кроме того, не имеется элементов I, которые не принадлежали бы ни X, ни
~X, так как те элементы, которые не принадлежат X, принадлежат ~X.
Следовательно,
X ~X =I.
Из симметрии этой формулы относительно Х и ~X следует не только то, что
~X является дополнением X, но и что Х является дополнением ~X. Но
дополнение ~X есть ~~X. Таким образом,
~~X =Х
С помощью операции дополнения можно в удобном виде представить
разность множеств
X\Y=X~Y.
1.8 Симметрическая разность
Симметрической разностью множеств X и Y называется множество,
состоящее из всех тех и только тех элементов, которые принадлежат либо
множеству X, либо множеству Y, но не одновременно. Симметрическая
разность обозначается через XY.
Пример 9.Для множеств X и Y в примере 1 XY={1,3,5,6,7}.
Пример 10.Для множеств X и Y в примере 2 XY – множество студентов,
являющихся либо отличниками, либо проживающих в общежитии.
Рис 6. Симметрическая разность множеств.
1.9.Тождества алгебры множеств
С помощью операций объединения, пересечения и дополнения из
множеств можно составлять различные алгебраические выражения.
Обозначим через (X, Y, Z) некоторое алгебраическое выражение,
составленное из множеств X, Y и Z. Оно само представляет собой некоторое
множество. Пусть (X, Y, Z) – другое алгебраическое выражение,
составленное из тех же множеств. Если оба алгебраических выражения
10
представляют собой одно и то же множество, то их можно приравнять друг к
другу, получая алгебраическое тождество вида
(X, Y, Z)=(X, Y, Z).
Такие множества бывают очень полезны при преобразованиях
алгебраических выражений над множествами, и некоторые из них мы
рассмотрим в настоящей работе.
На рисунках 7, 8 приведены диаграммы Эйлера – Венна для выражений
(XY)Z и (ХZ)  (YZ). Из этих диаграмм видно, что оба выражения
определяют одно и то же множество, так что в алгебре множеств имеет место
тождество (XY)Z = (ХZ)  (YZ).
Рис 7, 8. Геометрическая иллюстрация тождества (XY)Z = (ХZ)(YZ).
3.ЗАДАНИЕ
3.1.Вручную доказать тождества, выбранные преподавателем из вариантов
задания.
3.2.Разработать программу, реализующую выполнение операций над
множествами(A,B,C): объединения, пересечения, разности между первым и
вторым, дополнения к первому множеству, симметрической разности. В
качестве универсального множества принять совокупность букв латинского
алфавита.
3.3.Реализовать свой вариант задания на языке программирования.
За универсальное множество принять совокупность букв латинского
алфавита.
11
1. а) A\(BC)=(A\B)  (A\C)
2. A\(BC)=(A\B)  (A\C)
3. A(B\C)=(AB)\(AC)
4. (AB)\C=(A\C)  (B\C)
5. A\(BC)=(A\B)\C
6 A  (BC)=(AB)  C
7. A  (BC)=(AB)  (AC)
8. (AB)C  A(~BC)
9. (AB)C  AС и AС
10. A(BC)  AB A и C
11. AB  AC BC
12. AB  (C\B)  (C\A)
13. (AB)  C=A (BC)  C A
14. A (BC)  (A  ~B ) C
15. A\(BC)=(A\B)  (A\C)
16. A(BC)  AB A и C
17. A\(BC)=(A\B)\C
18. (AB)\C=(A\C)  (B\C)
19. AB  AC BC
20. (AB)  C=A (BC)  C A
б)(A\B)  B=A  BA
AB  (A\C) (B\C)
AB  ~B  ~A
AB =AB  A=B
A=~B  AB=0 и AB=I
(AB)  C=A (BC)  C A
A (BC)  (A  ~B ) C
A\(BC)=(A\B)  (A\C)
AB=A (B\A)
A\ (BC)=(A\B)  (A\C)
A\B= A  (AB)
A  (BC)=(AB)  (AC)
A \ (A\B)= AB
A\(BC)=(A\B)  (A\C)
AB  (A\C) (B\C)
A\ (BC)=(A\B)  (A\C)
A=~B  AB=0 и AB=I
AB =AB  A=B
A\B= A  (AB)
A \ (A\B)= AB
4.МЕТОДИЧЕСКИЕ УКАЗАНИЯ
Примеры доказательства.
1)Доказать тождество:
Доказательство:
2)Доказать тождество:
, где
.
.
Доказательство:
3)Доказать тождество:
Доказательство:
, где
.
Программу на языке программирования Turbo - Pascal рекомендуется
составлять из отдельных процедур, которые затем будут использоваться
в основной программе. Так, в особые процедуры следует выделить ввод
12
и вывод элементов исходных и полученных множеств.
Множество может быть задано в разделе описаний либо константой,
либо в виде блока
......................................
Type
Lat = set of ‘a’..’z’;
Var a,b,c:lat;
......................................
Ввод элементов множества можно организовать следующим образом :
задав перед входом в цикл данное множество пустым, в цикле добавлять
к нему вводимые пользователем с клавиатуры элементы:
............................
a:=[ ];
for i:=1 to n do begin
readln(x);
a:=a+[x]
end;
............................
где x – вводимый элемент множества.
Для получения объединения, пересечения и т.д. производятся операции
с элементами соответствующих множеств. Процедуры реализации
данных операций могут выглядеть так:
объединение
procedure unific(a,b,c:lat; var d:lat);
begin
d:=a+b+c
end;
пересечение
procedure cross(a,b,c:lat; var d:lat);
begin
d:=a*b*c
end;
разность
procedure diff(a,b:lat; var d:lat);
begin
d:=a-b end;
симметрическая разность procedure
simdiff(a,b,c:lat; var d:lat);
begin d:=a+b+c-a*b-a*c-b*c+a*b*c
13
end;
или
procedure simdiff(a,b,c:lat; var d:lat);
begin
unific(a,b,c,e);
cross(a,b,c,f); d:=e-a*ba*c-b*c+f
end;
дополнение
procedure obj(a:lat; var d:lat);
var x:char;
begin d:=[ ];
for x:=’a’ to ‘z’ do
if not (x in a) then d:=d+[x]
end;
Так как величины множественного типа не могут быть элементами
списка вывода в Turbo – Pascal, то для реализации вывода приходится
использовать специальные приемы. Например, для вывода элементов
множества d указанного выше типа можно применить такой фрагмент:
............................................
for x:=’a’ to ‘z’ do
if x in d then write(x,’ ‘);
............................................
В
основной программе будут содержаться
вышеперечисленные блоки
и
вызов процедур в нужной последовательности.
5.СОДЕРЖАНИЕ ОТЧЕТА
 постановка задачи;
 вариант задания;
 выполнение своего варианта вручную;
 программа решения поставленной задачи и проведение
исследований по заданию преподавателя;
 результаты работы программы. 
14
6.КОНТРОЛЬНЫЕ ВОПРОСЫ
1.Что называется множеством, элементом множества, конечным и
бесконечным множествами? Привести примеры.
2.Какие существуют способы задания множеств?
3.Для множеств какого типа наиболее приемлем перечисляемый способ
задания?
4.Дать определение пустому и равным множествам.
5.Какие операции над множествами вы знаете?
6.Дать определение понятию “универсальное множество”.
7.Что такое диаграмма Эйлера – Венна?
15
Тема. Основы теории графов. Практическое занятие №2 Задание
графов, матрицы инцидентности и смежности.
1. ОБЩИЕ СВЕДЕНИЯ
Определение 1: Графом G называется пара множеств V, Е, где V —
непустое множество элементов называемых вершинами, Е — конечное
семейство неупорядоченных пар, называемых рёбрами (рис. 1).
Рисунок 1
Рассмотрим основные характеристики графа на примере (рис. 2)
граф G
Рисунок 2
V={A,B,C,D,E,F};
E={(BC), (EF), (ED), (FD)}
Определение 2: Две вершины А и В называются
если существует ребро, их соединяющее, при этом
называется инцидентным вершине А и вершине В.
смежными,
это ребро
16
На рис. 2 смежными, например, являются вершины C и B, F и D,
вершина C инцидентна вершине B, вершина F соответственно вершине D.
Определение 3: Два ребра называются смежными, если у них есть хотя
бы одна общая вершина.
В нашем случае ребра EF и ED являются смежными.
Определение 4:
Степенью вершины А р(А) называют число
рёбер, инцидентных (входящих) в вершину А.
Например, р(E)=2
Определение 5: Вершина называется изолированной, если р(А)=0 (на
рассматриваемом графе р(A)=0);
Определение 6: Вершина называется висячей, если р(А)=1.
Для графа G это вершины B и C.
Определение 6: Граф, у которого нет ребер, называется пустым графом.
Граф, любые две вершины которого смежные, называется полным
графом.
Граф, у которого степени вершин одинаковы, называется однородным.
Если любые две вершины графа могут быть соединены линией
проходящей по рёбрам графа, то такой граф называется связным.
Рассмотрим описанные выше характеристики на примере графов,
приведенных на рисунке 1.
Граф 5 является пустым, так как не содержит ребер. Граф 1 не является
полным, в свою очередь графы 2, 4 есть полные, однородные. Граф 3
полный, однородный и связный.
Задать граф - указать множество его ребер, вершин и отношений
инцидентности.
В теоретико-множественной и геометрической форм определения
(задания) графов, часто используется матричная форма их представления.
Существуют различные виды матриц графов, однако все они, как правило,
полностью передают основные свойства графов. Матричная форма задания
графов обладает достаточной наглядностью при любой степени сложности
графа и, что самое важное, позволяет автоматизировать процесс обработки
информации, представленной в терминах теории графов, – любая матрица
графа может быть введена в ЭВМ.
При задании графов в матричной форме могут учитываться либо
отношения смежностей (вершин или ребер (дуг)), либо отображения
инцидентности (вершин и ребер (дуг)). В связи с этим матрицы графов
делятся на два основных класса: матрицы смежностей и матрицы
инциденций.
17
Рассмотрим эти способы представления графа на примере.
Матрица смежности
Квадратная матрица, строки которой соответствуют вершинам графа и
столбцы соответствуют вершинам графа.
Составим матрицу смежности для данного графа:
1
2
3
4
5
6
1
0
0
0
0
0
0
2
0
0
1
0
0
0
3
0
1
0
0
0
0
4
0
0
0
0
1
1
5
0
0
0
1
0
1
6
0
0
0
1
1
0
Матрица инцидентности
Прямоугольная матрица, строки которой соответствуют вершинам графа,
столбцы - ребрам.
Составим матрицу инцидентности для данного графа:
1
2
(23)
0
1
(46)
0
0
(56)
0
0
(45)
0
0
18
3
4
5
6
1
0
0
0
0
1
0
1
0
0
1
1
0
1
1
0
2. ЦЕЛЬ И ПОРЯДОК РАБОТЫ
Цель работы - разработать при помощи любой известной среды
программирования программу, которая:
1)
позволяет, используя манипулятор мышь или клавиатуру,
задавать точки (вершины) графа и соединять их рёбрами.
2) по заданному графу строит матрицу инцидентности и
матрицу смежности
Порядок работы:

изучить описание работы;

согласно своему варианту, решить заданные примеры без
использования ЭВМ;

написать и отладить программу в соответствии с заданием;

оформить отчет.
3. ЗАДАНИЯ
Задания для ручного просчета:
3.1 Для данного графа:
3.1.1 Выписать смежные вершины.
3.1.2 Выписать три пары смежных ребер.
3.1.3 Чему равны р(2) и р(7)?
3.1.4 Выписать изолированные и висячие вершины (если они
есть).
3.1.5 Является ли граф полным? однородным? связным?
3.2 Составить матрицу смежности и инцидентности для данного графа.
1.
2.
19
3.
4.
5.
6.
7.
8.
20
9.
3.3 Дана матрица смежности. Построить граф, соответствующий данной
матрице.
1.
1
2
3
4
5
6
1
0
1
0
1
1
1
2
1
0
1
0
0
0
3
0
1
0
0
0
0
4
1
0
0
0
1
0
5
1
0
0
1
0
1
6
1
0
0
0
1
0
1
0
1
1
0
1
1
2
1
0
1
1
1
0
3
1
1
0
0
0
0
4
0
1
0
0
1
0
5
1
1
0
1
0
0
6
1
0
0
0
0
0
1
0
1
0
1
1
2
1
0
1
1
0
3
0
1
0
0
0
4
1
0
0
0
1
5
1
0
0
1
0
6
0
0
0
0
1
2.
1
2
3
4
5
6
3.
1
2
3
4
5
21
6
4.
1
2
3
4
5
6
5.
1
2
3
4
5
6
6.
1
2
3
4
5
6
7.
1
2
3
4
5
6
8.
1
2
3
0
0
0
0
1
0
1
0
1
0
1
1
1
2
1
0
1
0
0
0
3
0
1
0
0
1
0
4
1
0
0
0
1
0
5
1
0
1
1
0
1
6
1
0
0
0
1
0
1
0
1
0
0
1
1
2
1
0
1
0
0
0
3
0
1
0
1
0
1
4
0
0
1
0
1
0
5
1
0
0
1
0
1
6
1
0
1
0
1
0
1
0
1
0
1
1
1
2
1
0
0
1
0
0
3
0
0
0
0
0
1
4
1
1
0
0
0
0
5
1
0
0
0
0
1
6
1
0
1
0
1
0
1
0
0
0
1
1
1
2
0
0
1
1
0
0
3
0
1
0
0
0
0
4
1
0
0
0
1
1
5
1
0
0
1
0
1
6
1
0
0
1
1
0
1
0
1
0
2
1
0
1
3
0
1
0
4
0
1
0
5
1
0
0
6
1
1
0
22
4
5
6
9.
1
2
3
4
5
6
10.
1
2
3
4
5
6
0
1
1
1
0
1
0
0
0
0
0
0
0
0
1
0
1
0
1
0
0
1
1
1
1
2
0
0
1
0
0
0
3
1
1
0
0
0
0
4
1
0
0
0
1
1
5
1
0
0
1
0
1
6
1
0
0
1
1
0
1
0
1
0
0
1
1
2
1
0
1
0
0
0
3
0
1
0
1
0
1
4
0
0
1
0
1
0
5
1
0
0
1
0
1
6
1
0
1
0
1
0
3.4 Дана матрица инцидентности. Построить граф, соответствующий
данной матрице.
1.
(12)
(13)
(23)
(35)
(45)
(56)
1
1
0
0
0
0
1
1
0
1
0
0
0
2
0
1
1
1
0
0
3
0
0
0
0
1
0
4
0
0
0
1
1
1
5
0
0
0
0
0
1
6
2.
(15)
(23)
(26)
(45)
(46)
(56)
1
0
0
0
0
0
1
0
1
1
0
0
0
2
0
1
0
0
0
0
3
0
0
0
1
1
0
4
1
0
0
1
0
1
5
0
0
1
0
1
1
6
23
3.
1
2
3
4
5
6
(12)
1
1
0
0
0
0
(13)
1
0
1
0
0
0
(16)
1
0
0
0
0
1
(24)
0
1
0
1
0
0
(45)
0
0
0
1
1
0
(46)
0
0
0
1
0
1
(23)
0
1
1
0
0
0
(24)
0
1
0
1
0
0
(25)
0
1
0
0
1
0
(26)
0
1
0
0
0
1
(45)
0
0
0
1
1
0
(56)
0
0
0
0
1
1
(12)
1
1
0
0
0
0
(23)
0
1
1
0
0
0
(24)
0
1
0
1
0
0
(26)
0
1
0
0
0
1
(35)
0
0
1
0
1
0
(46)
0
0
0
1
0
1
(15)
1
0
0
0
1
0
(23)
0
1
1
0
0
0
(26)
0
1
0
0
0
1
(34)
0
0
1
1
0
0
(35)
0
0
1
0
1
0
(56)
0
0
0
0
1
1
(12)
1
(14)
1
(23)
0
(26)
0
(35)
0
(56)
0
4.
1
2
3
4
5
6
5.
1
2
3
4
5
6
6.
1
2
3
4
5
6
7.
1
24
2
3
4
5
6
1
0
0
0
0
0
0
1
0
0
1
1
0
0
0
1
0
0
0
1
0
1
0
1
0
0
0
0
1
1
(16)
1
0
0
0
0
1
(23)
0
1
1
0
0
0
(24)
0
1
0
1
0
0
(35)
0
0
1
0
1
0
(36)
0
0
1
0
0
1
(46)
0
0
0
1
0
1
(13)
1
0
1
0
0
0
(24)
0
1
0
1
0
0
(35)
0
0
1
0
1
0
(36)
0
0
1
0
0
1
(45)
0
0
0
1
1
0
(46)
0
0
0
1
0
1
(13)
1
0
1
0
0
0
(15)
1
0
0
0
1
0
(24)
0
1
0
1
0
0
(26)
0
1
0
0
0
1
(45)
0
0
0
1
1
0
(56)
0
0
0
0
1
1
8.
1
2
3
4
5
6
9.
1
2
3
4
5
6
10.
1
2
3
4
5
6
4. МЕТОДИЧЕСКИЕ УКАЗАНИЯ
Рассмотрим эти способы представления графа на примере.
Матрица смежности
Квадратная матрица, строки которой соответствуют вершинам графа и
столбцы соответствуют вершинам графа.
25
Составим матрицу смежности для данного графа:
1
2
3
4
5
6
1
0
0
0
0
0
0
2
0
0
1
0
0
0
3
0
1
0
0
0
0
4
0
0
0
0
1
1
5
0
0
0
1
0
1
6
0
0
0
1
1
0
Матрица инцидентности
Прямоугольная матрица, строки которой соответствуют вершинам графа,
столбцы - ребрам.
Составим матрицу инцидентности для данного графа:
1
2
3
4
5
6
(23)
0
1
1
0
0
0
(46)
0
0
0
1
0
1
(56)
0
0
0
0
1
1
(45)
0
0
0
1
1
0
26
В работе можно использовать следующие фрагменты программ,
представленные на языке C#.
//Случайное заполнение матрицы смежности
{Random x = new Random();
for (short i = 0; i < n; i++)
for (short j = 0; j < n; j++)
{
if (i != j)
{
dataGridView1[i, j].Value = x.Next(0, 2);
}
}
// Случайное построение графа
{
if (MessageBox.Show("Вы действительно хотите сбросить старые
результаты?", "Подтверждение выбора", MessageBoxButtons.YesNo) ==
DialogResult.Yes)
{
for (short i = 0; i < n; i++)
{
for (short j = 0; j < n; j++)
{
if (i != j)
{
dataGridView1[i, j].Value = null;
a[i, j] = 0;
a1[i, j] = 0;
}
}
}
koord.Clear();
n = 1;
numericUpDown1.Value = n;
pictureBox1.Invalidate();
}
// Для того чтобы сбросить старые результаты, можно использовать:
{
27
if (MessageBox.Show("Вы действительно хотите сбросить старые
результаты?", "Подтверждение выбора", MessageBoxButtons.YesNo) ==
DialogResult.Yes)
{
for (short i = 0; i < n; i++)
{
for (short j = 0; j < n; j++)
{
if (i != j)
{
dataGridView1[i, j].Value = null;
a[i, j] = 0;
a1[i, j] = 0;
}
}
}
koord.Clear();
n = 1;
numericUpDown1.Value = n;
pictureBox1.Invalidate();
}
}
// Можно использовать следующую часть программы для выведения
матриц смежности и инцидентности
private void Form1_MouseClick(object sender, MouseEventArgs e)
{
if (rect) return;
//вкючение новых вершин и дуг
int i; bool b=false;
if (kv <= 0&& !mcrest)
{//занести новую вершину в массив
A[kv].n = kv; A[kv].x = e.X; A[kv].y = e.Y; A[kv].r = rv; A[kv].e =
true;
A[kv].c = Col[q]; A[kv].q = q;
kv++;
}else
{//найти вершину близкую к текущей точке
b = false;
for(i=0;i<kv;i++)
28
if ((e.X - A[i].x) * (e.X - A[i].x) + (e.Y - A[i].y) * (e.Y - A[i].y)
<= (rv + re) * (rv + re))
{ b = true; break; }
if (!b & !mcrest )
{ //не найдена вершина - занести новую вершину
if (kv < maxkv)
{
A[kv].n = kv; A[kv].x = e.X; A[kv].y = e.Y; A[kv].r = rv;
A[kv].e = true;
A[kv].c = Col[q]; A[kv].q = q;
if (kv > 0) Atek = A[kv - 1];
kv++;
}
}
else
{ //найдена i-я вершина на клике мышки- если тек. вершина
заполнена рисуем ребро
if (rcrest)
{//удалить вершину
if (Atek.n == A[i].n && Atek.e)
if (i > 0) Atek = A[i - 1];
else Atek.e = false;
A[i].e = false;
//удалить все ребра, связанные с данной вершиной
int j;
for (j = 0; j < kv; j++)
X[i, j] = X[j, i] = 0;
if (i == (kv - 1))
{ for (j = kv - 1; j >= 0 && !A[j].e; j--);kv = j + 1; }
}
else if (rrib)
{//удалить ребро
if (!Atek.e) Atek = A[i];
else
{
X[Atek.n, A[i].n] = X[A[i].n, Atek.n] = 0;
Atek = A[i];
}
}
29
else if (mcrest)
{//переместить вершину
if (!Atek.e) Atek = A[i];
else
{
b = false;
for (i = 0; i < kv; i++)
if (A[i].n == Atek.n) { b = true; break; }
if (b) { A[i].x = Atek.x = e.X; A[i].y = Atek.y = e.Y; }
}
}
else
{ //заполнить новое ребро
if (!Atek.e) Atek = A[i];
else
{//завести ребро (Atek - A[i])
X[Atek.n, A[i].n] = 1; //заполнили таблицу смежности
//Матрица инцидентности
Y[z].m = Atek.n; Y[z].k = A[i].n; Y[z].n = z;
In[Y[z].m, Y[z].n] = 1;
In[Y[z].k, Y[z].n] = -1;
Atek = A[i];
}
}
//Счетчик дуг
z = 0;
for (int ii = 0; ii < kv; ii++)
{
for (int jj = 0; jj < kv; jj++)
z += X[ii, jj];
}
//Матрица смежности и инцидентности на label3
label3.Text = "Матрица инцедентности\n";
for (int q = 0; q < kv; q++)
{
for (int w = 0; w < z; w++)
label3.Text += In[q,w] + " ";
label3.Text +="\n";
}
30
label3.Text += "\nМатрица смежности\n";
for (int q = 0; q < kv; q++)
{
for (int w = 0; w < kv; w++)
label3.Text += X[q, w] + " ";
label3.Text += "\n";
}
}
}
Invalidate();
}
5. СОДЕРЖАНИЕ ОТЧЕТА
 наименование работы, постановку задачи;
 выбранный вариант задания;
 результаты решения задач без применения ЭВМ;
 программу решения задачи (представляется в электронном виде;
 результаты работы программы и их анализ.
6. КОНТРОЛЬНЫЕ ВОПРОСЫ
1.
Дайте определение понятию граф.
2.
При каком условии ребро инцидентно вершинам?
3.
Как называется вершина А при условии p(A)=0, где р(А)-степень
вершины А? при р(А)=1?
4.
Любой ли однородный граф является полным? Любой ли полный
граф является однородным?
5.
Является ли следующий граф связным (рис. 3)?
Рисунок 3
6.
Может ли граф не содержать ребер? вершин?
7.
Что значит задать граф?
8.
На какие два основных класса делятся матрицы графов? Дайте
определение матрице смежности и матрице инцидентности?
31
Тема. Основы теории графов. Практическое занятие №3
Определение изоморфности графов
1 ОБЩИЕ СВЕДЕНИЯ
Отображение графов – это двумерное представление графа,
сохраняющее отношение смежности.
Графы G1=(V1,E1) и G2=(V2,E2) называются изоморфными
(обозначение
G1~G2),
если
между
графами
существует
взаимнооднозначное отображение j: G1~G2 (V1~V2, E1~E2), которое
сохраняет соответствие между ребрами (дугами) графов, т.е. для любого
ребра (дуги) e=(v,u) верно:
e'=j(v,u)=(j(v),j(u)) (e~E1, e'~E2) (1)
Отображение j называется изоморфным отображением.
Дадим другое определение изоморфности: два графа G1 и G2
называются изоморфными, если между их вершинами установлено
взаимнооднозначное соответствие, такое, что любые две вершины графа
G1 соединены так же, как и соответствующие вершины графа G2
Рассмотрим графы 1 и 2.
Рисунок 4 Изоморфные графы
32
На рисунке 1 видно, что между вершинами графов существует
взаимно-однозначное соответствие, то есть, например, ребро (2,6)
первого графа подобно ребру (2,6) второго графа. Это можно наблюдать
для всех вершин и ребер.
Иными
словами,
изоморфные
графы
различаются
только
обозначением вершин. Условимся называть (0,1)-матрицу булевой
(матрицей из нулей и единиц, где умножение и сложение логические).
Изоморфизм графов можно определить в матричных терминах.
Предварительно введём понятие перестановочного подобия матриц.
Оно формулируется одинаково для булевых матриц и матриц над полем.
Квадратная (0,1)-матрица P называется перестановочной, если
она имеет в каждой строке и каждом столбце ровно одну единицу. Это
легко проверить: PPt  P t P  E  P t  P 1.
Матрицы A и B называются перестановочно подобными, если
А  PBP t для некоторой перестановочной матрицы P. Содержательный
смысл этого определения заключается в том, что A получается из B
одинаковыми перестановками строк и столбцов.
Пусть графы с n вершинами, заданные матрицами смежности A и
B, изоморфны, то есть существует такая биекция (перестановка) σ на
множестве {1,2, ... , n}, что для любых ij. Тогда:
(2)
aij  b
 (i) ( j )
Сопоставим перестановке перестановочную матрицу P = (p)
порядка n, где
(3).
Прямыми вычислениями проверяется, что A  PBP t (4)
Итак, если графы изоморфны, то их матрицы смежности
перестановочно
подобны.
Наоборот,
если
матрицы
смежности
33
перестановочно подобны, то графы изоморфны, причем изоморфизм σ
определяется по матрице подобия P из равенств (3).
Вывод: графы изоморфны тогда и только тогда, когда их
матрицы смежности перестановочно подобны.
Задача проверки изоморфизма графов относится к задачам,
относительно которых нельзя точно сказать, являются ли они
полиномиальными или нет. Для определения изоморфности графа
существует два подхода.
В первом выполняется попытка перебора всех возможных
перестановок элементов графов для установления взаимно-однозначного
соответствия. При наличии у разных графов совпадающих перестановок,
считается, что графы изоморфны. В качестве элементов могут выступать
как сами вершины графа, так и матрицы смежности, несущие в себе
информацию
о
смежности
вершин
графа.
Тогда
в
качестве
соответствующего взаимно-однозначного соответствия между парами
матриц смежности будет отношение перестановочного подобия. Но изза необходимости перебора всех n! вариантов перестановок, при
большом количестве n, время, необходимое для вычислений делает эту
задачу нерешаемой в условиях реального масштаба времени.
Во втором подходе пытаются найти такой инвариант, из
совпадений которого следовало бы, что графы изоморфны. Недостатком
этого варианта решения задач является то, что не существует полного
инварианта.
К основным инвариантам относятся:

Индекс Винера (сумма длин кратчайших путей между всеми
парами вершин в графе);

Определитель матрицы смежности;

Число вершин/дуг/ребер (для вычисления необходимо
сверить число дуг/вершин/ребер между графами);
34

Индекс Рандича (индекс связности неориентированного

Диаметр графа (максимально возможное расстояние между
графа
;
двумя его вершинами.);
Рассмотрим первый алгоритм определения изоморфности двух
графов. Для этого дадим определение связных вершин и подграфа.
Вершины в графе связаны, если существует соединяющая их
(простая) цепь, где цепь в графе — маршрут, все рёбра которого
различны. Если все вершины (а тем самым и рёбра) различны, то такая
цепь называется простой (элементарной).
Граф называется связным, если любые две его вершины связаны.
Если граф не связен, то он представляет собой объединение нескольких
связных подграфов.
Граф
(V1 , E1 )
называется
подграфом
графа
(V,E),
если
V1  V, E1  E . Например, цепь в графе можно рассматривать как
подграф. Говорят, что подграф порождён подмножеством вершин
V1 если E1 состоит из рёбер, соединяющих вершины из V1 . Говорят, что
подграф порождён подмножеством рёбер E1 если V1 состоит из концов
рёбер из E1 .
Легко убедиться, что отношение связанности на множестве
вершин графа рефлексивно, симметрично и транзитивно, то есть,
связанность вершин является отношением эквивалентности.
35
2. ЦЕЛЬ И ПОРЯДОК РАБОТЫ
Цель работы – моделировать сложные структуры с помощью
графов и уметь представлять их в виде изоморфных графов, приводящих
к решению практических задач
Порядок работы:

изучить описание работы;

согласно своему варианту, решить заданные примеры без
использования ЭВМ;

написать и отладить программу в соответствии с заданием;

оформить отчет.
3. ЗАДАНИЯ
3.1 Задания для ручного просчета:
Для данных графов выяснить, являются ли они изоморфными.
Если да, то установить изоморфизм, в противном случае доказать,
почему графы неизоморфны.
Решите задание вашего варианта:
Вариант 1
36
Вариант 2
Вариант 3
Вариант 4
Вариант 5
37
Вариант 6
Вариант 7
Вариант 8
Вариант 9
38
Вариант 10
3.2 Задания для изучения изоморфности с помощью программ:
Для заданных пользователем графов определить изоморфность
(результатом программы является вывод «да-нет» в зависимости от
заданных графов).
4. МЕТОДИЧЕСКИЕ УКАЗАНИЯ
Рассмотрим пример определения изоморфности графов.
Даны два графа. Выяснить, являются ли они изоморфными.
Покажем, что данные графы изоморфны.
Действительно, отображение a e, b f, c g, d h, являющееся
изоморфизмом легко представить как модификацию первого графа,
передвигающую вершину d в центр рисунка.
Составим матрицу смежности для первого графа:
39
a
b
c
d
a
0
1
1
1
b
1
0
1
1
c
1
1
0
1
d
1
1
1
0
Составим матрицу смежности для второго графа:
e
f
g
h
e
0
1
1
1
f
1
0
1
1
g
1
1
0
1
h
1
1
1
0
Так как соответствующие матрицы смежности одинаковы, то
графы 1 и 2 изоморфны.
Для проверки изоморфности графов, с помощью программ можно
использовать следующий модуль (C#):
//проверка изоморфности подграфов
//int[, ,] X - матрица смежности подграфа
//int f1, int f2 - счетчики
//int k - кол-во вершин подграфа
//f1,f2 - номера подграфов
bool izomorf(int[, ,] X, int f1, int f2, int k)
{
int i, j, f;
bool b;
int n = 1;
for (i = 1; i <= k; i++) n = n * i;
int[,] M = new int[n, k]; //массив перестановок вершин,
perestan(M, k); //построение массива перестановок вершин
//сравнение подграфов с перестановкой строк и столбцов
for (f = 1; f < n; f++)
{
b = true;
40
for (i = 0; i < k; i++)
{
for (j = 0; j < k; j++)
if (X[f1, i, j] != X[f2, M[f, i], M[f, j]])
{
b = false; break;
}
if (!b) break;
}
if (b) return true;
}
return false;
}//izomorf
5. СОДЕРЖАНИЕ ОТЧЕТА

наименование работы, постановку задачи;

выбранный вариант задания;

результаты решения задач без применения ЭВМ;

программу решения задачи (представляется в электронном
виде);

результаты работы программы и их анализ.
6. КОНТРОЛЬНЫЕ ВОПРОСЫ
1. Какие графы называются изоморфными?
2. Докажите, что графы на рис. 1 изоморфны (выпишите все
соответствующие вершины и ребра).
3. Дайте определение булевой матрицы.
4. Объясните понятие перестановочного подобия матриц.
5. Известно, что если графы изоморфны, то их матрицы смежности
перестановочно подобны. Верно ли это утверждение наоборот?
6. В каком случае вершины u и v связны?
7. Какой граф называется подграфом?
41
8. Среди данных графов выберете изоморфные и неизоморфные
графы.
42
Тема. Основы теории графов. Практическое занятие №4
Кратчайший путь в графе.
1. ОБЩИЕ СВЕДЕНИЯ
Задача о кратчайшем пути возникает, когда необходимо
проложить так называемый оптимальный маршрут.
Пусть имеется неориентированный граф G(V,E), причем каждому
ребру графа поставлено в соответствие некоторое число L(e)>0,
называемое длиной ребра.
Задача нахождения кратчайшего пути сводится к тому, что от Va начальной вершины к Vb следует проложить µ(Va , Vb), причем длина
этого пути Lµ должна быть минимальной, таким образом кратчайшим
путем между двумя вершинами называется путь наименьшего
веса(длины), соединяющий эти вершины.
Определение кратчайшего пути в графе с произвольной
длиной дуг.
Пусть имеется неориентированный граф, к каждой дуге которого
приписана длина L.
Общая идея алгоритма: к каждой вершине алгоритма должно быть
приписано число, которое дает кратчайшую длину пути из этой
вершины в конечную.
Опишем этот алгоритм более подробно:
1. Конечной вершине V0присвоим λ0, а всем остальным
вершинам Viприсвоим λi=∞.
2. Находим пару вершин Vi и Vj, для которых:
λj- λi>L(Vi, Vj)
Для каждой пары производим переиндексацию вершин:
λj=>λjl= λi+ L(Vi, Vj)
3. Продолжаем до тех пор, пока пар вершин с условием λjλi>L(Vi, Vj) не останется.
Vn – начальная вершина – получит индекс λn, который является
длиной кратчайшего пути из начальной вершины в конечную.
Свойства индексов вершин после реализации алгоритма:
1.
Для любой произвольных вершин Vkи Vs, имеющих λkи λs
получим:
λs–λk≤L(Vk, Vs)
потому что, если мы встретим пару λs–λk>L(Vk, Vs), то это значит,
что мы не закончили алгоритм.
2.
Пусть имеется произвольная вершина Vpс индексом λp,
который в процессе работы алгоритма неуклонно уменьшается.
Пусть λq– последняя вершина, которая послужила причиной
переиндексации:
λp= λq + L(Vq , Vp)
43
Для любой вершины можно найти смежную вершину, для
которой имеет место:
λp- λq =L(Vq , Vp)в соответствии с алгоритмом.
Алгоритм Дейкстры.
Рассмотрим еще один метод нахождения кратчайших путей в
графе на примере алгоритма Дейкстры.
Допустим, на некотором шаге описанного выше алгоритма
построено дерево с множеством вершин A, а для каждой вершины
известна вершина
, на которой достигается наименьшее
значение величины
, где минимум берется по
всем вершинам
. Тогда на этом шаге следует выбрать вершину
с наименьшим значением величины
и присоединить к дереву
ребро (F(y),y).
После этого для каждой вершины z, еще не принадлежащей к
дереву, значения
и F(z) уточняются следующим образом: если
,
то
следует
положить
F(z)=y,
. Вершина F(y) может рассматриваться как
предполагаемый отец вершины (y) в геодезическом дереве (если все
множество состояло бы из одной вершины y, то F(y) была бы ее
истинным отцом). Величина
представляет собой оценку кратчайшего
пути из (a) в (y), она равна весу кратчайшего из путей, проходящих
только через вершины множества A. После того, как вершина (y)
присоединяется к дереву, значения F(y) и
больше не изменяются,
F(y) является отцом вершины (y)в геодезическом дереве, а
.
Реализация алгоритма, шаги реализации и комментарии даны в
разделе «Методические указания».
Алгоритм Беллмана-Форда.
Алгоритм начинает свою работу в точке, к которой следует
проложить маршрут(называется исходной точкой). Расстояние от этой
точки до самой себя задается равным нулю, а расстояние до всех
остальных точек считается равным бесконечности.
Основное предположение, выдвигаемое в данном алгоритме,
заключается в том, что от любой точки системы существует как
минимум один маршрут к исходной точке. Ни одна точка не является
полностью изолированной. Кроме тoгo, по достижении исходной точки
маршрут заканчивается. Он не может пройти через исходную точку, а
затем вернyться назад, образовав петлю. Таким образом, нельзя пройти
ПО одному и тому же пути дважды. На каждой итерации на схему
наносится путь от каждой удалённой точки до исходной точке, причём
количество переходов на этом пути соответствует номеру итерации.
Рядом с каждым переходом записывается его длина.
44
Реализация алгоритма, шаги реализации и комментарии даны в
разделе «Методические указания».
2. ЦЕЛЬ И ПОРЯДОК РАБОТЫ
Цель работы - научиться находить кратчайший путь в графе,
применяя заданный алгоритм.
Порядок работы:
 изучить описание работы;
 согласно своему варианту, решить заданные примеры без
использования ЭВМ;
 написать и отладить программу в соответствии с заданием и
провести исследования;
 оформить отчет.
3. ЗАДАНИЯ
3.1 Задания для ручного просчета:
Найти кратчайшее расстояние от X до Y:
2
7
5
5
8
8
3
11
9
2
1
1
2
6
5
2
4
4
4
7
5
6
2
9
10
4
13
7
8
1
3
3
6
9
12
9
№
1
2
3
4
5
6
7
X
1
1
1
2
2
5
2
Варианты заданий
Y
№
X
Y
8
10
12
4
9
11
10
3
10
12
3
8
9
13
5
12
11
14
6
11
13
15
1
11
12
16
13
2
45
8
9
10
6
7
12
12
13
4
17
18
19
11
12
8
3
3
3
3.2 Задания для вычисления с помощью программы:
Написать программу, находящую кратчайший
вершинами X и Y в данном графе.
3
путь
5
1
6
2
3
4
4
3
7
6
между
5
2
8
9
1
0
4
4
2
3
1
1
1
2
1
4
3
1
3
5
6
1
1
2
2
0
9
5
2
2
9
3
7
5
1
8
4
1
4
6
1
5 7
8
4
2
1
3
9
2
2
4
3
2
5
Варианты заданий:
1.
3.
5.
7.
9.
11.
13.
X=1,Y=8
X = 7 , Y = 24
X = 2 , Y =12
X = 8 , Y = 13
X = 5 , Y = 13
X = 12 , Y= 20
X =17 , Y =25
4.
2.
4.
6.
8.
10.
12.
14.
X = 1 , Y = 18
X = 9 , Y = 17
X = 8 , Y = 23
X = 3 , Y = 13
X = 11 , Y = 18
X=2,Y=7
X = 4 , Y =1
МЕТОДИЧЕСКИЕ УКАЗАНИЯ
Пример 1.
46
Найти кратчайший путь в заданном графе методом индексации
вершин.
4
7
6
6
3
8
5
5
7
9
2
8
6
7
4
3
5
Решение:
Реализуем первый пункт алгоритма:
4
6
∞
∞
7
6
∞
5
3
∞
8
8
∞
5
6
∞
9
7
∞
2
7
4
∞
0
3
∞
5
Далее производим переиндексацию:
19
15
26
18
26
8
9
70
3
Когда не останется пар вершин для переиндексации, получим граф
с такими индексами:
47
15
12
17
9
17
8
9
70
3
Длина кратчайшего пути равна 15.
Пример 2.
Рассмотрим выполнение алгоритма Дейкстры на примере графа,
показанного на рисунке.
Пусть требуется найти кратчайшие расстояния от 1-й вершины до
всех остальных.
Кружками обозначены вершины, линиями — пути между ними
(рёбра графа). В кружках обозначены номера вершин, над рёбрами
обозначена их «цена» — длина пути. Рядом с каждой вершиной красным
обозначена метка — длина кратчайшего пути в эту вершину из вершины
1.
48
Первый шаг. Рассмотрим шаг алгоритма Дейкстры для нашего
примера. Минимальную метку имеет вершина 1. Её соседями являются
вершины 2, 3 и 6.
Первый по очереди сосед вершины 1 — вершина 2, потому что
длина пути до неё минимальна. Длина пути в неё через вершину 1 равна
сумме значения метки вершины 1 и длины ребра, идущего из 1-й в 2-ю,
то есть 0 + 7 = 7. Это меньше текущей метки вершины 2, бесконечности,
поэтому новая метка 2-й вершины равна 7.
Аналогичную операцию проделываем с двумя другими соседями 1й вершины — 3-й и 6-й.
49
Все соседи вершины 1 проверены. Текущее минимальное
расстояние до вершины 1 считается окончательным и пересмотру не
подлежит (то, что это действительно так, впервые доказал Э. Дейкстра).
Вычеркнем её из графа, чтобы отметить, что эта вершина посещена.
Второй шаг. Шаг алгоритма повторяется. Снова находим
«ближайшую» из непосещённых вершин. Это вершина 2 с меткой 7.
Снова пытаемся уменьшить метки соседей выбранной вершины,
пытаясь пройти в них через 2-ю вершину. Соседями вершины 2
являются вершины 1, 3 и 4.
50
Первый (по порядку) сосед вершины 2 — вершина 1. Но она уже
посещена, поэтому с 1-й вершиной ничего не делаем.
Следующий сосед вершины 2 — вершина 3, так как имеет
минимальную метку из вершин, отмеченных как не посещённые. Если
идти в неё через 2, то длина такого пути будет равна 17 (7 + 10 = 17). Но
текущая метка третьей вершины равна 9, а это меньше 17, поэтому метка
не меняется.
Ещё один сосед вершины 2 — вершина 4. Если идти в неё через 2ю, то длина такого пути будет равна сумме кратчайшего расстояния до
2-й вершины и расстояния между вершинами 2 и 4, то есть 22 (7 + 15 =
22). Поскольку 22< устанавливаем метку вершины 4 равной 22.
Все соседи вершины 2 просмотрены, замораживаем расстояние до
неё и помечаем её как посещённую.
51
Третий шаг. Повторяем шаг алгоритма, выбрав вершину 3. После
её «обработки» получим такие результаты:
Дальнейшие шаги. Повторяем шаг алгоритма для оставшихся
вершин. Это будут вершины 6, 4 и 5, соответственно порядку.
52
Завершение выполнения алгоритма. Алгоритм заканчивает
работу, когда нельзя больше обработать ни одной вершины. В данном
примере все вершины зачёркнуты, однако ошибочно полагать, что так
будет в любом примере — некоторые вершины могут остаться
незачёркнутыми, если до них нельзя добраться, т. е. если граф
несвязный. Результат работы алгоритма виден на последнем рисунке:
кратчайший путь от вершины 1 до 2-й составляет 7, до 3-й — 9, до 4-й
— 20, до 5-й — 20, до 6-й — 11.
Реализация алгоритма Дейкстры на C#:
using
using
using
using
System;
System.Collections.Generic;
System.Linq;
System.Text;
/// <summary>
/// Реализация алгоритма Дейкстры. Содержит матрицу смежности в виде
массивов вершин и ребер
/// </summary>
class DekstraAlgorim
{
public Point[] points { get; private set; }
public Rebro[] rebra { get; private set; }
public Point BeginPoint { get; private set; }
53
public DekstraAlgorim(Point[] pointsOfgrath, Rebro[] rebraOfgrath)
{
points = pointsOfgrath;
rebra = rebraOfgrath;
}
/// <summary>
/// Запуск алгоритма расчета
/// </summary>
/// <param name="beginp"></param>
public void AlgoritmRun(Point beginp)
{
if (this.points.Count() == 0 || this.rebra.Count() == 0)
{
throw new DekstraException("Массив вершин или ребер не
задан!");
}
else
{
BeginPoint = beginp;
OneStep(beginp);
foreach (Point point in points)
{
Point anotherP = GetAnotherUncheckedPoint();
if (anotherP != null)
{
OneStep(anotherP);
}
else
{
break;
}
}
}
}
/// <summary>
/// Метод, делающий один шаг алгоритма. Принимает на вход вершину
/// </summary>
/// <param name="beginpoint"></param>
public void OneStep(Point beginpoint)
{
foreach (Point nextp in Pred(beginpoint))
{
if (nextp.IsChecked == false)//не отмечена
{
float newmetka = beginpoint.ValueMetka +
GetMyRebro(nextp, beginpoint).Weight;
if (nextp.ValueMetka > newmetka)
{
nextp.ValueMetka = newmetka;
nextp.predPoint = beginpoint;
}
else
{
}
}
54
}
beginpoint.IsChecked = true;//вычеркиваем
}
/// <summary>
/// Поиск соседей для вершины. Для неориентированного графа ищутся
все соседи.
/// </summary>
/// <param name="currpoint"></param>
/// <returns></returns>
private IEnumerable<Point> Pred(Point currpoint)
{
IEnumerable<Point> firstpoints = from ff in rebra where
ff.FirstPoint == currpoint select ff.SecondPoint;
IEnumerable<Point> secondpoints = from sp in rebra where
sp.SecondPoint == currpoint select sp.FirstPoint;
IEnumerable<Point> totalpoints =
firstpoints.Concat<Point>(secondpoints);
return totalpoints;
}
/// <summary>
/// Получаем ребро, соединяющее 2 входные точки
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
private Rebro GetMyRebro(Point a, Point b)
{//ищем ребро по 2 точкам
IEnumerable<Rebro> myr = from reb in rebra where (reb.FirstPoint
== a & reb.SecondPoint == b) || (reb.SecondPoint == a & reb.FirstPoint ==
b) select reb;
if (myr.Count() > 1 || myr.Count() == 0)
{
throw new DekstraException("Не найдено ребро между
соседями!");
}
else
{
return myr.First();
}
}
/// <summary>
/// Получаем очередную неотмеченную вершину, "ближайшую" к заданной.
/// </summary>
/// <returns></returns>
private Point GetAnotherUncheckedPoint()
{
IEnumerable<Point> pointsuncheck = from p in points where
p.IsChecked == false select p;
if (pointsuncheck.Count() != 0)
{
float minVal = pointsuncheck.First().ValueMetka;
Point minPoint = pointsuncheck.First();
foreach (Point p in pointsuncheck)
{
if (p.ValueMetka < minVal)
{
minVal = p.ValueMetka;
minPoint = p;
}
55
}
return minPoint;
}
else
{
return null;
}
}
public List<Point> MinPath1(Point end)
{
List<Point> listOfpoints = new List<Point>();
Point tempp = new Point();
tempp = end;
while (tempp != this.BeginPoint)
{
listOfpoints.Add(tempp);
tempp = tempp.predPoint;
}
return listOfpoints;
}
}
/// <summary>
/// Класс, реализующий ребро
/// </summary>
class Rebro
{
public Point FirstPoint { get; private set; }
public Point SecondPoint { get; private set; }
public float Weight { get; private set; }
public Rebro(Point first, Point second, float valueOfWeight)
{
FirstPoint = first;
SecondPoint = second;
Weight = valueOfWeight;
}
}
/// <summary>
/// Класс, реализующий вершину графа
/// </summary>
class Point
{
public float ValueMetka { get; set; }
public string Name { get; private set; }
public bool IsChecked { get; set; }
public Point predPoint { get; set; }
public object SomeObj { get; set; }
public Point(int value,bool ischecked)
{
ValueMetka = value;
IsChecked = ischecked;
predPoint = new Point();
}
public Point(int value, bool ischecked,string name)
{
56
ValueMetka = value;
IsChecked = ischecked;
Name = name;
predPoint = new Point();
}
public Point()
{
}
}
// <summary>
/// для печати графа
/// </summary>
static class PrintGrath
{
public static List<string> PrintAllPoints(DekstraAlgorim da)
{
List<string> retListOfPoints = new List<string>();
foreach (Point p in da.points)
{
retListOfPoints.Add(string.Format("point name={0}, point
value={1}, predok={2}", p.Name, p.ValueMetka, p.predPoint.Name ?? "нет
предка"));
}
return retListOfPoints;
}
public static List<string> PrintAllMinPaths(DekstraAlgorim da)
{
List<string> retListOfPointsAndPaths = new List<string>();
foreach (Point p in da.points)
{
if (p != da.BeginPoint)
{
string s = string.Empty;
foreach (Point p1 in da.MinPath1(p))
{
s += string.Format("{0} ", p1.Name);
}
retListOfPointsAndPaths.Add(string.Format("Point ={0},MinPath
from {1} = {2}", p.Name, da.BeginPoint.Name, s));
}
}
return retListOfPointsAndPaths;
}
}
class DekstraException:ApplicationException
{
public DekstraException(string message):base(message)
{
}
}
class Program
{
static void Main(string[] args)
{
57
Point[] v = new Point[6];
v[0] = new Point(0, false, "F");
v[1] = new Point(9999, false, "A");
v[2] = new Point(9999, false, "B");
v[3] = new Point(9999, false, "C");
v[4] = new Point(9999, false, "D");
v[5] = new Point(9999, false, "E");
Rebro[] rebras = new Rebro[10];
rebras[0] = new Rebro(v[0], v[2], 8);
rebras[1] = new Rebro(v[0], v[3], 4);//FC
rebras[2] = new Rebro(v[0], v[1], 9);//FA
rebras[3] = new Rebro(v[2], v[3], 7);//bc
rebras[4] = new Rebro(v[2], v[5], 5);//be
rebras[5] = new Rebro(v[3], v[5], 5);//ce
rebras[6] = new Rebro(v[1], v[5], 6);//ae
rebras[7] = new Rebro(v[1], v[4], 5);//ad
rebras[8] = new Rebro(v[3], v[4], 4);//cd
rebras[9] = new Rebro(v[2], v[4], 7);//bd
DekstraAlgorim da = new DekstraAlgorim(v, rebras);
da.AlgoritmRun(v[0]);
List<string> b = PrintGrath.PrintAllMinPaths(da);
for (int i = 0; i < b.Count; i++)
Console.WriteLine(b[i]);
Console.ReadKey(true);
}
}
Реализация алгоритма Флойда на C# при известной матрице смежности
графа:
using
using
using
using
System;
System.Collections.Generic;
System.Linq;
System.Text;
namespace Алгоритм_Флойда
{
class Program
{
static void Main()
{
int[,] array = new int[7, 7]
{
{0,2,1,5,7,5,6},
{2,0,5,3,1,8,6},
{1,5,0,1,5,1,2},
{5,3,1,0,3,4,3},
{7,1,5,3,0,1,5},
{5,8,1,4,1,0,1},
{6,6,2,3,5,1,0 }
};
int i, j, k;
for (k = 0; k < 7; k++)
for (i = 0; i < 7; i++)
for (j = 0; j < 7; j++)
if (array[i, j] > array[i, k] + array[k, j])
58
array[i, j] = array[i, k] + array[k, j];
Console.WriteLine("Floid: ");
Console.WriteLine("
1 2 3 4 5 6 7");//вершины графа
Console.WriteLine(" ______________");
for (i = 0; i < 7; i++)
{
Console.Write((i + 1) + "| ");
for (j = 0; j < 7; j++)
Console.Write("{0} ", array[i, j]);
Console.WriteLine("\n |");
}
Console.ReadLine();
}
}
}
5. СОДЕРЖАНИЕ ОТЧЕТА
 наименование работы, постановку задачи;
 выбранный вариант задания;
 результаты решения задач без применения ЭВМ;
 программу решения задачи (представляется в электронном
виде);
 результаты работы программы и их анализ.
6. КОНТРОЛЬНЫЕ ВОПРОСЫ
1)
Что называется весом дуги?
2)
Что такое кратчайший путь между двумя вершинами?
3)
Как определяется длина пути в графе?
4)
Что называется расстоянием между фиксированными
вершинами графа?
5)
Опишите алгоритм нахождения расстояния между двумя
фиксированными вершинами.
6)
Опишите алгоритм Дейкстры.
7) В чем состоит сущность алгоритма Беллмана-Форда?
9) Какие еще алгоритмы Вы знаете?
59
Тема. Основы теории графов. Практическое занятие №5
Построение графа наименьшей длины.
1. ОБЩИЕ СВЕДЕНИЯ
Большое практическое значение имеет следующая задача,
которую можно сформулировать в виде задачи о проведении дорог.
Имеется несколько городов а, b, с ..., которые нужно соединить между
собой сетью дорог. Для каждой пары городов (х, у) известна стоимость
1(х, у)' строительства соединяющей их дороги. Задача состоит в том,
чтобы построить самую дешевую из возможных сетей дорог. Вместо
сети дорог можно рассматривать сеть линий электропередачи, сеть
нефтепроводов и т. п. Называя в графе, изображающем сеть дорог,
величину 1(х, у) длиной ребра (х, у), приходим к задаче о построении
графа наименьшей длины. Поэтому далее в качестве стоимости дорог
примем длину ребер графа.
Дадим определение дерева. Дерево — это связный граф (то есть
такой граф, между любой парой вершин которого существует, по
крайней мере, один путь), не содержащий циклов (то есть ациклический
граф). Ацикличность означает, что в дереве существует только по
одному пути между парами вершин.
Граф наименьшей длины всегда является деревом, так как если
бы он содержал цикл, можно было бы удалить одно из ребер этого
цикла и вершины все еще остались бы соединенными. Следовательно,
для соединения п вершин нужно построить п-1 ребро.
Покажем, что граф наименьшей длины можно построить,
пользуясь следующим правилом. Прежде всего, соединяем две
вершины с наиболее коротким ребром u i . На каждом из следующих
шагов добавляем самое короткое из ребер u 1 , при присоединении
которого к уже имеющимся ребрам не образуется никакого цикла. Если
имеется несколько ребер одинаковой длины, то выбираем любое из них.
Каждое дерево Q, построенное таким образом, будем называть
экономическим деревом. Его длина равна сумме длин отдельных
ребер:
l(Q)  lu1  ...  lu n 1
(1)
60
Рисунок 5 Построение графа наименьшей длины
Покажем, что никакое другое дерево, соединяющее те же
вершины, не может иметь длину, меньшую длины экономического
дерева Q
Пусть Р - дерево наименьшей длины, соединяющее
рассматриваемые вершины, а Q - любое экономическое дерево.
Предположим, что ребра u 1 , u 2 ...u n i занумерованы в том порядке, в
котором они присоединялись при построении Q, т. е. удовлетворяют
условию l( u k ) l( u k 1 ). Если дерево Р не совпадает с Q, то Q имеет по
меньшей мере одно ребро не принадлежащее Р. Пусть u i =(a, b)-первое
такое ребро и пусть L(a, b)-цепь графа Р, соединяющая вершины а и b,
как, например, на рис 1. Если ребро u1 добавить к Р, то получим цикл, а
так как Q не имеет циклов, то в этот цикл должно входить по крайней

мере одно ребро, не принадлежащее Q. Пусть это будет u i . Удалив его,
получим дерево Р' с тем же числом вершин, что и Р, длина которого

l(Р')=l(Р)+l( u i )-l( u i )
(2)

Так как граф Р имеет наименьшую длину, то l( u i ) l( u i ). Но u i
было ребром наименьшей длины, при добавлении которого к ребрами
u1 ,u2 ...ui-1 -не получается циклов. Так как при добавлении u i-1 к этим
ребрам также не получается никакого цикла, то
l(u1 ) = l(u i )
(3)
и, следовательно, Р' имеет, так же как и Р, наименьшую длину. Но Р'
имеет с экономическим деревом Q на одно общее ребро больше, чем Р.
Повторяя эту операцию несколько раз, получаем дерево наименьшей
длины, совпадающее с Q. Следовательно, Q-дерево наименьшей длины.
61
Описанный выше метод был предложен Дж. Краскалом в 1956 г.
Данный алгоритм позволяет построить экстремальный граф (граф
наименьшей длины) любого связного графа.
Граф
называется
связным, если он содержит ровно одну компоненту связности. Это
означает, что между любой парой вершин этого графа существует, по
крайней мере, один путь.
Например, необходимо построить автомобильные дороги,
связывающие девять поселков так, чтобы их суммарная длина была
наименьшей. Любые два поселка должны быть связаны дорогой либо
непосредственно, либо дорогами, проходящими через другие поселки.
Известно расстояние между поселками (в км):
Таблица 1 Расстояния между поселками
П2
П
1
П
2
П
3
П
4
П
5
П
6
П
7
П
8
П3
2
5
П4
П5
П6
П7
П8
П9
1
3
3
2
3
4
3
5
4
9
1
9
14
1
2
3
1
1
9
5
9
4
7
6
0
4
8
7
3
6
1
3
4
3
2
40
6
5
6
6
8
0
5
1
46
2
6
1
5
2
8
48
1
9
5
4
4
2
3
5
61
27
33
На первом шаге выбираем самый короткий участок искомой сети
дорог, связывающей поселки. Это дорога длиною 12 км между
поселками П2 и П3. Затем добавляем к ней дороги между П1 и П3 (13
км), П1 и П9 (14 км), П5 и П7 (15 км), П3 и П4 (18 км). Следующее
минимальное расстояние между поселками равно 19 км. Таково
расстояние между П1 и П8 и между П6 и П7. Так как обе эти дороги не
образуют цикла с уже отобранными дорогами, то обе они добавляются
62
в список. Следующие по длине (25 км и 26 км) дороги между П1, П2 и
П3, П2 или П5, П6, П7, П5. Восьмая и последняя дорога искомого
минимального остова имеет длину 28 км, она проходит между П5 и П8.
Граф наименьшей длины (экономическое дерево), связывающий девять
поселков, изображен на рис. 2. Минимальная длина дорог,
связывающих поселки, равна 138 км.
Рисунок 6 Граф наименьшей длины, связывающий девять
поселков
Замечание: алгоритм Краскала также называется алгоритмом
построения остова наименьшей стоимости, где G=(V,E) - связный
неориентированный граф, для которого задана функция стоимости,
отображающая ребра в вещественные (целые) числа; остовным деревом
для данного графа называется неориентированное дерево, содержащее
все вершины графа. Стоимость остовного дерева определяется как
сумма стоимостей его ребер.
Экстремальное дерево может быть построено для произвольного
графа, а не только для полного графа. Например, связи между
некоторыми
вершинами
могут
быть
нежелательными
или
недопустимыми.
2. ЦЕЛЬ И ПОРЯДОК РАБОТЫ
Цель работы - научится строить граф наименьшей длины.
Порядок работы:
 изучить описание работы;
 согласно своему варианту, решить заданные примеры без использования
ЭВМ;
 написать и отладить программу в соответствии с заданием;
 оформить отчет.
63
3. ЗАДАНИЯ
3.1 Задания для ручного просчета:
Исходный граф задан матрицей смежности. На вершинах данного графа
и его ребрах постройте граф наименьшей длины и определите сумму
длин его ребер в соответствии со своим вариантом.
1.
A
B
C
D
E
F
G
A
B
C
D
E
F
G
0
3
1
5
7
5
6
3
0
5
3
1
8
6
1
5
0
1
5
1
2
5
3
1
0
3
3
3
7
1
5
3
0
1
5
5
8
1
3
1
0
1
6
6
2
3
5
1
0
A
B
C
D
E
F
G
A
0
2
1
7
5
6
B
2
0
1
8
6
C
D
E
F
G
1
5
7
5
6
5
3
1
8
6
1
0
0
1
5
1
2
1
0
3
1
0
3
4
3
5
3
0
1
5
1
4
1
0
1
2
3
5
1
0
A
B
C
D
E
F
G
0
3
1
5
7
5
3
0
5
3
6
8
1
5
0
1
5
1
5
3
1
0
3
3
7
6
5
3
0
1
5
8
1
3
1
0
2
6
2
3
5
1
2.
3.
A
B
C
D
E
F
64
G
2
6
2
3
5
1
0
A
B
C
D
E
F
G
A
B
C
D
0
3
1
5
3
0
5
3
1
5
0
7
5
3
1
0
7
7
9
3
5
2
1
3
E
F
G
7
5
6
1
2
6
9
1
2
3
3
1
1
0
1
5
1
0
1
6
6
2
1
1
5
1
0
A
B
C
D
E
F
G
0
3
2
5
7
5
6
3
0
5
3
1
8
7
2
5
0
1
5
1
2
5
3
1
0
3
3
3
7
1
5
3
0
2
5
5
8
1
3
2
0
1
6
7
2
3
5
1
0
A
B
C
D
E
F
G
0
3
1
5
7
3
7
3
0
5
3
1
8
6
1
5
0
1
5
1
2
5
3
1
0
3
2
3
7
1
5
3
0
1
5
3
8
1
2
1
0
1
7
6
2
3
5
1
0
A
B
C
D
E
F
G
A
0
3
5
7
5
6
B
3
0
1
1
5
3
1
5
6
4.
5.
A
B
C
D
E
F
G
6.
A
B
C
D
E
F
G
7.
65
C
1
1
5
7
5
6
5
0
1
5
1
2
3
1
5
6
1
5
1
2
0
3
3
3
3
0
1
5
3
1
0
4
3
5
4
0
A
B
C
D
E
F
G
A
0
3
1
5
5
6
B
C
D
E
3
1
5
1
0
5
6
0
5
3
1
5
0
1
5
3
1
0
3
1
0
1
5
3
0
8
1
3
4
6
2
3
5
8
6
1
2
3
3
4
5
0
1
1
0
A
B
C
D
E
F
G
0
3
1
5
7
9
6
3
0
5
3
1
8
6
1
5
0
6
5
1
2
5
3
6
0
3
7
3
7
1
5
3
0
1
5
9
8
1
7
1
0
1
6
6
2
3
5
1
0
A
B
C
D
E
F
G
0
4
1
5
7
5
6
4
0
5
3
2
8
9
1
5
0
1
5
1
2
5
3
1
0
3
3
8
7
2
5
3
0
1
5
5
8
1
3
1
0
1
6
9
2
8
5
1
0
D
E
F
G
8.
F
G
9.
A
B
C
D
E
F
G
10.
A
B
C
D
E
F
G
66
3.2 Задания для вычисления с помощью программы:
Задан полный граф с длинами ребер. Построить для него граф
наименьшей длины, используя известную среду программирования.
4. МЕТОДИЧЕСКИЕ УКАЗАНИЯ
Рассмотрим пример построения экономического дерева:
A
B
C
D
A
0
1
7
8
B
1
0
6
7
C
7
6
0
1
D
8
7
1
0
E
8
7
1
2
Построим по заданной матрице смежности граф.
E
8
7
1
2
0
Список ребер графа упорядочим по возрастанию длины ребра:
(АB),(CD),(CE),(DE),(BC),(AC),(BC),(BE),(AD),(AE).
Включаем
в
результат ребра AB, CD,CE, ребро DE в результат не входит, так как
оно образует цикл с ранее включенными ребрами CD и CE.
Следующим в результирующее дерево включается ребро BC.
Ребра BC, BE, AD, AE из решения исключаются, так как они также
образуют циклы.
67
Определим сумму длин ребер полученного экономического
дерева:
AB+CD+CE+BC=1+1+1+6=9
Построим экономическое дерево:
Описание алгоритма Краскала на псевдокоде:
T <- пустое множкство;
VS <- пустое множество;
Построить очередь с приоритетами Q, содержащую все ребра из E;
for (v принадлежащего V) Добавить {v} к VS
while |VS|>1
{
Выбрать в Q ребро (v,w) наименьшей стоимости;
Удалить (v,w) из Q;
if v и w принадлежат различным множествам W1 и W2 из VS
{
Заменить W1 и W2 на объединение W1 и W2 в VS;
68
Добавить (v,w) к T;
}
}
Реализуем алгоритм на языке C++. Для хранения ребер и их
стоимостей воспользуемся бинарным деревом поиска, описание
которого имеет вид:
typedef unsigned int SubInt;
typedef struct Uzel *Ref;
typedef struct Uzel
{
SubInt X; //Начало дуги.
SubInt Y; //Конец дуги
int Pay; //Стоимость дуги.
Ref Left; //Указатель на левого сына.
Ref Right;//Указатель на правого сына.
};
Ясно, что в "самой левой" вершине дерева будет храниться дуга,
обладающая наименьшей стоимостью, и поиск этой вершины может
выглядеть, например, так:
UkUzel = Root; //Установили текущий указатель на корень дерева.
while (UkUzel->Left != NULL)
UkUzel = UkUzel->Left;
T1 = UkUzel->X; T2 = UkUzel->Y; //Получили ребро!
Множество VS будем хранить в линейном однонаправленном
списке с заглавным звеном, описание которого выглядит так:
typedef struct zveno *svqz;
typedef struct zveno
{
unsigned int Element[256]; // Множество из VS.
svqz Sled; // Указатель на узел.
zveno(); // Конструктор.
};
zveno::zveno()
//Обнуление элементов.
{
for(int k=0;k<256;Element[k++]=0);
}
Тогда, например, фрагмент алгоритма:
69
if v и w принадлежат различным множествам W1 и W2 из VS
{
Заменить W1 и W2 на объединение W1 и W2 в VS;
Добавить (v,w) к T;
}
запишется на языке С++ так:
Res1 = Res2 = NULL;
Poisk (UkStr,T1,&Res1);
Poisk (UkStr,T2,&Res2);
if ( Res1!=Res2 )
{
for (int k=0;k<256;k++)
if ( Res1->Element[k]==1 || Res2->Element[k]==1 )
>Element[k]=1;
Udalenie (&Res2,UkStr);
cout << "(" << T1 << " " << T2 << ") ";
}
Res1-
Пример. Построение графа наименьшей длины (алгоритм Краскала).
#include <iostream.h>
#define TRUE 1
#define FALSE 0
typedef int Boolean;
typedef unsigned int SubInt;
typedef struct Uzel *Ref;
typedef struct Uzel
{
SubInt X; //Начало дуги.
SubInt Y; //Конец дуги
int Pay; //Стоимость дуги.
Ref Left; //Указатель на левого сына.
Ref Right;//Указатель на правого сына.
};
typedef struct zveno *svqz;
typedef struct zveno
{
unsigned int Element[256];
svqz Sled;
70
zveno();
};
zveno::zveno()
{
for(int k=0;k<256;Element[k++]=0);
}
class Spisok
{
private:
Ref Root;
void Search (int, int, int, Ref *);
void Poisk (svqz, SubInt, svqz *);
void Postroenie (svqz *);
void Udalenie (svqz *, svqz);
public:
Spisok() { Root = NULL;} //Вначале дерево пусто.
void Reshenie();
void Postr();
};
void Spisok::Search (int A, int B, int C, Ref *p)
//Добавление вершины, содержащей поля A,B,C, в дерево *p.
{
if ( (*p) == NULL )
{
(*p) = new (Uzel); (**p).X = A; (**p).Y = B; (**p).Pay = C;
(**p).Left = (**p).Right = NULL;
}
else
if ( C<=(**p).Pay ) Search (A,B,C,&((**p).Left));
else
if ( C>(**p).Pay ) Search (A,B,C,&((**p).Right));
}
void Spisok::Postroenie (svqz *UkStr)
//Постpоение линейного однонапpавленного списка
//с заглавным звеном, содержащего вершины графа.
{
svqz UkZv;
int el;
(*UkStr) = new (zveno);
71
UkZv = (*UkStr); UkZv->Sled = NULL;
cout << "Вводите вершины графа: \n";
cin >> el;
while ( el!=0 )
{
UkZv->Sled = new (zveno); UkZv = UkZv->Sled;
UkZv->Element[el] = 1; UkZv->Sled = NULL;
cin >> el;
}
}
void Spisok::Postr()
//Постpоение деpева, содержащего все ребра графа.
{
int A,B,C;
cout << "Для каждого ребра вводите начальную, затем конечную\n";
cout << "вершины и стоимость ребра, их соединяющего:\n";
cin >> A >> B >> C;
while ( A!=0 )
{ Search (A,B,C,&Root);
cin >> A >> B >> C;
}
}
void Spisok::Poisk (svqz st, SubInt MENT, svqz *Res)
{
svqz q;
(*Res) = NULL; q = st->Sled;
while ( q != NULL && (*Res) == NULL )
{
if ( q->Element[MENT]==1 ) (*Res) = q;
else q = q->Sled;
}
}
void Spisok::Udalenie (svqz *zv, svqz UkStr)
//Удаление из однонапpавленного списка с заглавным звеном
//элемента, на который указывает указатель zv.
{
svqz Z; //"Стаpый" указатель.
svqz UkZv1; //"Hовый" указатель.
72
if ( (*zv)->Sled != NULL ) (**zv) = *((**zv).Sled);
else
{ Z = UkStr; UkZv1 = UkStr->Sled;
while (UkZv1 != (*zv))
{ Z = UkZv1; UkZv1 = UkZv1->Sled; }
Z->Sled = NULL; delete UkZv1;
}
}
void Spisok::Reshenie()
{
svqz UkStr; //Указатель на список.
Ref UkUzel; //Рабочий указатель на узел дерева.
Ref UkUzel1; //Рабочий указатель на узел дерева.
SubInt T1,T2;
svqz Res1,Res2;
//Построение первоначальных множеств вершин графа.
Postroenie (&UkStr);
cout <<"Ребра экономического дерева: ";
while ( UkStr->Sled->Sled != NULL )
{
UkUzel1 = Root;
//"Отстающий" указатель.
UkUzel = Root->Left; //"Опережающий" указатель.
if ( UkUzel== NULL )
{ //Выбор в дереве ребра наименьшей стоимости и ...
T1 = Root->X; T2 = Root->Y;
//... удаление этого ребра из дерева.
Root = Root->Right; delete UkUzel1;
}
else
{ //Выбор в дереве ребра наименьшей длиныи и ...
while ( UkUzel->Left != NULL )
{
UkUzel1 = UkUzel1->Left;
UkUzel = UkUzel->Left;
}
T1 = UkUzel->X; T2 = UkUzel->Y;
//... удаление этого ребра из дерева.
UkUzel1->Left = UkUzel->Right;
delete UkUzel;
73
}
//Если v и w принадлежат различным
//множествам W1 и W2 из VS ...
Res1 = Res2 = NULL;
Poisk (UkStr,T1,&Res1);
Poisk (UkStr,T2,&Res2);
if ( Res1!=Res2 )
{
for (int k=0;k<256;k++)
if ( Res1->Element[k]==1 || Res2->Element[k]==1 )
Res1->Element[k]=1;
Udalenie (&Res2,UkStr);
cout << "(" << T1 << " " << T2 << ") ";
}
}





}
void main ()
{
Spisok Tree;
Tree.Postr();
Tree.Reshenie();
}
5. СОДЕРЖАНИЕ ОТЧЕТА
наименование работы, постановку задачи;
выбранный вариант задания;
результаты решения задач без применения ЭВМ;
программу решения задачи (представляется в электронном виде);
результаты работы программы и их анализ.
6. КОНТРОЛЬНЫЕ ВОПРОСЫ
1. Сформулируйте задачу о построении графа наименьшей длины
на примере построения автомобильных дорог.
2. Дайте определение дерева.
3. Почему граф наименьшей длины всегда является деревом?
4. Какое дерево называется экономическим?
5. Опишите алгоритм построения графа наименьшей длины.
6. Пользуясь данными таблицы 1, постройте граф наименьшей
длины и найдите сумму длин ребер полученного экономического
дерева.
7.
Каковы этапы алгоритма построения остова
наименьшей стоимости? тождественен ли он алгоритму
Краскала?
74
Тема. Сети и потоки. Практическое занятие №6 Максимальный
поток в сети.
2. ОБЩИЕ СВЕДЕНИЯ
Ориентированный граф (кратко орграф) - граф, рёбрам которого
присвоено направление. Направленные рёбра именуются также дугами.
Транспортной сетью называется конечный связный орграф G(V,
E) без петель, каждой дуге которого поставлено в соответствие
некоторое неотрицательное число c, называемое пропускной
способностью дуги, и существует:
1) ровно одна вершина, в которую не заходит ни одна дуга,
называемая источником или началом сети;
2) ровно одна вершина, из которой не выходит ни одной дуги; эта
вершина называется стоком или концом сети.
Потоком сети называется неотрицательная функция f такая, что
f(e) меньше или равно c(e). (Поток не может превышать пропускную
способность дуги.)
Дуга называется насыщенной потоком f, если f(e)=c(e).
Поток называется полным, если содержит насыщенную дугу
f(e)=c(e).)
Разрезом L сети G(V,E) называется множество насыщенных дуг,
отделяющих источник s от стока t.
Сформулируем некоторые леммы.
Лемма 1. Величина потока через любой разрез одна и та же.
Лемма 2. Для любого потока f и любого разреза (X, X )
val(f0)=c(X, X ).
Лемма 3. Если для некоторого потока f0 и некоторого разреза (X ,X 0)
val(f0) = c(X0, Õ 0 ), то величина потока f0 - максимально возможная, а
пропускная способность разреза (X0, Õ 0 )- наименьшая из пропускных
способностей разрезов сети.
Пропускной способностью разреза называется сумма пропускных
способностей принадлежащих ему дуг. Мы будем рассматривать
главным образом такие разрезы, которые обладают наименьшей
возможной пропускной способностью, — так называемые минимальные
разрезы.
75
Величина любого потока не превышает пропускной способности
любого разреза, и, следовательно, величина любого максимального
потока не превышает пропускной способности любого минимального
разреза. Однако сразу не ясно, что два последних числа всегда равны
между собой; этот замечательный результат называется теоремой о
максимальном потоке и минимальном разрезе. Впервые она была
доказана Фордом и Фалкерсоном Теорема (о максимальном потоке и
минимальном разрезе). Во всякой сети величина любого
максимального потока равна пропускной способности любого
минимального разреза.
Отметим еще раз, что сетью называют взвешенный орграф с
двумя выделенными вершинами: истоком и стоком.
Вес дуг означает, как правило, пропускную способность дуги.
Задача о наибольшем потоке в сети не единственная, но вероятно,
основная задача для потоков в сети. Очевидно практическое применение
решения этой задачи для решения транспортных проблем (пробки на
дорогах это и есть насыщение сети или отдельной ее дуги), проблем
транспортировки нефтепродуктов или электроэнергии.
2. ЦЕЛЬ И ПОРЯДОК РАБОТЫ
Цель работы -Изучить алгоритм определения
потока






максимального
Порядок выполнения работы:
изучить описание работы;
согласно своему варианту задания, решить заданные примеры без
применения ЭВМ
разработать алгоритмы решения отдельных задач и оформить в
виде процедур
разработать и отладить программу в соответствии с заданием;
проверить с помощью программы результат ручного просчета.
оформить отчет.
3. ЗАДАНИЯ
3.1 Задания для ручного просчета:
Дана сеть (G,), s – источник, t – сток сети, :EN (Цифрами
указаны пропускные способности дуг ). Построить максимальный
поток для сети, соответствующей вашему варианту
76
1)
2
1
2
3
5
s
4
t
7
8
2)
2
3
4
4
s
7
t
5
1
2
3)
3
2
3
4
s
7
3
4
t
4
4)
4
6
3
4
77
t
5
s
4
5
5)
2
6
6
7
s
t
5
5
2
9
3
6)
3
6
2
5
1
s
6
t
4
3
4
7)
3
7
1
3
6
s
t
5
2
5
78
3.2 Задания для вычисления с помощью программы
Дан граф:
1
6
11
16
21
2
7
12
17
22
3
8
13
18
23
4
9
14
19
24
5
10
15
20
25
Согласно своему варианту разработать программу для
максимального
потока,
используя
известную
вам
программирования.
поиска
среду
1. МЕТОДИЧЕСКИЕ УКАЗАНИЯ
Рассмотрим решение задачи методом Форда-Фалкерсона.
Задана пропускная способность дуг транспортной сети (рис. 1) с
началом в вершине 1 и концом в вершине 8. Используя алгоритм ФордаФалкерсона, найти максимальный поток по сети.
79
Рисунок 7
Решение
Алгоритм из двух частей — насыщение потока и его
перераспределение. В первой части задача ставится локально. Дуги
рассматриваются отдельно (возможно хаотично) и каждой дуге
приписывается возможно больший поток, согласованный только с
условием сохранения в узлах (вершинах). Во второй части
перераспределения потока выполняется из условия достижения общего
по сети максимума потока.
Рассмотрим алгоритм Форда — Фалкерсона:
Дан граф G(V,E) с пропускной способностью c(u,v) и потоком
f(u,v) = 0 для ребер из u в v. Необходимо найти максимальный поток из
источника s в сток t. На каждом шаге алгоритма действуют те же
условия, что и для всех потоков:

. Поток из u в v не превосходит пропускной
способности.

.

для всех узлов u, кроме s и t.
Поток не изменяется при прохождении через узел.
Остаточная сеть Gf(V,Ef) — сеть с пропускной способностью
cf(u,v) = c(u,v) − f(u,v) и без потока.
Вход Граф
с пропускной способностью , источник
и сток
Выход Максимальный поток из в
1.
для всех ребер
2. Пока есть путь из в в , такой что
для всех
ребер
:
1. Найти
2. Для каждого ребра
2.
3.
1. Насыщение потока (нахождение наибольшего потока)
80
Поток называется насыщенным, если любой путь из истока (1) в сток (8)
содержит насыщенную дугу.
Рассмотрим путь 1-2-4-6-8. Пропустим через этот путь поток
равный 4. При этом дуга 2-4 и 4-6 будут насыщенными. Аналогично,
путь 1-3-5-7-8 насытим потоком 4. Распределение потока отметим на
графе. В числителе ставим пропускную способность, в знаменателе —
поток. Числитель всегда больше знаменателя, знаменатель может быть и
нулем.
Рисунок 8
Заметим, что из 1 в 8 есть еще ненасыщенный путь 1-3-2-5-4-7-6-8,
в котором можно увеличить поток на 2. При этом насытятся дуги 1-3, 25, 4-7.
Рисунок 9
Из 1 в 8 больше нет ненасыщенных путей. По дуге 1-3 двигаться
нельзя (она уже насыщена), а движение по дуге 1-2 заканчивается в
вершине 2, так как обе выходящие из нее дуги насыщены.
2. Перераспределение потока (построение наибольшего
потока).
Найдем последовательность вершин из 1 в 8, такую, что дуги,
соединяющие соседние вершины, направленные из 1 в 8 ненасыщены, а
дуги, направленные в обратном направлении не пусты. Имеем
единственную последовательность 1-2-3-5-7-6-8. Перераспределяем
поток. Поток в дугах прямого направления увеличиваем на 1, а поток в
дугах обратного направления уменьшаем на 1. Процесс продолжаем до
тех пор, пока одна из прямых дуг будет насыщена или какая-нибудь
обратная дуга будет пуста.
81
Рисунок 10
Поток в насыщенной сети можно посчитать по потоку
выходящему из истока 1, или по входящему в 8. Очевидно, эти числа
должны быть равны. Кроме этого для проверки решения следует
проверить условие сохранения потока по узлам. В каждый узел
суммарный входящий поток должен быть равен выходящему. В
рассматриваемом примере поток равен 11.
 Алгоритм нахождения максимального потока в сети
поиском в ширину (алгоритм Эдмондса-Карпа)
FindPath(source, target) - поиск пути по которому возможно пустить
поток алгоритмом обхода графа в ширину, функция ищет путь из истока
в сток по которому еще можно пустить поток, считая вместимость
ребера (i,j) равной c[i][j] - f[i][j]
// f - массив содержащий текушее значение потока
// f[i,j] - поток текущий от вершины i к j
// kv – количество вершин графа
//функция поиска максимального потока
public int MaxFlow(int source, int target) // source - исток, target - сток
{
// инициализируем переменные:
for (int j = 0; j < kv; j++)// по графу ничего не течет
for (int r = 0; r < kv; r++)
f[j, r] = 0;
int MaxFl = 0; // начальное значение потока
int AddFlow;
do
{
// каждую итерацию ищем какой-либо простой путь из истока в сток
// и какой еще поток моожет быть пущен по этому пути
AddFlow = FindPath(source, target);
82
MaxFl += AddFlow;
} while (AddFlow > 0); // повторяем цикл пока поток
увеличивается
return MaxFl;
}
 Реализуем алгоритм поиска максимального потока в сети на
языке Pascal
#include <stdio.h>
#include <math.h>
int C[202][202],F[202][202],P[202][2],oo=(1<<25),;
bool fl;
int MIN(int A,int B)
{
if(A<B) return A;
return B;
}
void Stream(int N,int i)
{
if(P[i][0]>0) F[P[i][0]-1][i]+=P[N-1][1];
else F[i][abs(P[i][0])-1]-=P[N-1][1];
if(abs(P[i][0])!=N-1) Stream(N,abs(P[i][0])-1);
}
void Mark(int N)
{
bool *Nnew=new bool[N];
int i,seek=N-2;
for(i=0;i<N;i++) Nnew[i]=1;
P[seek][0]=seek+1;
P[seek][1]=oo;
while(!P[N-1][0] && fl)
{
for(i=0;i<N;i++)
if(!P[i][0] && (C[seek][i] || C[i][seek]))
{
if(F[seek][i]<C[seek][i])
{
P[i][0]=seek+1;
P[i][1]=MIN(P[seek][1],C[seek][i]-F[seek][i]);
}
else if(F[i][seek]>0)
{
P[i][0]=-seek-1;
P[i][1]=MIN(P[seek][1],F[i][seek]);
}
}
Nnew[seek]=0;
seek=0;
while(seek<N && (!Nnew[seek] || !P[seek][0])) seek++;
if(seek>=N) fl=0;
83
}
}
bool FordF(int N)
{
while(1)
{
for(i=0;i<N;i++) P[i][0]=0;
Mark(N);
if(!fl) break;
Stream(N,N-1);
}
}
 На языке C алгоритм можно реализовать следующим
образом:
Идея данного алгоритма состоит в нахождении сквозных путей с
положительными потоками от источника к стоку.
#include <iostream.h>
#include <stdlib.h> //Для функции abs().
#define TRUE 1
#define FALSE 0
#define MaxNodes 5
//Количество вершин.
#define MaxInt 1000 //Машинный эквивалент бесконечности.
//Описание типа узла.
struct Uzel
{
int Element; //Заданный номер вершины.
int Propusk; //Пропускная способность.
int Metka;
//Помечена вершина или нет.
};
class Spisok
{
private:
int C[MaxNodes][MaxNodes];
//Матрица начальных пропускных
способностей.
int c[MaxNodes][MaxNodes];
//Матрица конечных пропускных
способностей.
int Put[MaxNodes][MaxNodes]; //Матрица сквозных путей.
int Potok [MaxNodes];
//Потоки.
int Est (Uzel*,int,int);
int Tpk (int*,int,int);
public:
void Vvod_Ves();
int Reshenie ();
void Vyvod(int);
};
void main()
{
Spisok A;
A.Vvod_Ves();
A.Vyvod(A.Reshenie());
}
void Spisok::Vvod_Ves()
84
//Ввод матрицы пропускных способностей.
{
cout << "Вводите пропускные способности ребер:\n";
for (int i=0;i<MaxNodes;i++)
for (int j=0;j<MaxNodes;j++)
{
cout << "Введите C[" << (i+1) << "," << (j+1) << "]: ";
cin >> C[i][j];
c[i][j] = C[i][j];
}
}
void Spisok::Vyvod(int n)
//Вывод результатов.
{
//Вычисление максимального объема потока.
for (int i=0,sum=0;i<=n;sum+=Potok[i++]);
cout << "\nМаксимальный объем потока в сети: " << sum;
cout << "\nЗначения потоков по различным ребрам:\n";
for (i=0;i<MaxNodes;i++)
for (int j=i;j<MaxNodes;j++)
if (C[i][j])
{
cout << "Ребро (" << (i+1) << "," << (j+1) <<"): ";
cout << "(" << C[i][j] << "," << C[j][i] << ")-(";
cout << c[i][j] << "," << c[j][i] << ")=(";
cout << (C[i][j]-c[i][j]) << "," << (C[j][i]-c[j][i]) << ") ";
cout << "Поток: " << abs(C[i][j]-c[i][j]) << " ";
if (C[i][j]-c[i][j]!=0)
{
cout << "Направление: ";
if (C[i][j]-c[i][j]>0)
cout << (i+1) << "->" << (j+1);
else
cout << (j+1) << "->" << (i+1);
}
cout << endl;
}
}
int Spisok::Reshenie()
{
Uzel SS[MaxNodes]; //Множество узлов, в которые можно перейти.
Uzel S[MaxNodes]; //Путь.
int i,j=0,k,el,mx,mn;
int m; //Текущее количество вершин в пути.
int nomer=-1; //Текущее количество сквозных потоков.
int Tupik[MaxNodes]; //Перечень "тупиковых" вершин.
int N_Tupik; //Количество элементов в массиве.
while (j!=-1)
{
i=m=0;
S[i].Element=0;
S[i].Propusk=MaxInt;
S[i].Metka=TRUE;
el=0;
N_Tupik=-1;
while (el!=MaxNodes-1)
{
j=-1;
for (k=0;k<MaxNodes;k++)
if (c[i][k]!=0) //Если есть ненулевой поток...
85
if (i>0)
//и в путь уже включены вершины...
{
if (!Est(&S[0],m,k) && !Tpk(&Tupik[0],N_Tupik,k))
//то включаем текущую вершину,
//если ее нет в пути и если она не
"тупиковая".
{
SS[++j].Element=k;
SS[j].Propusk=c[i][k];
SS[j].Metka=FALSE;
}
}
else
if (!Tpk(&Tupik[0],N_Tupik,k)) //Не вернулись ли назад?
//Поток не нулевой, и это первая вершина.
{
//Включаем эту вершину в путь.
SS[++j].Element=k;
SS[j].Propusk=c[i][k];
SS[j].Metka=FALSE;
}
if (j!=-1) //Есть продолжение.
{
mx=SS[0].Propusk;
el=0;
for (k=1;k<=j;k++)
if (SS[k].Propusk>mx)
{ el=k; mx=SS[k].Propusk; }
S[++m].Element=SS[el].Element;
S[m].Propusk=mx;
S[m].Metka=TRUE;
if (SS[el].Element==MaxNodes-1) //Найден сквозной путь.
{
nomer++;
//Запоминаем сквозной путь.
for (k=0;k<=m;k++)
Put[nomer][k]=S[k].Element;
//Ищем минимальный поток.
mn=S[0].Propusk;
el=0;
for (k=1;k<=m;k++)
if (S[k].Propusk<mn)
{ el=k; mn=S[k].Propusk; }
Potok[nomer]=mn; //Запоминаем его.
//Вычисляем остаточные пропускные способности.
for (k=0;k<m;k++)
{
c[S[k].Element][S[k+1].Element] -= Potok[nomer];
c[S[k+1].Element][S[k].Element] += Potok[nomer];
}
el=MaxNodes-1; //Переход к следующей итерации.
j=0;
}
else i=S[m].Element;
}
else //Продолжения нет. Это возможно тогда, когда:
{
if (i==0) //а) все пропускные способности нулевые.
//
В этом случае - выход
el=MaxNodes-1;
else
//б) мы попали в тупик. Запомним тупиковую вершину
//
в массиве и отступим назад на одну вершину.
{
Tupik[++N_Tupik]=S[m].Element;
86
m--;
i=S[m].Element;
}
}
}
}
return nomer; //Возвращает количество сквозных потоков.
}
int Spisok::Est(Uzel S[], int m, int
//Функция проверяет, есть ли вершина
//m - текущее количество элементов в
//Возвращает 1, если вершина есть, и
{
for (int l=0;l<=m;l++)
if (S[l].Element==k) return 1;
return 0;
}
k)
k в пути S.
пути.
0 - в противном случае.
int Spisok::Tpk(int Tupik[],int N_Tupik, int k)
//Функция проверяет, есть ли вершина k в массиве "тупиковых" вершин.
//N_Tupik - текущее количество вершин в массиве.
//Возвращает 1, если вершина есть, и 0 - в противном случае.
{
if (N_Tupik==-1) return 0;
for (int l=0;l<=N_Tupik;l++)
if (Tupik[l]==k) return 1;
return 0;
}
 Поиск возможного пути из х0 в z :
k:=0;
j:=1;
usl:=0;
repeat
if graf[i,1]=j then
begin
if graf[i,5]=0 then
begin
inc(k);
mas[k]:=i;
j:=graf[i,2];
l:=i;
i:=1;
end
else
begin
inc(i);
end;
end else inc(i);
if i>count-1 then
if graf[l,2]<>n then
begin
j:=graf[l,1];
graf[l,5]:=1;
mas[k]:=0;
87
i:=1;
dec(k);
if k=0 then j:=1;
end
until (graf[l,2]=n)or(k<0);
где graf[i,j]  список инцидентности графа.
Mas[i]  массив полученного пути (указаны строки списка инцидентности которые
входят в найденный путь из х0 в z) .
Переменная к показывает количество дуг входящих в полученный путь.
Проверка на насыщенность :
for i:=1 to count-1 do
if graf[i,3]=graf[i,4] then
graf[i,5]:=1 else graf[i,5]:=0;
end;
где graf[i,5] поле списка определяющее насыщенность дуги(0- ненасыщенная , 1насыщенная ).
Насыщение найденного пути:
usl:=0;
{переменная условия выхода}
if k>=0 then
repeat
for i:=1 to k do
begin
l:=mas[i];
graf[l,4]:=graf[l,4]+1;
end;
for i:=1 to k do
begin
l:=mas[i];
if graf[l,4]=graf[l,3] then usl:=1;
end;
until usl=1;
5. СОДЕРЖАНИЕ ОТЧЕТА




виде);

наименование работы, постановку задачи;
выбранный вариант задания;
результаты решения задач без применения ЭВМ;
программу решения задачи (представляется в электронном
результаты работы программы и их анализ.
6. КОНТРОЛЬНЫЕ ВОПРОСЫ
1. Что называется ориентированным графом?
2. Дайте определение транспортной сети.
3. Может ли поток превышать пропускную способность дуги?
88
Какая дуга называется насыщенной?
Дать определение разреза.
Сформулируйте три леммы.
Кем была впервые предложена теорема о максимальном
потоке и минимальном разрезе? Сформулируйте ее.
8. Каково практическое применение задачи о максимальном
потоке?
9. Раскройте этапы алгоритма Форда—Фалкерсона.
10. На примере рис. 5 рассмотреть оба этапа алгоритма
Форда— Фалкерсона.
4.
5.
6.
7.
Рисунок 11
89
Тема. Сети и потоки. Практическое занятие №7 Максимальные
паросочетания.
2. ОБЩИЕ СВЕДЕНИЯ
Пусть G(V, E) — неориентированный граф без петель.
Паросочетание — произвольное подмножество попарно несмежных
ребер графа. Замечание.
Паросочетанием можно назвать и сам граф, если все его ребра
составляют паросочетание (регулярный граф степени 1). Мощность
паросочетания равна числу ребер, составляющих паро- сочетание.
Максимальное паросочетание — паросочетание, не содержащееся в
паросочетании большей мощности.
Наибольшее паросочетание — максимальное паросочетание с
наибольшей мощности среди всех максимальных паросочетаний
графа. Совершенное паросочетание — паросочетание, покрывающее
все вершины графа (т.е. каждая вершина графа инцидентна какомулибо ребру паросочетания). В графах, изображенных на рис.1
выделены максимальные паросочетания. Причем в последнем случае
паросочетание является совершенным.
Рис.1
Двудольный граф — граф, множество вершин которого состоит из
двух непересекающихся подмножеств (долей) попарно несмежных
вершин.
Замечание. В двудольном графе смежными могут быть только
вершины из разных долей.
Полный двудольный граф — двудольный граф, множество ребер
которого содержит все возможные ребра.
Матрица смежности двудольного графа G(X, Y, E) где X = {x1, x2, ...,
xm}, Y = {y1, y2, ..., yn} — матрица AXY (G) порядка m × n, элементы
которой определяются следующим образом: aij равен числу ребер,
соединяющих вершины xi ∈ X и yj ∈ Y .
90
Матрица весов двудольного нагруженного графа G(X, Y, E), где X =
{x1, x2, ..., xm}, Y = {y1, y2, ..., yn}, — матрица WXY (G) по- рядка m ×
n, элементы которой определяются следующим образом: wij равен весу
ребра (xi , yj ), если вершины смежны; wij = ∞, если вершины не
смежны.
Критерий двудольности графа. Граф является двудольным тогда и
только тогда, когда все его простые циклы имеют четную длину.
Теорема Холла. Для того чтобы в двудольном графе G(X, Y, E)
существовало паросочетание покрывающее все вершины множества X
необходимо и достаточно, чтобы для любого подмножества A ⊆ X
выполнялось неравенство |A| ≤ |Γ(A)|.
Следствие 1. Для того чтобы в двудольном графе существовало
совершенное паросочетание необходимо чтобы доли имели одинаковое
количество вершин.
Следствие 2. Для того чтобы в двудольном графе существовало
совершенное паросочетание достаточно, чтобы все его вершины имели
одинаковую степень (не равную нулю).
АЛГОРИТМ ПОСТРОЕНИЯ НАИБОЛЬШЕГО ПАРОСОЧЕТАНИЯ В
ДВУДОЛЬНОМ ГРАФЕ
Пусть G(X, Y, E) — двудольный граф, в котором выделено некоторое
паро- сочетание P. Обозначим Xp и Yp множества вершин, инцидентных
ребрам паросочетания P (Xp ⊆ X и Yp ⊆ Y ).
Шаг 1. Строим орграф G(X, Y, E ) следующим образом: все ребра,
входящие в паросочетание P преобразуем в дуги, направленные из Y в
X, а все ребра, не входящие в паросочетание P преобразуем в дуги,
направленные из X в Y .
Шаг 2. В орграфе G ищем путь из какой-либо вершины u ∈ X \ Xp в
какую-либо вершину v ∈ Y \ Yp . Для этого выполняем поиск в ширину
из множества вершин X \ Xp . Если в результате поиска ни одна из
вершин множества Y \ Yp не получила метки, то алгоритм заканчивает
работу; P — наибольшее паросочетание.
Шаг 3. Пусть v ∈ Y \Yp некоторая вершина, получившая метку при
поиске в ширину. Следовательно в G существует путь u, w1, w2, . . . , wk,
v, u ∈ X \ Xp . Преобразуем паросочетание P и, соответственно, граф G
следующим образом. Добавляем в паросочетание P ребра,
соответствующие дугам пути, идущим из вершин множества X \ XP в
вершины множества Y \ Yp , а ребра, соответствующие дугам пути,
идущим из вершин множества Y в вершины множества X удаляем: Xp :=
Xp ∪ {u}, Yp := Yp ∪ {v},
Ep :=( Ep \{(w1,w2),(w3,w4), ...,(wk−1,wk)}) ∪ {(u,w1),(w2,w3),...,(wk,v)}.
Мощность паросочетания P при этом увеличивается на 1. Возвращаемся
на шаг 1.
91
ПРИМЕР: В двудольном графе, заданном матрицей смежности, найти
наибольшее паросочетание.
РЕШЕНИЕ:
Построим данный граф. Выделим в нем некоторое максимальное
паросочетание
P: Xp = {x3, x5}, Yp = {y2, y3}, P = {(x3, y2),(x5, y3)}.
Построим также орграф G(X, Y, E )
G
P
¯G
Выполним из множества вершин {x1, x2, x4} поиск в ширину. В
результате поиска получит метку вершина y4: x1, y2, x3, y4.
В паросочетание добавляем ребра (x1, y2), (x3, y4) и удаляем ребро (x3,
y2).
92
Поиск в ширину
Р
G
Xp = {x1, x3, x5}, Yp = {y2, y3, y4}, P = {(x1, y2),(x3, y4),(x5, y3)}.
Выполним поиск в ширину из множества вершин {x2, x4}. В
результате поиска получит метку вершина y1: x4, y3, x5, y1. В
паросочетание добавляем ребра (x4, y3), (x5, y1) и удаляем ребро (x5, y3)
Поиск в ширину
Р
Xp = {x1, x3, x4, x5},
Yp = {y1, y2, y3, y4}, P = {(x1, y2),(x3,
y4),(x4, y3),(x5, y1)}.
Так как Yp = Y , то алгоритм прекращает работу.
P — наибольшее паросочетание.
2. ЦЕЛЬ И ПОРЯДОК РАБОТЫ
Цель работы - научится находить максимальное паросочетание в
графе, применяя выбранный Вами алгоритм.
Порядок работы:
 изучить описание работы;
 согласно своему варианту, решить заданные примеры без
использования ЭВМ;
 написать и отладить программу в соответствии с заданием;
93
 оформить отчет.
3. ЗАДАНИЯ
3.1Задание для ручного просчета:
Найти: наибольшее паросочетание в двудольном графе, заданном
матрицей смежности:
2
1
3
4
5
6
7
8
9
10
94
3.2 Задание для вычисления с помощью программы:
Для заданного пользователем двудольного графа, реализовать
алгоритм, определяющий максимальное паросочетание.
4. МЕТОДИЧЕСКИЕ УКАЗАНИЯ
Пример решения:
ЗАДАНИЕ В двудольном графе, заданном матрицей смежности, найти
наибольшее паросочетание.
РЕШЕНИЕ:
Построим данный граф. Выделим в нем некоторое максимальное
паросочетание
P: Xp = {x3, x5}, Yp = {y2, y3}, P = {(x3, y2),(x5, y3)}.
Построим также орграф G(X, Y, E )
G
P
¯G
Выполним из множества вершин {x1, x2, x4} поиск в ширину. В
результате поиска получит метку вершина y4: x1, y2, x3, y4.
В паросочетание добавляем ребра (x1, y2), (x3, y4) и удаляем ребро (x3,
y2).
95
Поиск в ширину
Р
G
Xp = {x1, x3, x5}, Yp = {y2, y3, y4}, P = {(x1, y2),(x3, y4),(x5, y3)}.
Выполним поиск в ширину из множества вершин {x2, x4}. В
результате поиска получит метку вершина y1: x4, y3, x5, y1. В
паросочетание добавляем ребра (x4, y3), (x5, y1) и удаляем ребро (x5, y3)
Поиск в ширину
Р
Xp = {x1, x3, x4, x5},
Yp = {y1, y2, y3, y4}, P = {(x1, y2),(x3,
y4),(x4, y3),(x5, y1)}.
Так как Yp = Y , то алгоритм прекращает работу.
P — наибольшее паросочетание.
В работе можно использовать следующие фрагменты программ,
представленные на языке C++.
//алгоритм Куна поиска максимального паросочетания
bool kuhn(int v) {
//если вершина является пройденной, то не производим из нее
вызов процедуры
if (used[v]) {
return false;
}
96
used[v] = true; //помечаем вершину первой доли, как
пройденную
//просматриваем все вершины второй доли, смежные с
рассматриваемой вершиной первой доли
for (int i = 0; i < adj[v].size(); ++i) {
int w = adj[v][i];
//нашли увеличивающую цепь, добавляем ребро (v, w) в
паросочетание
if (mt[w] == -1 || kuhn(mt[w])) {
mt[w] = v;
return true;
}
}
return false;
}
//процедура считывания входных данных с консоли
void readData() {
//считываем количество вершин в первой и второй доли и
количество ребер графа
scanf("%d %d %d", &n1, &n2, &m);
//инициализируем список смежности размерности n1
adj = new vector<int>[n1];
//считываем граф, заданный списком ребер
for (int i = 0; i < m; ++i) {
int v, w;
scanf("%d %d", &v, &w);
v--;
w--;
//добавляем ребро (v, w) в граф
adj[v].push_back(w);
}
used.assign(n1, false);
mt.assign(n2, -1);
}
void solve() {
//находим максимальное паросочетание
for (int v = 0; v < n1; ++v) {
used.assign(n1, false);
//если нашли увеличивающую цепь,
//то размер максимального паросочетания увеличиваем на 1
if (kuhn(v)) {
97
mtSize++;
}
}
}
void printData() {
printf("%d\n", mtSize);
for (int i = 0; i < n2; ++i) {
if (mt[i] != -1) {
printf("%d %d\n", mt[i] + 1, i + 1);
}
}
}
int main()
{
readData();
solve();
printData();
return 0;
}
5. СОДЕРЖАНИЕ ОТЧЕТА




виде);

наименование работы, постановку задачи;
выбранный вариант задания;
результаты решения задач без применения ЭВМ;
программу решения задачи (представляется в электронном
результаты работы программы и их анализ.
6. КОНТРОЛЬНЫЕ ВОПРОСЫ
7) Что называется паросочетанием?
8) Что такое максимальное паросочетание?
9) Что такое наибольшее совершенное паросочетание?
10)
Что называется двудольным и полным двудольным
графом?
11)
Сформулируйте теорему Холла.
12)
Опишите алгоритм нахождения максимального
паросочетание.
13)
Как найти наибольшее паросочетание?
98
99
Тема. Конечные автоматы. Практическое занятие №8 Решение
задач на эмуляторе машины Поста
1. ОБЩИЕ СВЕДЕНИЯ
1.1. «Внешний вид» машины Поста
Машина Поста не есть реально существующее, сделанное кем-то
устройство. Она представляет собой мысленную конструкцию.
Машина Поста состоит из ленты и каретки. Лента бесконечна и
разделена на секции одинакового размера. Порядок в котором
расположены секции ленты, подобен порядку, в котором расположены
все целые числа. Поэтому принято рассматривать ленту, как
«целочисленную систему координат» (рис.1).
-6 -5 -4 -3 -2 -1
0 1
2
3 4
5 6
Рис.1
В каждой секции ленты может быть либо ничего не записано
(пустая секция), либо записана метка V. Информация о том, какие
секции пусты, а какие отмечены, образует состояние ленты.
Каретка может передвигаться вдоль ленты влево и вправо. Когда
она неподвижна, она стоит ровно против секции ленты; говорят, что
каретка обозревает эту секцию, или держит ее в поле зрения.
Информация о том, какие секции пусты, а какие отмечены и где
стоит каретка, образует состояние машины Поста.
-6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6
vv
v
v v
За единицу времени (шаг) каретка может сдвинуться на одну секцию
влево или вправо. Кроме того, каретка может поставить или уничтожить
(стереть) метку в той секции, против которой она стоит, а также
распознать, стоит или нет метка в обозреваемой ею секции.
1.2. Программа машины Поста
Работа машины Поста состоит в том, что каретка передвигается
вдоль ленты и печатает или стирает метки. Эта работа происходит
согласно программе.
Каждая программа машины Поста состоит из команд. Существует
шесть видов команд (буквы i, j, j1, j2 означают натуральные числа):
1. Команда движения вправо.
ij
100
2. Команда движения влево.
ij
3. Команда печатания метки.
i v j
4. Команда стирания метки.
i j
5. Команда передачи управления.
j1 если секция пуста
i ?
j2 если секция отмечена
6. Команда остановки.
i стоп.
Число i, стоящее в начале команды, называется номером команды.
Число j, стоящее в конце команды—отсылка. У команды остановки нет
отсылки.
Программа машины Поста—конечный непустой список команд
машины Поста, обладающий следующими двумя свойствами:
1) на первом месте в этом списке стоит команда с номером 1, на
втором месте- команда с номером 2 и т.д.; вообще на k- том месте стоит
команда с номером k;
2) отсылка любой из команд списка совпадает с номером
некоторой (другой или той же самой) команды списка.
2.ЦЕЛЬ И ПОРЯДОК РАБОТЫ
Цель работы—получить первичные знания об алгоритмических
системах, ознакомиться с работой машины Поста, овладеть навыками
написания программ для машины Поста.
Работу следует выполнять в таком порядке:
 изучить описание работы;
 написать программы для реализации основных задач на машине
Поста;
 написать эмулятор машины Поста на языке Turbo Pascal;
 по индивидуальному заданию написать программу машины
Поста, затем выполнить ее на созданном эмуляторе;
 Классифицировать машину Поста как конечный автомат и
обосновать
 оформить отчет.
3. ЗАДАНИЯ
3.1. Написать пять программ машины Поста и осуществить их
реализацию на существующем эмуляторе.
a) На ленте имеется машинная запись числа N, представленная в
виде массива из N+1 меток. Каретка находится против самого левого
элемента массива. Требуется записать число N+1, добавив метку справа
к массиву.
101
b) Дан массив из 2*N-1 меток. Каретка находиться слева от
массива. Требуется стереть среднюю метку.
c) Дан массив из 2*N меток. Каретка находится слева от массива.
Требуется раздвинуть две половины массива на одну секцию.
d) Дано два массива, расположенных на произвольном расстоянии
друг от друга. Каретка находится слева от массивов. Требуется сложить
массивы.
e) На ленте имеется машинная запись числа N (массив N+1
меток). Требуется записать число N+1. Положение каретки произвольно.
[УКАЗАНИЕ. Необходимо рассмотреть два случая: каретка расположена
над заполненной секцией, тогда задача сводится к первой из
предложенных; каретка расположена над пустой секцией, тогда нужно
осуществить поиск массива]
3.2.На языке программирования Turbo Pascal написать простейший
эмулятор машины Поста.
3.3.Согласно варианту выбрать задание и написать программу
машины Поста. Реализацию программы осуществить на
разработанном эмуляторе.
1) Разделить заданное число на два.
2) Разделить заданное число на три.
3) Разделить заданное число на четыре.
Примечание. Каретка слева от массива. Начальное состояние ленты машинная запись делимого; конечное состояние - частное.
Пояснение. Под делением понимается нахождение частного или
неполного частного, так что результат деления 7 на 3 будет 2.
4) Разделить одно число на другое.
Примечание. Каретка слева от массивов. Начальное состояние ленты
машинная запись делимого и делителя; конечное состояние частное.
Пояснение. Под делением понимается нахождение частного или
неполного частного, так что результат деления 7 на 3 будет 2.
5) Вычесть одно число из другого.
Примечание. Каретка слева от массивов. Начальное состояние ленты
-два массива, расположенных на произвольном расстоянии (причем
первый слева массив- уменьшаемое, второй-вычитаемое); конечное
состояние- разность.
Пояснение. Если вычитание невозможно (вычитаемое больше
уменьшаемого), программа не должна приводить к результативной
остановке.
6) Умножить заданное число на два.
7) Умножить заданное число на три.
8) Умножить заданное число на четыре.
Примечание. Каретка слева от массива. Начальное состояние ленты 102
машинная запись умножаемого; конечное состояние - произведение
9) Перемножить два числа.
Примечание. Каретка слева от массивов. Начальное состояние ленты
машинная запись двух чисел; конечное состояние - произведение.
10)Найти НОД (наибольший общий делитель) двух чисел.
Примечание. Каретка слева от массивов. Начальное состояние ленты
машинная запись двух чисел; конечное состояние - НОД.
11) Найти сумму двух чисел.
Примечание. Положение каретки произвольно. Начальное состояние
ленты -два массива, расположенных на произвольном расстоянии;
конечное состояние- сумма.
Пояснение. Необходимо предусмотреть поиск массивов, т.к.
неизвестно ни положение каретки, ни расположение массивов
относительно друг друга.
12) Найти выражение (a+b)*c.
Примечание. Каретка слева от массивов. Начальное состояние ленты
-первый массив слева -число a, второй массив- число b, третий
массив- число с; конечное состояние- результат.
13) Перемножить два числа.
Примечание. Положение каретки произвольно. Начальное состояние
ленты -два массива, расположенных на произвольном расстоянии;
конечное состояние- произведение.
Пояснение. Необходимо предусмотреть поиск массивов, т.к.
неизвестно ни положение каретки, ни расположение массивов
относительно друг друга.
14) Возвести число в квадрат.
15) Возвести число в куб.
Примечание. Каретка слева от массива. Начальное состояние ленты машинная запись числа; конечное состояние- результат.
4. МЕТОДИЧЕСКИЕ УКАЗАНИЯ
4.1. Создание эмулятора машины Поста.
Эмулятор должен представлять собой ленту с расположенными на
ней метками и каретку, находящуюся напротив определенной секции.
Рекомендуется для описания состояния ленты использовать
массив булевых элементов (например 100 элементов. Ограничение
ленты упрощает работу). При этом в начале работы каретка находится
напротив нулевой секции ( 50-тый элемент массива). В эмуляторе
103
каретка всегда остается на месте, а передвигаются лента, программно
это означает перерисовывание меток.
Проще рисовать эмулятор в текстовом режиме, используя символы
ASCII для рисования таблиц.
Программу для машины Поста удобнее генерировать в файле, т.о.
отпадает необходимость вводить ее каждый раз с клавиатуры.
Примерные фрагменты процедур
Процедура вывода рамки ленты и каретки
procedure lenta_wid;
begin
textcolor (7);
gotoxy (1,6);
{Рисование заголовка (верхняя треть) ленты}
write (#194);
for i:=1 to 39 do
write (#196,#194);
write (#196);
{Середина ленты}
for i:=1 to 40 do
write (#179,#32);
{Подвал ленты}
write (#193);
for i:=1 to 39 do
write (#196,#193);
write (#196);
{Изображение каретки}
gotoxy (40,5);
textcolor (14);
write (c00);
end;
Процедура работы с клавиатурой
procedure key;
begin
b:=false; gotoxy (40,5);
c:=readkey;
while keypressed do
c:=readkey; {Очистка буфера}
case c of
#32 :ln[n]:=not (ln[n]); {Пробел - поставить/стереть метку}
#75 :if n<>0
then n:=n-1
104
else {Курсор вправо - сдвиг ленты}
begin
gotoxy (5,10);
write ('Конец ленты')
end;
#77 :if n<>100 then n:=n+1
else {Курсор влево - сдвиг ленты}
begin
gotoxy (5,10);
write ('Конец ленты')
end;
#27,#13 : b:=true; {Esc,Enter - окончание редактирования ленты}
else b:=false
end
end;
Процедура вывода состояния текущего участка ленты
procedure obraz;
var i00 :integer;
begin
for i:=1 to 40 do
begin {Проход всего видимого участка ленты}
gotoxy (2*i,7);
{Перевод курсора в ячейку}
i00:=n-20+i;
if (i00>=0) and (i00<=100)
then {Определение границ}
{Если границы соответствуют и метка есть вывести символ метки,
иначе забить предыдущий символ данной ячейки}
if ln[i00] then write (c01)
else write (' ');
gotoxy (38,9);
write (' ',n-50,' ')
end
end;
Основная же часть программы создания эмулятора машины Поста
предлагается на собственное усмотрение.
5. СОДЕРЖАНИЕ ОТЧЕТА
Отчет должен содержать:
 наименование работы;
 текст пяти обязательных программ в тетради;
 программу создания эмулятора машины Поста (в электронном виде);
105
 текст программы машины Поста по индивидуальному заданию.
6. КОНТРОЛЬНЫЕ ВОПРОСЫ
1. Что представляет собой машина Поста?
2. Что называют состоянием ленты, а что - состоянием машины Поста?
3. Для чего предназначена каретка?
4. Какие команды могут быть использованы в программе машины
Поста?
106
1. ЦЕЛЬ И ПОРЯДОК ВЫПОЛНЕНИЯ РАБОТЫ
Цель работы - овладеть навыками написания машин Тьюринга.
Порядок выполнения:
 ознакомиться с описанием работы;
 согласно варианту задания, выданному преподавателем,
разработать алгоритмы решения поставленной задачи;
 отладить программу;
 оформить отчет
2. СВЕДЕНИЯ ИЗ ТЕОРИИ
Машина Тьюринга состоит из:
1) внутреннего алфавита - совокупности состояний { q1 , ... ,qn } и
команд для каретки.
2) внешнего алфавита А={а1, ... ,аm}, символы которого
считываются и заносятся на ленту;
3) устройства обращения к ленте, каретки, которая в каждый
момент обозревает ячейку ленты, в зависимости от символа в этой
ячейке и состояния управляющего устройства записывает в ячейку
символ ,который в соответствии с текущей командой , сдвигается на
ячейку вправо или влево или останавливается на месте; при этом
управляющее устройство переходит в новое состояние (или остается в
старом).
Таким образом, память машины Тьюринга - это конечное множество
состояний (внутренняя память) и лента (внешняя память). Лента
бесконечна в обе стороны, но в начальный момент времени только
конечное число ячеек ленты заполнено непустыми символами. Данные
машины Тьюринга - это слова в алфавите ленты; на ленте
записываются и исходные данные, и окончательные результаты.
Детерменированность машины, т.е. последовательность ее шагов,
определяется следующим образом: для любого внутреннего состояния
qi и символа aJ однозначно заданы:
а) следующее состояние q`i ;
б) символ a` J,который нужно записать вместо aJ в ту же ячейку;
в) направление сдвига каретки dk, обозначаемое одним из трех
символов: L(влево), R (вправо) , E (на месте).Это задание описывается в
виде таблицы, строкам которой соответствуют состояния, столбцам входные символы, а на пересечении строки qi и столбца aJ записана
тройка символов q`i a`J dk .
Функциональная схема:
107
aJ
qi
aJ
L
a`J
Q
C
(лево, право, на месте)
q`i
Некоторые операции над машинами Тьюринга.
Теорема 1. Если f1(x) и f2(x) вычислимы по Тьюрингу то их
композиция f2(f1(x)) также вычислима по Тьюрингу.
Пусть T1 - машина, вычисляющая f1 , а T2 - машина, вычисляющая f2 , и
множества их состояний соответственно Q1 =( q11, ... , q1n) Q2 =( q21, ... ,
q2n)
Система команд машины T строится следующим образом: система
команд T2 приписывается к системе команд T1 , при этом конечное
состояние T1 отождествляется с начальным для T2 . Построенная машина
T называется композицией машин T1 и T2 и обозначается T2(T1). Это
определение остается в силе, если T1 и T2 вычисляют функции от
нескольких перемнных. Важно лишь, чтобы данные для T2 были в
обусловленном виде подготовленны машиной T1 .
Вычисление предикатов на машинах Тьюринга.
Машина Т вычисляет предикат Р(а) (а - выражение на ленте), если
Р(а)=х, где х=И, когда Р(а) истино, и х=Л, когда Р(а) ложно. Если же Р(а)
не определен, то машина Т, как и при вычислении функций, не
останавливается. При обычном вычисленни предиката уничтожается а,
что может оказаться неудобным, если после Т должна работать другая
машина. Поэтому вводится понятие вычисления с восстановлением:
машина Т вычисляет Р(а) с восстановлением, если Р(а)=ха. Вычисление
с восстановлением можно представить следующей
последовательностью: выполняется Tкоп , каретка сдвигается до маркера
*, затем вычисляется Р(а) , и наконец х переносится в крайнее левое
положение. Машина Т является композицией указанных четырех
машин. В конкретных случаях возможны и более простые способы
восстановления а.
Пусть функция f(а) задана описанием: « если Р(а) истино, то f(а)=g1(х) ,
иначе f(а)=g2(х) ». Функция f(а) называется разветвлением или условным
переходом к g1(х) и g2(х) по условию Р(а).
Теорема 2. Если g1(x), g2(x) и Р(а) вычислимы по Тьюрингу то
разветвление g1 и g2 по Р(а) также вычислимо.
3. ЗАДАНИЕ
Создать машину Тьюринга в соответствии с номером варианта задания.
108
Для созданной машины классифицировать ее в виде конечного автомата
4. ВАРИАНТЫ ЗАДАНИЙ
1) Вычислить выражение (a+b)/c.
2) Возведение чисел в квадрат.
3) Зеркально отбразить число.
4) Вычислить выражение a(c+b).
5) Умножение нескольких чисел, записаных одно за другим через
разделитель.
6) Определить остаток от деления двух чисел.
7) Определить частное от деления двух чисел.
8) Вычислить выражение (a+b)*c.
9) Вычислить a+b , если a и b четные, и a*b , если нечетные.
10) Умножение двух чисел.
11) Вычислить a-b , если a и b четные, и a/b , если нечетные.
12) Деление нескольких чисел нацело, записаных одно за другим через
разделитель.
13) Вычислить выражение (a+b)с.
14) Определение НОД.
15) Определить челую часть от выражения (a+b)/c.
5. МЕТОДИЧЕСКИЕ УКАЗАНИЯ
При написании программ, осуществляюших операции над числами
необходимо переводить их на ленте из позиционной системы в унарное
представление. При этом число х представляется словом 1..1=1х ,
состоящим из х однотипных знаков.
Перевод числа из позиционной системы в унарное представление .
1 2 3 4 5 6 8 9 0 * _ $
Q1
Q2
Q3
Q4
q11R q12R q13R q14R q15R q16R q18R q19R Q10R q1*R q1_R q2$L
q30L q31L q32L q33L q3 4L q3 5L q3 7L q3 8L Q3 9L q4*R q3_L
q31L q31L q31L q31L q31L q31L q31L q31L Q31L q3*L q1*R
q4_R Q4_N q4_N q4_N q4_N
Каретка слева от числа , справа от числа должен стоять знак $
Приложение 1
Ручной просчет:
Задание умножить два числа.
1
_
*
0
~
q1 q2 0 R
q6 _ R
q 1* L q1 1 L
q2 q2 1 R
q3 * R
q3 * R
q2 * L
q3 q 31 R
q4 1 L
q3 1 R
109
q4
q5
q6
q7
q8
q9
q10
q4 1 L
q6 _ R
q6 1 R
q7 _ R
q10 * L
q7 1 L
q4 * E
q7 * L
q3 1 R
q7 _E
q4 * L
q6 _ R
q7 1 L
q4 * L
q5 * L
q1 0 R
q4 * L
q4 * L
q4 _L
q4 * L
q4 1 L
q1 0 L
q4 * R
q4 * L
q4 * L
Перевод числа из однотипных знаков в десятичную смстему счисления.
1
2
3
4
5
6
8
9
0
*
_
Q1
q3 2 Nq3 3 Nq3 4 Nq3 5 Nq3 6 Nq3 7 Nq3 9 Nq1 0 L q3 1 Nq1 *L q3 1 N
Q2
q2 1 R q2 2 R q 2 3 R q2 4 R q2 5 R q2 6 R q2 8 R q2 9 R q2 0 R q1 _ R q2 _ L
Q3
q3 1 R q3 2 R q 3 3 R q3 4 R q3 5 R q3 6 R q3 8 R q3 9 R q3 0 R q1 * R q1 _ L
Сложение. Во введенном представлении сложить числа a и b - это
значит слово 1a*1b переработать в слово 1a+b, т.е. удалить разделитель *
и сдвинуть одно из слагаемых, скажем первое, к другому. Это
преобразование осуществляет машина T+ со следующей системой
команд:
1
*
_
q1 q2 _ R q2 _ R
q2 q2 1 R q3 1 L
q3 q3 1 L
q3 _E
Начальное состояние : {q1E} , каретка на левом числе.
Копирование ( перезапись слова ) слова, т.е. переработка слова а в
а*а. Для чисел эту задачу решает машина Tкоп, система команд которой
приведена в таблице :
1
_
*
0
q1 q2 0 R
q1 _ E
q 1* L q1 1 L
q2 q2 1 R
q3 * R
q3 * R
q3 q 31 R
q4 1 L
q4 q4 1 L
q4 * L q1 0 R
Начальное состояние : {q1E} , каретка на левой единице левого числа.
Машина при каждом проходе исходного слова 1а заменяет левую из
его единиц нулем и пишет (в состоянии q3) одну единицу справа от 1а в
ближайшую пустую клетку. При первом проходе, кроме того, в
состоянии q2 ставится маркер *. Таким образом, копия 1а строится за а
проходов. После записи очередной единицы машина переходит в
состояние q4 , которое передвигает каретку влево от ближайшего нуля,
после чего машина переходит в q1 и цикл повторяется. Он прерывается,
110
когда q1 обнаруживает на ленте не единицу, а маркер. Это значит, что
все единицы 1а исчерпаны, т.е. сделано а проходов. Тогда каретка
возвращается влево в свое исходное положение, заменяя по дороге все
нули единицами.
Пример 3
1
_
*
0
q1 q2 0 R
q6 _ R
q 1* L q1 1 L
q2 q2 1 R
q3 * R
q3 * R
q3 q 31 R
q4 1 L
q4 q4 1 L
q4 * L q1 0 R
q5 q6 _ R
q6 _ R
q6 q6 1 R
q7 1 L
q7 q7 1 L
q7 _E
Начальное состояние : {q1E} , каретка на левой единице числа.
Это система команд машины T+(Tкоп). Она вычисляет функцию f(x)=2х ,
при этом машина Tкоп строит два числа на ленте, а T+ складывает их.
Пример 4
1
_
q1 q3 1 R q1 И E
q2 q3 1 R q4 1 L
q3 q2 1 R q5 1 L
q4 q4 _ L q4 И E
q5 q5 _ L q5 Л E
Начальное состояние : {q1E} , каретка на левой единице числа.
Машина вычисляет предикат « а - четное число » : каретка достигает
конца числа в состоянии q2 , если число единиц четно, и в состоянии q3 ,
если число единиц нечетно, после чего она перемещается в исходное
положение в состоянии q4 либо q5 и печатает И либо Л соответственно.
Для того, чтобы этот предикат вычислялся с восстановлением,
достаточно не стирать, а сохранять единицы, т.е. заменить команды
q4_L и q5_L на команды q41L и q51L .
Пример 5
а)
1
_
*
q1
q2 _ R
q4 _ R
q2
q2 1 R
q4 1 R
q3
q3 1 L
q1 _ R
q4
q4 1 R
q5 _ L
q3 * L
q5
q5 1 L
q5 _ E
Начальное состояние : {q1E} , каретка на левой единице числа.
111
Система команд машины T++ для сложения n чисел. Цикл состояний q1 ,
q2 , q3 - это « зацикленная » машина T+ , в которой заключительное
состояние совмещено с начальным. Сумма, полученная на очередном
цикле, является первым слагаемым следующего цикла. Состояние q4
реализует разветвление. В нем проверяется условие - есть ли второе
слагаемое. Если да ( о чем говорит наличме маркера * ), то происходит
переход к следующему циклу; если нет ( о чем говорит пробел поосле
единиц ) , то машина выходит из цикла.
б) Пусть машина Т с алфавитом Ат не является правильно вычисляющей
и ее заключительная конфигурация на ленте стандартна, но может
содержать любые символы Ат ( кроме проделов ) , а результат
интерпритируется как число, равное числу единиц на ленте. Построим
для Т машину T`++ , которая работает как T++ , а все символы , кроме 1 и
пробела , она воспринимает как маркеры , т.е. команды для них - те же,
что и для *. Тогда T`++ соберет все единицы в один массив и,
следовательно, T`++ (T(а)) правильно вычисляет функцию, вычисляемую
машиной T.
Аналогично тому как из машины T+ была построена T++ , можно
построить машину Tхх , которая перемножает несколько чисел, и по
схеме с использованием T`хх вместо T`++ построить машину,
осуществляющую возведение в степень.
6. СОДЕРЖАНИЕ ОТЧЕТА
Отчет должен содержать:
 наименование работы;
 текст программы машины Тьюрига по индивидуальному заданию.
7. КОНТРОЛЬНЫЕ ВОПРОСЫ
1. Что представляет собой машина Тьюринга?
2. Что называют внутренним , а что внешним состоянием машины
Тьюринга?
3. Для чего предназначена каретка?
4. Какие команды могут быть использованы в программе машины
Тьюринга?
4. Каким образом осуществляется композиция машин Тьюринга?
5. Что является памятью машины Тьюринга?
6. Что представляет из себя условный переход в алгоритмической
системе Тьюринга
112
Тема. Конечные автоматы. Практическое занятие №10
Построение минимальных автоматов
1. ОБЩИЕ СВЕДЕНИЯ
Конечный автомат состоит из конечного управления и входной
ленты, разбитой на ячейки. В каждой ячейке записан один символ из
входного алфавита Σ, и все они образуют конечную входную цепочку.
Конечное управление первоначально находится в состоянии q0 и
сканирует крайнюю левую ячейку ленты. По мере чтения входной
цепочки слева направо автомат переходит в другие состояния из
множества Q. Если, прочитав входную цепочку, автомат оказывается в
некотором конечном состоянии из множества F, то говорят, что он
принял ее. Множество цепочек, принимаемых конечным автоматом,
называется языком, распознаваемым данным конечным автоматом.
Определение.
Конечным автоматом называется формальная
система M = (Q, Σ, δ, q0, F), где Q - конечное непустое множество
состояний; Σ - конечный входной алфавит; δ - отображение типа QxΣ →
Q; q0  Q - начальное состояние; F  Q - множество конечных состояний.
Запись δ(q, a) =p, где q  p, Q и a Σ, означает, что конечный автомат M в
состоянии q, сканируя входной символ a, продвигает свою входную
головку на одну ячейку вправо и переходит в состояние p .
Автомат «вообще»- управляющая система, являющаяся конечным
автоматом или некоторой его модификацией, полученной путем
изменения его компонент или функционирования. Основное понятие конечный автомат - возникло в середине 20 века в связи с попытками
описать на математическом языке функционирование нервных систем,
универсальных вычислительных машин и других реальных автоматов.
Характерной особенностью такого описания является дискретность
соответствующих математических моделей и конечность областей
значений их параметров, что приводит к понятию конечного автомата.
113
Наряду с понятием конечного автомата рассматриваются
различные его обобщения и модификации, отражающие те или иные
особенности реальных устройств. Для конечного автомата (A, S, B, , )
существующие модификации можно разбить на следующие три
основные группы.
 К первой группе относятся автоматы, у которых некоторые из
алфавитов A (входной), S (состояний) или B (выходной)
бесконечны, в связи с чем такие автоматы называются
бесконечными.
 Ко второй группе относятся автоматы, у которых вместо выходной
и переходной функций  и  допускаются произвольные
отношения или случайные функции. Таковы частичные,
недетерминированные, вероятностные и другие автоматы.
 К третьей группе относятся автоматы со специфическими
множествами входных объектов. Таковы, например, автоматы с
переменной структурой.
Существуют автоматы, принадлежащие одновременно разным
группам. Наряду с этим большую роль играют специальные подклассы
конечных автоматов, например, автоматы без памяти. Кроме того,
использование понятий и методов из других разделов математики также
приводит к появлению специфических классов автоматов и связанных с
ними задач. Например, при применении алгебраических средств
возникают понятия автоматов над термами, линейного, группового,
свободного и других; вопросы теории кодирования порождают понятия
самонастраивающихся, обратимых автоматов и другие.
Теория автоматов - это раздел теории управляющих систем,
изучающий математические модели преобразователей дискретной
информации, называемые автоматами. С определенной точки зрения
такими преобразователями являются как реальные устройства
(вычислительные машины, автоматы, живые организмы и т.д.), так и
абстрактные системы (например, формальная система, аксиоматические
теории и т.д.). Наиболее тесно теория автоматов связана с теорией
алгоритмов.
Большинство задач теории автоматов - общие для основных видов
управляющих систем. К ним относятся задачи анализа и синтеза
автоматов,
задачи
полноты,
минимизации,
эквивалентных
преобразований автоматов и другие.
Теория автоматов находит применение как и в других областях
математики, так и в решении практических задач. Например, средствами
114
теории автоматов доказывается разрешимость некоторых формальных
исчислений. Применение методов и понятий теории автоматов к
изучению формальных и естественных языков привело к возникновению
математической
лингвистики
(математическая
лингвистика
математическая дисциплина, предметом которой является разработка
формального аппарата для описания строения естественных и некоторых
искусственных языков.) Понятие автомата может служить модельным
объектом в самых разнообразных задачах, благодаря чему возможно
применение теории автоматов в различных научных и прикладных
исследованиях.
Способы задания автоматов.

Во-первых, автомат может быть задан в виде
непосредственного описания функций:
fq1={q2 (x1/y1); q3 (x2/y2); q4 (x3/y1)}
fq2={q1(x1/y1); q2 (x2/y2); q3 (x3/y2)}
fq3={q3 (x1/y2); q1 (x2/y1); q2 (x3/y1)}
fq4={q4(x1/y1); q2 (x2/y2); q1 (x3/y2)},
где X={x1, x2, x3} –входной алфавит
Z={q1,q2,q3,q4} – множество состояний автомата
Y={y1,y2} – выходной алфавит

Во-вторых, функции перехода и выхода могут быть
представлены в табличной форме.
Таблица функции перехода
X(t)
Z(t)
x1
q1
q2
q2
q1
q3
q3
q4
q4
Z(t+1)
x2
q3
q2
q1
q2
x3
q4
q3
q2
q1
Z(t+1)=f(x(t);z(t))
f(xi, qi)=qj
Таблица функции выхода
X(t)
Z(t)
x1
q1
y1
q2
y1
q3
y2
q4
y1
y(t)
x2
y2
y2
y1
y2
x3
y1
y2
y1
y2
115
y(t)=g(x(t); z(t))
g(xi,qi)=yi
 Граф автомата (графоид) – это сигнальный граф, вершины
которого обозначают состояния автомата, на дугах отражены условия
перехода из состояния в состояние и значения выходных сигналов в
виде дроби: над косой чертой – x(j), под ней – y(j).
q
1
x3/y
1
x2/y
2
q
3
x2/y
2
x1/y
1
x1/y
1
x3/y
x3/y 1
q
2
x2/y
2
q
4
2
x1/y
1
x3/y
2
M = (X, Y, Z, f, g),
Минимизация конечных автоматов.
Пусть
– автомат Мили. Расширим действие функций
d и l на слова в алфавите X следующим образом:
,
,
.
Функция
называется расширенной функцией переходов.
.
Функция называется расширенной функцией выходов. Согласно
приведенному определению она отмечает последний переход в
автомате.
Пусть
, i = 1, 2 – автоматы с одинаковыми
входными и выходными алфавитами. Состояния автомата А1 и
автомата А2 называются неотличимыми (эквивалентными) тогда и
только тогда, когда для любого слова
справедливо
116
.
Отсюда следует, что при подаче на вход автоматов любого слова
выходные слова автоматов, находящихся соответственно в состоянии
и
совпадают (состояния не различаются по выходу).
В частности, может быть А1= А2, и речь будет идти о неотличимых
состояниях одного автомата. Отношение неотличимости на множестве
состояний одного автомата является отношением эквивалентности. Оно
разбивает множество всех состояний на непересекающиеся классы.
Каждый класс содержит все неотличимые между собой состояния.
Автоматы А1 и А2 называются неотличимыми (эквивалентными)
тогда и только тогда, когда для любого состояния
существует эквивалентное ему состояние
автомата А1
автомата А2, и для каждого
состояния
автомата А2 существует эквивалентное ему состояние
автомата А1. Неотличимые автоматы осуществляют одно и то же
отображение входных слов в выходные.
Автомат А называется приведенным, если в нем нет эквивалентных
состояний. Известно, что для любого автомата
существует
эквивалентный ему приведенный автомат А. Число состояний в этом
автомате является минимальным в классе всех автоматов,
эквивалентных автомату
. Процедура нахождения приведенного
(минимального) автомата
для произвольного автомата
называется минимизацией конечного автомата
.
Для нахождения минимального автомата множество всех состояний
автомата
разбивается на классы по отношению неотличимости
состояний.
Пусть
– разбиение на
, соответствующее отношению
неотличимости. Тот факт, что состояния s и t из
находятся в одном
классе разбиения будем обозначать:
.
Через
будем обозначать класс разбиения
, содержащий
элемент s из .
Разбиение , соответствующе отношению неотличимости, можно
построить согласно следующей процедуре, называемой алгоритмом
Мили.
Строится последовательность разбиений
следующим
образом:
Шаг1.
.
117
Иначе одному классу
принадлежат те состояния s и t, которые
одинаково реагируют на все слова длины 1.
Шаг
к
В один класс разбиения
объединяются те состояния из класса
,
которые по любому сигналу х переходят в один и тот же класс
разбиения
. Поскольку
, т. е.
получается из
измельчением классов, то на шаге к в один класс объединяются те
состояния s и t, которые одинаково реагируют на все слова длины к, а
поскольку для нетривиальных автоматов число состояний в каждом
классе разбиения
не более п -1, то для некоторого шага
окажется
, т. е. число классов перестает увеличиваться.
Разбиение
и является искомым разбиением
из одного класса разбиения
, поскольку состояния
одинаково реагируют на слова любой
длины. Для автомата
полагают
, в
качестве же множества состояний S приведенного автомата берется
множество всех классов
разбиения p. Функция переходов d
приведенного автомата А определяется следующим образом:
(2.1)
т. е. значением функции переходов d на классе разбиения, содержащем
некоторый элемент s, является класс разбиения, содержащий
элемент
, т. е. состояние, в которое переходит состояние s
автомата
под действием заданного входного значения х. (Такое
задание является корректным, поскольку известно, что эквивалентные
состояния переходят в эквивалентные по любому входу х). Для функции
выходов l полагают:
, (2.2)
т. е. значением функции выходов приведенного автомата на классе
разбиения p, содержащем некоторый элемент s, является значение
функции выходов исходного автомата
в состоянии s при том же
входном значении х. Это значение функции одно и то же для всех
состояний s из одного класса, так как все состояния в классе
эквивалентны.
Данные о значении функции переходов и выходов заносятся в
таблицу, строки которой соответствуют классам разбиения p (состояния
автомата А), а столбцы – входным значениям х из Х.
118
Поскольку автомат Мура можно рассматривать как частный случай
автомата Мили, то описанную процедуру можно использовать и для
автомата Мура.
119
2. ЦЕЛЬ И ПОРЯДОК РАБОТЫ
Цель работы - получить первичные знания о теории конечных
автоматов. Изучить алгоритм нахождения минимального конечного
автомата.
Порядок выполнения работы:
 изучить описание работы;
 согласно своему варианту задания, решить заданные примеры без
применения ЭВМ
 разработать алгоритмы решения отдельных задач и оформить в
виде процедур
 разработать и отладить программу в соответствии с заданием;
 проверить с помощью программы результат ручного просчета.
 оформить отчет.
4. ЗАДАНИЯ
3.1 Задания для ручного просчета
3.1.1. На вход автомата подано входное слово. Конечный автомат
задан в виде непосредственного описания функции. Задать автомат в
виде таблицы перехода, таблицы выхода, в виде графоида.
Выполнить задания в соответствии со своим вариантом:
fq1={q2 (x1/y1); q3 (x2/y2); q4 (x3/y1)}
fq2={q1(x1/y1); q2 (x2/y2); q3 (x3/y2)}
fq3={q3 (x1/y2); q1 (x2/y1); q4 (x3/y1)}
fq4={q4 (x1/y2); q2 (x2/y2); q1 (x3/y2)}
fq1={q2 (x1/y1); q3 (x2/y2); q4 (x3/y1)}
fq2={q4(x1/y1); q2 (x2/y2); q3 (x3/y2)}
fq3={q3 (x1/y2); q1 (x2/y2); q2 (x3/y1)}
fq4={q4(x1/y1); q2 (x2/y2); q1 (x3/y2)}
1)
2)
fq1={q2 (x1/y1); q3 (x2/y2); q4 (x3/y1)}
fq2={q1(x1/y2); q4 (x2/y2); q3 (x3/y2)}
fq3={q3 (x1/y2); q1 (x2/y1); q2 (x3/y1)}
fq4={q2 (x1/y1); q2 (x2/y2); q1 (x3/y1)}
3)
fq1={q1 (x1/y1); q3 (x2/y2); q4 (x3/y1)}
fq2={q1(x1/y1); q2 (x2/y2); q4 (x3/y2)}
fq3={q3 (x1/y1); q1 (x2/y1); q2 (x3/y1)}
fq4={q4 (x1/y1); q2 (x2/y2); q1 (x3/y2)}
5)
fq1={q2 (x1/y2); q3 (x2/y1); q4 (x3/y1)}
fq2={q1(x1/y1); q4 (x2/y2); q3 (x3/y2)}
fq3={q3 (x1/y2); q1 (x2/y2); q2 (x3/y1)}
fq4={q4 (x1/y1); q1 (x2/y2); q1 (x3/y2)}
7)
fq1={q2 (x1/y1); q3 (x2/y2); q4 (x3/y2)}
fq2={q1(x1/y1); q4 (x2/y2); q3 (x3/y2)}
fq3={q3 (x1/y2); q1 (x2/y1); q2 (x3/y2)}
fq4={q4 (x1/y1); q3 (x2/y2); q1 (x3/y1)}
fq1={q2 (x1/y2); q1 (x2/y2); q4 (x3/y1)}
fq2={q1(x1/y2); q4 (x2/y2); q3 (x3/y2)}
fq3={q3 (x1/y2); q1 (x2/y1); q2 (x3/y1)}
fq4={q3(x1/y1); q2 (x2/y2); q1 (x3/y2)}
4)
fq1={q2 (x1/y1); q3 (x2/y2); q4 (x3/y1)}
fq2={q1(x1/y1); q4 (x2/y2); q3 (x3/y1)}
fq3={q3 (x1/y2); q1 (x2/y1); q2 (x3/y1)}
fq4={q1 (x1/y1); q2 (x2/y1); q1 (x3/y2)}
6)
fq1={q2 (x1/y1); q3 (x2/y2); q4 (x3/y1)}
fq2={q1(x1/y1); q2 (x2/y1); q3 (x3/y2)}
fq3={q1 (x1/y2); q2 (x2/y1); q2 (x3/y1)}
fq4={q4 (x1/y1); q2 (x2/y2); q1 (x3/y2)}
8)
fq1={q2 (x1/y1); q1 (x2/y2); q4 (x3/y1)}
fq2={q4(x1/y2); q2 (x2/y2); q3 (x3/y2)}
fq3={q3 (x1/y2); q1 (x2/y2); q2 (x3/y1)}
fq4={q3 (x1/y1); q2 (x2/y1); q1 (x3/y2)}
120
9)
10)
По заданию преподавателя получить выходные слова по всем моделям
задания автомата.
3.1.2. На выходе автомата получено слово, определить входное
слово и состояние, на которое оно было подано.
1) На выходе получено слово МАКС, конечное состояние q2
X(t)
Z(t+1)
X(t)
y(t)
Z(t)
x1
x2
x3
Z(t)
x1
x2
x3
q1
q1
q3
q4
q1
М
А
Ш
q2
q4
q2
q3
q2
О
З
И
q3
q3
q1
q4
q3
Я
Г
К
q4
q4
q2
q1
q4
У
С
Е
2) На выходе получено слово САША, конечное состояние q4
X(t)
Z(t+1)
X(t)
y(t)
Z(t)
x1
x2
x3
Z(t)
x1
x2
x3
q1
q3
q3
q4
q1
К
М
А
q2
q4
q2
q3
q2
С
О
Г
q3
q3
q1
q4
q3
Д
Ш
Е
q4
q4
q3
q1
q4
Л
А
П
3) На выходе получено слово МИША, конечное состояние q3
X(t)
Z(t+1)
X(t)
y(t)
Z(t)
x1
x2
x3
Z(t)
x1
x2
x3
q1
q3
q3
q1
q1
М
К
С
q2
q1
q2
q3
q2
Е
Д
А
q3
q3
q4
q2
q3
Т
И
О
q4
q4
q2
q1
q4
У
Ш
Г
4) На выходе получено слово ДИМА, конечное состояние q4
X(t)
Z(t+1)
X(t)
y(t)
Z(t)
x1
x2
x3
Z(t)
x1
x2
x3
q1
q3
q2
q4
q1
К
О
Д
q2
q4
q2
q3
q2
А
Ш
С
q3
q3
q1
q2
q3
Г
Я
М
q4
q4
q3
q1
q4
Н
И
Е
5) На выходе получено слово МАША, конечное состояние q1
121
X(t)
Z(t)
q1
q2
q3
q4
x1
q2
q4
q3
q4
Z(t+1)
x2
q3
q1
q1
q2
x3
q4
q3
q4
q1
X(t)
Z(t)
q1
q2
q3
q4
x1
И
С
Е
Ч
y(t)
x2
М
А
Г
Ш
x3
К
О
А
Н
6) На выходе получено слово МАМА, конечное состояние q1
X(t)
Z(t+1)
X(t)
y(t)
Z(t)
x1
x2
x3
Z(t)
x1
x2
x3
q1
q1
q3
q4
q1
Г
М
Е
q2
q1
q2
q4
q2
А
К
И
q3
q3
q4
q2
q3
Ш
А
С
q4
q3
q2
q1
q4
О
М
Л
7) На выходе получено слово МИША, конечное состояние q3
X(t)
Z(t+1)
X(t)
y(t)
Z(t)
Z(t)
x1
x2
x3
x1
x2
x3
q1
q3
q1
q4
q1
М
О
С
q2
q1
q2
q3
q2
К
Е
А
q3
q3
q4
q2
q3
Г
И
Р
q4
q4
q2
q1
q4
Т
Ш
У
8) На выходе получено слово ДИМА, конечное состояние q4
X(t)
Z(t+1)
X(t)
y(t)
Z(t)
x1
x2
x3
Z(t)
x1
x2
x3
q1
q1
q3
q4
q1
О
Д
К
q2
q4
q2
q3
q2
М
С
Ш
q3
q3
q4
q2
q3
Е
Г
И
q4
q4
q2
q1
q4
А
Л
У
3.1.3. Получить минимальный автомат из исходного, заданного в
табличном виде. Представить исходный в виде графоида и
минимальный автомат в виде графоида и в табличном виде.
Выполнить задания в соответствии со своим вариантом.
122
1.
X(t)
Z(t)
1
2
3
4
5
6
7
2.
X(t)
Z(t)
1
2
3
4
5
6
7
3.
X(t)
Z(t)
1
2
3
4
5
6
7
2
6
2
6
2
2
4
Z(t+1)
β
5
2
2
6
5
6
3
2
2
6
6
2
2
4
Z(t+1)
β
5
2
2
6
5
6
3
3
2
6
6
3
2
4
Z(t+1)
β
5
2
2
6
5
6
3
α
α
α
5
5
7
3
5
5
1
X(t)
Z(t)
1
2
3
4
5
6
7
5
7
5
3
5
7
1
X(t)
Z(t)
1
2
3
4
5
6
7
γ
γ
γ
5
7
5
3
5
7
1
X(t)
Z(t)
1
2
3
4
5
6
7
α
1
0
0
0
1
0
1
α
1
0
0
0
1
0
1
α
1
0
0
0
1
0
1
y(t)
β
0
1
1
1
0
1
0
y(t)
β
0
1
1
1
0
1
0
y(t)
β
0
1
1
1
0
1
0
γ
1
1
1
1
1
1
1
γ
1
1
1
1
1
1
1
γ
1
1
1
1
1
1
1
4
X(t)
Z(t)
4
2
3
1
α
6
2
6
2
Z(t+1)
β
6
2
2
5
γ
3
7
5
5
123
5
6
7
2
2
4
5
6
3
X(t)
Z(t)
1
2
3
1
5
6
7
5
7
1
α
0
0
0
1
1
0
1
y(t)
β
1
1
1
0
0
1
0
γ
1
1
1
1
1
1
1
5
X(t)
Z(t)
1
2
3
4
6
6
7
α
2
6
2
4
2
2
6
Z(t+1)
β
5
2
2
3
6
5
6
γ
5
5
7
1
5
5
3
X(t)
Z(t)
1
2
3
4
5
6
7
α
1
0
0
1
0
1
0
y(t)
β
0
1
1
0
1
0
1
γ
1
1
1
1
1
1
1
3.2. Написать программу для построения минимального автомата,
используя любую известную вам среду программирования.
5. МЕТОДИЧЕСКИЕ УКАЗАНИЯ
4.1 Пример к заданию 3.1
На вход автомата подано входное слово x2x1x1x3x2x1
X={x1, x2, x3}
Z={q1,q2,q3,q4}
Y={y1,y2}
Автомат задан в виде непосредственного описания функций:
fq1={q2 (x1/y1); q3 (x2/y2); q4 (x3/y1)}
fq2={q1(x1/y1); q2 (x2/y2); q3 (x3/y2)}
fq3={q3 (x1/y2); q1 (x2/y1); q2 (x3/y1)}
fq4={q4(x1/y1); q2 (x2/y2); q1 (x3/y2)}
Начальное состояние q1
1) Определим выходное слово. Так как начальное состояние q1, то
можем видеть, что при входной букве x2 выходная буква у2.
fq1={q2 (x1/y1); q3 (x2/y2); q4 (x3/y1)}
fq2={q1(x1/y1); q2 (x2/y2); q3 (x3/y2)}
fq3={q3 (x1/y2); q1 (x2/y1); q2 (x3/y1)}
fq4={q4(x1/y1); q2 (x2/y2); q1 (x3/y2)}
Дальше переходим в состояние q3.
Следующая входная буква х1. Определяем, что на выходе будет у2 и т.
д.
fq1={q2 (x1/y1); q3 (x2/y2); q4 (x3/y1)}
124
fq2={q1(x1/y1); q2 (x2/y2); q3 (x3/y2)}
fq3={q3 (x1/y2); q1 (x2/y1); q2 (x3/y1)}
fq4={q4(x1/y1); q2 (x2/y2); q1 (x3/y2)}
В итоге получаем выходное слово: y2y2y2y1y2y1.
2) Составим таблицу перехода для данного автомата.
X(t)
Z(t)
q1
q2
q3
q4
Z(t+1)
x2
x1
q2
q1
q3
q4
q3
q2
q1
q2
x3
q4
q3
q2
q1
Z(t+1)=f(x(t);z(t))
f(xi, qi)=qj
То есть при z=q1 и xi=х1, z(t+1)=q2
fq1={q2 (x1/y1); q3 (x2/y2); q4 (x3/y1)}
fq2={q1(x1/y1); q2 (x2/y2); q3 (x3/y2)}
fq3={q3 (x1/y2); q1 (x2/y1); q2 (x3/y1)}
fq4={q4(x1/y1); q2 (x2/y2); q1 (x3/y2)}, и т.д.
3) Составим таблицу выхода для данного автомата.
X(t)
Z(t)
q1
q2
q3
q4
y(t)
x2
x1
y1
y1
y2
y1
y2
y2
y1
y2
x3
y1
y2
y1
y2
y(t)=g(x(t); z(t))
g(xi,qi)=yi
То есть в состоянии q1 при x1, получаем y1. Аналогично заполняем
таблицу далее.
fq1={q2 (x1/y1); q3 (x2/y2); q4 (x3/y1)}
fq2={q1(x1/y1); q2 (x2/y2); q3 (x3/y2)}
fq3={q3 (x1/y2); q1 (x2/y1); q2 (x3/y1)}
fq4={q4(x1/y1); q2 (x2/y2); q1 (x3/y2)}
125
4) Зададим автомат в виде графоида, вершинами которого служат
состояния графа.
f (ai, qi)=qj
fq1={q2 (x1/y1); q3 (x2/y2); q4 (x3/y1)}
fq2={q1(x1/y1); q2 (x2/y2); q3 (x3/y2)}
fq3={q3 (x1/y2); q1 (x2/y1); q2 (x3/y1)}
fq4={q4(x1/y1); q2 (x2/y2); q1 (x3/y2)}
То есть показывается дуга между состояниями q1 и q2 и ей
приписывается вес x1/y1 и т. д.
4.2 Пример к заданию 3.3
X(t)
Z(t)
1
2
3
Z(t+1)
α
β
γ
2
5
5
6
2
5
2
2
7
126
4
5
6
7
4
2
2
6
3
5
6
6
1
5
5
3
X(t)
Z(t)
1
2
3
4
5
6
7
α
1
0
0
1
1
0
0
y(t)
β
0
1
1
0
0
1
1
γ
1
1
1
1
1
1
1
По определению разбиения π1 в
один
класс должны объединяться те состояния, для которых строки в таблице
выходов совпадают.
Таким образом, имеем π1
∑11={1,4,5}
∑12={2,3,6,7}
(1)
На следующем шаге методом перебора пар из классов (1)
проверяем, какие из пар состояний принадлежат одному классу π2.
∑11={1,4,5}
∑12={2,3,6,7}
Проверяем ∑11 по α:
1→2
4→4
5→2
проверяем по β: 1→5
4→3
5→5
проверяем по γ: 1→5
4→1
5→5, отсюда можем сделать вывод, что пара 1 и 5
принадлежит одному классу, а 4 – другому.
Аналогично проверяем ∑12, получаем два разбиения {2,6} и {3,7}.
Делаем вывод, что для π2
∑21={1,5}
∑22={4}
∑23={2,6}
∑24={3,7}
(2)
На третьем шаге перебираются пары состояний из классов (2) и
проводится проверка переходов аналогично предыдущему шагу.
127
Шаг 3 дает разбиение π3=π2.
Тем самым найдено разбиение по отношению неотличимости π=
Обозначим
∑21={1,5} → 1`
π2.
∑22={4} → 2`
∑23={2,6} → 3`
∑24={3,7} → 4`
Построим графоид, согласно таблице перехода и выхода
Построим графоид с состояниями 1`, 2`, 3`, 4`, где α=a, β=b и γ=с.
128
5. СОДЕРЖАНИЕ ОТЧЕТА




виде);

наименование работы, постановку задачи;
выбранный вариант задания;
результаты решения задач без применения ЭВМ;
программу решения задачи (представляется в электронном
результаты работы программы и их анализ.
7. КОНТРОЛЬНЫЕ ВОПРОСЫ
1. Из чего состоит конечный автомат?
2. Что называется алфавитом автомата?
3. Дайте определение конечного автомата.
4. Что является характерной особенностью описания автомата?
5. Какие существуют способы задания автоматов?
6.Охарактеризуйте пошагово процесс минимизации конечных
автоматов.
7. Какие автоматы называют эквивалентными?
8. Какой автомат называют минимальным?
9. Что называют минимизацией конечного автомата?
10. Перечислите свойства эквивалентности.
129
Download