Квант

18

В. Евстгенев

Графы и программы

Теория графов оформлясь как самостоятельная ветвь математики в середине тридцатых годов и продолжает интенсивно развивать по сея день. Большой интерес к теории графов сегодия основан в первую очередь на ее широких и плодотворных применениях к проектированию и анализу сложных систем самой различной природы: трансportных сетей, электрических цепей, электронных схем, механических систем, химических реакций, управляющих систем, социальных групп и коллективов и т. д.

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

Графы и ориентированные графы

Граф — это набор элементов, неокторые пары которых выделены. Граф GG, таким образом, определяется двумя множествами:

G=(X,U);G = (X, U);

первое состояние из элементов произвольной природы (они называются вершинами), а второе — из всех выделенных пар вершин. Если каждая выделенная пара упорядочена, граф GG называется ориентированным графом или орерафом, пары называют дуемами; говорят, что дуга (x,y)(x, y) направлена от своего начала xx к своему концу yy и пишут

U∋u=(x,y).U \ni u = (x, y).

В этом случае говорят еще, что дуга и исходит (выходит) из xx и заходит (входит) в yy. Изображают орграф на плоскости в виде точек, соединенных дугами со стрелками (рис. 1). Заметьте на этом рисунке, что дуга, выходящая из вершины x3x_3, заходит в нее же; такая дуга называется netлей.

Если пары (x,y)(x, y) не упорядочены, то их называют ребрами, вершины ребра u={x,y}u = \{x, y\} называются концами, а сам граф G=(X,U)G = (X, U) называется неориентированным графом или протего графом. Пример такого графа — так называемый граф Петерсона — показан на рисунке 2.

Граф данной программы

Пусть дна неоктора программы PP, например, в виде блок-схемы («Алгебра 8», п. 50). Сопоставим каждому блоку вершину графа и соединним вершины в соответствий с последовательностью действия (указанной стрелками) в блок-схеме. Полученный орграф называем operафом проекции PP или pp-графом.

Упражнение 1. Нарисуйте pp-граф, отвечающий блок-схемы программных сортировки шаров, показанной на рисунке 3.

Если программа PP записана на каком-либо алгоритмическом языке,

Рис. 1.

Рис. 2.

19

то ей тоже можно сопоставить некоторый pp-граф: каждый оператор отвечает вершина, две вершины aa и bb соединяются другой (a,b)(a, b), если управление передается от оператора, изображенного вершиной aa, к оператору, изображенного вершиной bb.

Еще один пример pp-графа показан на рисунке 4. Обратите внимание на две особые вершины: x0dx_{0d} (ss) (соответствующий входным данным программмы), в которых не заходит ни одна дуга, и b1x0db_{1x0d} (tt) (соответствующий выходным данным программмы), из которого не исходит ни одна дуга.

На данной pp-графе G=(X,U)G = (X, U) (и вообще на любом орграфе) часто рассматривается путем, если в нем вершины не повторяются, контуром, если a=ba = b, и простым контуром, если a=ba = b, но других повторений вершин нет. Так, на рисунке 4 путь (x1,x3,x6,t)(x_1, x_3, x_6, t) — простой, (x1,x4,x6,x3,x6,t)(x_1, x_4, x_6, x_3, x_6, t) — не простой путь, (x3,x6,x3)(x_3, x_6, x_3) — простой контур, (x3,x6,x3,x6,x3)(x_3, x_6, x_3, x_6, x_3) — контур, но не простой, (x2,x7,x6)(x_2, x_7, x_6) — даже не путь.

Рис. 3.

Рис. 4.

Уражнение 2. Перечислите все простые пути и все простые контуры pp-графа, построенного при решении упражнения 1.

Все ли пути ведут в Рим?

В pp-графе, отвечающем хорошо составленной программы, «все пути ведут в Рим», то есть любой путь с началом в ss можно продолжить до выхода tt, обозначающего конец работы программы. Поэтому pp-граф естественно называется правильным, если любая вершина лежит на пути (не обязательно простом), ведущем из ss в tt.

Конечно, правильность pp-графа еще не гарантирует успешную работу программы: если в нем есть хотя бы один контур, из которого не выходит ни одна дуга, программа может зациклиться, то есть крутится по этому контуру. Но так как не существует общого алгоритма, проверяющего правильность работы программы (об этом мы рассскажем в «Кванте» в другой раз), важно проверять хотя бы правильность pp-графа.

Как проверить правильность pp-графа? В простых случаях это легко делается «вручную».

Уражнение 3. Проверите правильность pp-графа программы сортировки шаров (см. упражнение 1). Удостоверться в неправильности pp-графа на рисунке 5, найти неем «тупики», «тупиковые контуры» и «недоступные контуры».

В сложных же случаях, например, в современных больших программах,ручная проверка слищом трудемка и ненадежна — приходит прибегать к помощи ЭВМ. Поэтому необходимо иметь подходящие для этой цели алгоритмы. Задачу о построении таких алгоритмов мы сформулируем в виде трех упражнений (4—6) и для первого из них подскажем решение.

20

Рис. 5.

Уражнение 4. Найти все простые пути, соединяющие вход pp-графа с его выходом.

Один из наиболее красивых алгоритмов для решения этой задачи основан на последовательном устройении вершин pp-графа. На рисунке 6 показано его применение к pp-графу из рисунка 4. На каждом шагуSTRAЯЕТСЯ одна из вершин x∈Xx \in X (отличная от ss и tt); вместе простых путей, соединяющих вершины, соседние с xx и проходящие через xx, строится новая дуга (рядом с которой записьается название удаленной вершины). Возникающие в этом процессе петли отбрасываются. В результате получается набор дуг, соединяющих ss с tt, притом на каждой из этих дуг последовательно выписаны вершины, через которых разделяется найти алгоритмы, решающие управнения 5, 6. Записать их можно в виде блок-схемы, в таблином виде («Алгебра 8», п. 49) или, для учащихся ЗШП, на языке Рапира.

Уражнение 5*. Найти все простые контуры pp-графа.

Уражнение 6*. Построить систему путей (не обязательно простых), соединяющих вход pp-графа с его выходом, покрывающим все вершины pp-графа. Построить минимальный по числу путей) такую систему.

Оргraph арифметического выражения

При вычислении арифметических выражений на ЭВМ в произвольном порядке, когда этих выражений много и они достаточно громоздки, исходные данные и промежуточные результаты вычислений могут занять недопустимо большой объем памяти ЭВМ; как говорят программисты, «программа забивает оперативную память машины». Как с этим бороться? Здесь на помощь приходит теория графов.

Оказывается, с каждым арифметическим выражением можно свя-

ПРОСТЫЕ ПУТИ:

sx1x3x6ts x_1 x_3 x_6 t
sx1x4x6ts x_1 x_4 x_6 t
sx2x7ts x_2 x_7 t
sx2x5x7ts x_2 x_5 x_7 t

Рис. 6.

21

зать орграф специального вида. Например, с выражением
((a+b)⋅(c−d))/(g+f)+h=L((a+b) \cdot (c-d)) / (g+f) + h = L
можно связать граф, показанный на рисунке 7. Если в формуле буквы не повторяются, подобные графы имеют специальное название. Ордеревом (ориентированным деревом) называется граф, в котором выделена одна вершина — корень ордерева и от любой другой вершины ордерева к корню идет единственный путь. Из корня ни в одну вершину путь нет.

Так, в нашем примере (см. рис. 7) показано ордерево с корнем LL. Вершины a,b,c,d,f,g,ha, b, c, d, f, g, h называются высчиним.

Упражнение 7. Построите ордерево выражения
x+yz2+5at+7k+b+cr=L.\frac{\sqrt{x+y}}{z^2+5at+7k} + \frac{b+c}{r} = L.

Возвращаясь к рисунку 7, представим себе, что отдельные операции производятся в момент времени, показанные красными вертикальными линиями. Тогда в памяты приходит дережать до 6 чисел одновременно. Правда, это число можно сизить до 4, если в памяти числа g,fg, f в момент времени t=2t=2 (вместо t=1t=1).

Нельзя ли изобразить наше выражение еще более экономным (в этом смысле) ордерево?

Протащим верблюда через игольное ушко

Рассмотрим дискретную шкалу времени t=1,2,3,…t=1, 2, 3, \dots. Пусть вычислительной процесс организован так, что ячейки памяты заполняются (вводятся исходные данные, записываются вычисленный промежуточный результат и т. д.) в целочисленные моменты времени и оставятся занятыми в течение нескольких интервалов времени выбранной шкалы. Когда содержимое ячейки используется, она освобождается. Предположим также, что в каждой момент времени производится засылака только в одну ячейку памяты. Последнее условие позволяет занумеровать вершины соответствующего ордерева,

Идей построения укладок ордерева, шклина которых мала, была высказана А. П. Erшовым в 1958 году и оказалась чрезвычайно полезной. Для сложных задач удаются также узкие укладки, что впору готовить о протакивании верблюда через игольное ушко!

22

висячая, переходим к шагу 4, в противном случае — к шагу 5.

Шаг 4. Во втором столбце пшем 0, в третьем — x. (Таким образом, мы положили p(x)=0,q(x)=xp(x) = 0, q(x) = x.) Переходим к шагу 3.

Шаг 5. Пусть y1,y2,…,yky_1, y_2, \dots, y_k — вершины ордерева, неосредственно предшествующие x, упорядоченные так, что p(y1)≥p(y2)≥⋯≥p(yk)p(y_1) \geq p(y_2) \geq \dots \geq p(y_k). Найдем
p(x)=max⁡1≤s≤k{p(ys)+s−1}p(x) = \max_{1 \leq s \leq k} \{p(y_s) + s - 1\}
q(x)=q(y1)q(y2)…q(yk)x,q(x) = q(y_1)q(y_2) \dots q(y_k)x,
и внесем найденные значения во второй и третьий столбцы расматриваемой строки. Переходим к шагу 3.

Рис. 8.

Рис. 9.

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

Шаг 1. Построим таблицу с n строками и треяя стольцами, где n — число вершин ордерева.

Шаг 2. Заполним первый столбец таблицы сизу вверх, помещив в самой нижней строке корень x0x_0 ордерева, затем в произвольном порядке его предшествников, лишь бы нигде не нарушалась очередность вычислений (то есть любые данные, нужные для очередной операции, должны быть получены равше ее выполнения).

Далее через p(x)p(x) и q(x)q(x) мы будем обозначать записи во втором и третьем столбах строки, начинаяшейся с буквы x. Значениями функции pp будут числа, функция qq — последовательности букв. Пусть уже заполены r первых строк.

Шаг 3. Приступаем к заполнению очередной строки (предыдущие уже заполнены); обозначим через x ее первую букву. Если вершина x —

Повторяем шаги 3—5, пока не будет заполнен все таблица. Тогда в последней строке во втором столбце мы получим ширину укладки, то есть p(x0)=W(Y,T)p(x_0) = W(Y, T), а в третьем — саму укладку ордерева T, если вершины в последовательности q(x0)q(x_0) занутеровать слева направо.

Tabлица, полученная при применении алгоритма Реджеевского к ордереву на рисунке 7, показана на рисунке 8, а «уложенное» ордерево — на рисунке 9.

Упражнение 9. Примените алгоритм Реджеевского к ордереву, полученной в упражнения 7.