Часть 2 Фундаментальные алгоритмы 2 глава
Из связности сети следует, что (см. Рис.6.4) Tpq = и P =
Рис. 6.4 Поддеревья Tpq.
Оператор forall в комментариях в Алгоритме 6.3 будет обсуждаться в конце этого подраздела; в следующей теореме речь идет об алгоритме без этого оператора. Теорема 6.16 Древовидный алгоритм (Алгоритм 6.3) является волновым алгоритмом. Доказательство. Т.к. каждый процесс посылает не более одного сообщения, в целом алгоритм использует не более N сообщений. Отсюда следует, что алгоритм достигает заключительной конфигурации ¡ за конечное число шагов; мы покажем, что в ¡ хотя бы один процесс выполняет событие decide. Пусть F - количество битов rec со значением false в ¡, а K - количество процессов, которые уже послали сообщения в ¡. Т.к. в ¡ не передается ни одно сообщение (иначе ¡ не была бы заключительной), F = (2N-2) - K; общее число битов rec равно 2N-2, а K из них равны true. Предположим, что ни один процесс в ¡ не принял решения. N-K процессов, которые еще не послали сообщение в ¡, содержат хотя бы по два бита rec, равных false; иначе они бы могли послать сообщение, что противоречит тому, что ¡ - заключительная конфигурация. K процессов, которые послали сообщение в ¡, содержат хотя бы один бит rec, равный false; иначе они могли бы принять решение, что противоречит тому, что ¡ - заключительная конфигурация. Итак, F ³ 2(N-K) + K, а из (2N-2) - K ³ 2(N-K) + K следует, что -2 ³ 0; мы пришли к противоречию, следовательно, хотя бы один процесс в ¡ принимает решение. См. Упражнение 6.5. Наконец, нужно показать, что решению предшествует событие в каждом процессе. Пусть fpq - событие, где p посылает сообщение q, а gpq - событие, где q получает сообщение от p. Применяя индукцию по событиям получения сообщений, можно доказать, что " s Î Tpq $ e Î Cs: e p gpq.
Предположим, что это выполняется для всех событий получения сообщений, предшествующих gpq. Из того, что событию gpq предшествует fpq (в процессе p), и из алгоритма p следует, что для всех r Î Neighp при r ¹ q, grp предшествует fpq. Из гипотезы индукции следует, что для всех таких r и для всех s Î Trp существует событие e Î Cs, где e p grp, следовательно, e p gpq. Решению dp в p предшествуют grp для всех r Î Neighp, откуда следует, что " s Î P $ e Î Cs : e p dp. Читатель может смоделировать вычисление алгоритма на небольшом дереве (например, см. дерево на Рис.6.4) и самостоятельно убедиться в справедливости следующих замечаний. В Алгоритме 6.3 существует два процесса, которые получают сообщения через все свои каналы и принимают решение; все остальные тем временем ожидают сообщения с счетчиком команд, установленным на x, в заключительной конфигурации. Если к программе добавить оператор forall (в скобках комментария в Алгоритме 6.3), то все процессы принимают решение и в конечной конфигурации каждый процесс находится в конечном состоянии. Модифицированная программа использует 2N-2 сообщений.
6.2.3 Эхо-алгоритм Эхо-алгоритм - это централизованный волновой алгоритм для сетей произвольной топологии. Впервые он был представлен Чангом [Chang; Cha82] и поэтому иногда называется эхо-алгоритмом Чанга. Более эффективная версия, которая и представлена здесь, была предложена Сегаллом [Segall; Seg83]. Алгоритм распространяет сообщения < tok > по всем процессам, таким образом определяя остовное дерево, как определено в Лемме 6.3. Маркеры «отражаются» обратно через ребра этого дерева аналогично потоку сообщений в древовидном алгоритме. Алгоритм обозначен как Алгоритм 6.5. Инициатор посылает сообщения всем своим соседям. После получения первого сообщения не-инициатор пересылает сообщения всем своим соседям, кроме того, от которого было получено сообщение. Когда не-инициатор получает сообщения от всех своих соседей, эхо пересылается родителю (father). Когда инициатор получает сообщения от всех своих соседей, он принимает решение.
var recp : integer init 0; (* Счетчик полученных сообщений *) fatherp: P init udef;
Для инициатора: begin forall q Î Neighp do send < tok > to q; while recp < # Neighp do begin receive < tok >; recp:= recp + 1 end; decide end; Для не-инициатора: begin receive < tok > from neighbor q; fatherp:= q; recp:= recp + 1; forall q Î Neighp, q ¹ fatherp do send < tok > to q; while recp < # Neighp do begin receive < tok >; recp:= recp + 1 end; send < tok > to fatherp end
Алгоритм 6.5 Эхо-алгоритм. Теорема 6.17 Эхо-алгоритм (Алгоритм 6.5) является волновым алгоритмом. Доказательство. Т.к. каждый процесс посылает не более одного сообщения по каждому инцидентному каналу, количество сообщений, пересылаемых за каждое вычисление, конечно. Пусть ¡ - конечная конфигурация, достигаемая в вычислении C с инициатором p0. Для этой конфигурации определим (подобно определению в лемме 6.3) граф T = (P,ET), где pq Î ET Û fatherp = q. Чтобы показать, что этот граф является деревом, нужно показать, что количество ребер на единицу меньше, чем количество вершин (Лемма 6.3 утверждает, что T - дерево, но предполагается, что алгоритм является волновым, что нам еще нужно доказать). Отметим, что каждый процесс, участвующий в C, посылает сообщения всем своим соседям, кроме соседа, от которого он получил первое сообщение (если процесс - не-инициатор). Отсюда следует, что все его соседи получают хотя бы одно сообщение в C и также участвуют в C. Из этого следует, что fatherp ¹ udef для всех p ¹ p0. Что T не содержит циклов, можно показать, как в доказательстве Леммы 6.3. В корне дерева находится p0; обозначим через Tp множество вершин в поддереве p. Ребра сети, не принадлежащие T, называются листовыми ребрами (frond edges). В ¡ каждый процесс p, по крайней мере, послал сообщения всем своим соседям, кроме родителя fatherp, следовательно, каждое листовое ребро передавало в C сообщения в обоих направлениях. Пусть fp - событие, в котором p посылает сообщение своему родителю (если в C это происходит), а gp - событие, в котором родитель p получает сообщение от p (если это происходит). С помощью индукции по вершинам дерева можно показать, что
(1) C содержит событие fp для любого p ¹ p0; (2) для всех s Î Tp существует событие e Î Cs такое, что e p gp. Мы рассмотрим следующие два случая. p - лист. p получил в C сообщение от своего родителя и от всех других соседей (т.к. все остальные каналы - листовые). Таким образом, посылка < tok > родителю p была возможна, и, т.к. ¡ - конечная конфигурация, это произошло. Tp содержит только p, и, очевидно, fp p gp. p - не лист. p получил в C сообщение от своего родителя и через все листовые ребра. По индукции, C содержит fp¢ для каждой дочерней вершины p¢ вершины p, и, т.к. ¡ - конечная конфигурация, C также содержит gp¢. Следовательно, посылка < tok > родителю p была возможна, и, т.к. ¡ - конечная конфигурация, это произошло. Tp состоит из объединения Tp¢ по всем дочерним вершинам p и из самого p. С помощью индукции можно показать, что в каждом процессе этого множества существует событие, предшествующее gp. Отсюда следует, также, что p0 получил сообщение от каждого соседа и выполнил событие decide, которому предшествуют события в каждом процессе. Остовное дерево, которое строится в вычислении Алгоритма 6.5, иногда используют в последовательно выполняемых алгоритмах. (Например, алгоритм Мерлина-Сегалла (Merlin-Segall) для вычисления таблиц кратчайших маршрутов предполагает, что изначально дано остовное дерево с корнем в v0; см. Подраздел 4.2.3. Начальное остовное дерево может быть вычислено с использованием эхо-алгоритма). В последней конфигурации алгоритма каждый процесс (кроме p0) запомнил, какой сосед в дереве является его родителем, но не запомнил дочерних вершин. В алгоритме одинаковые сообщения принимаются от родителя, через листовые ребра, и от дочерних вершин. Если требуется знание дочерних вершин в дереве, алгоритм может быть слегка изменен, так чтобы отправлять родителю сообщения, отличные от остальных (в последней операции отправления сообщения для не-инициаторов). Дочерними вершинами процесса тогда являются те соседи, от которых были получены эти сообщения.
6.2.4 Алгоритм опроса В сетях с топологией клика между каждой парой процессов существует канал. Процесс может определить, получил ли он сообщение от каждого соседа. В алгоритме опроса, обозначенном как Алгоритм 6.6, инициатор запрашивает у каждого соседа ответ на сообщение и принимает решение после получения всех ответных сообщений. Теорема 6.18 Алгоритм опроса (Алгоритм 6.6) является волновым алгоритмом. Доказательство. Алгоритм пересылает по два сообщения через каждый канал, смежный с инициатором. Каждый сосед инициатора отвечает только один раз на первоначальный опрос, следовательно, инициатор получает N-1 ответ. Этого достаточно, чтобы принять решение, следовательно, инициатор принимает решение и ему предшествует событие в каждом процессе. Опрос может быть использован и в сети с топологией звезда, в которой инициатор находится в центре.
var recp : integer init 0; (* только для инициатора *)
Для инициатора: begin forall q Î Neighp do send < tok > to q; while recp < # Neighp do begin receive < tok >; recp:= recp + 1 end; decide end; Для не-инициатора: begin receive < tok > from q; send < tok > to q end
Алгоритм 6.6 Алгоритм опроса.
6.2.5 Фазовый алгоритм В этом разделе будет представлен фазовый алгоритм, который является децентрализованным алгоритмом для сетей с произвольной топологией. Алгоритм дан в [Tel91b, Раздел 4.2.3]. Алгоритм может использоваться как волновой для ориентированных сетей. Алгоритм требует, чтобы процессам был известен диаметр сети, обозначенный в тексте алгоритма как D. Алгоритм остается корректным (хотя и менее эффективным), если процессы вместо D используют константу D¢ > D. Таким образом, для применения алгоритма необязательно точно знать диаметр сети; достаточно, если известна верхняя граница диаметра (например, N-1). Все процессы должны использовать одну и ту же константу D¢. Пелег [Peleg; Pel90] дополнил алгоритм таким образом, чтобы диаметр вычислялся во время выполнения, но это расширение требует уникальной идентификации. Общий случай. Алгоритм может использоваться в ориентированных сетях произвольной топологии, где каналы могут передавать сообщения только в одном направлении. В этом случае, соседи p являются соседями по входу (процессы, которые могут посылать сообщения p) и соседями по выходу (процессы, которым p может посылать сообщения). Соседи по входу p содержатся в множестве Inp, а соседи по выходу - в множестве Outp. В фазовом алгоритме каждый процесс посылает ровно D сообщений каждому соседу по выходу. Только после того, как i сообщений было получено от каждого соседа по входу, (i+1)-ое сообщение посылается каждому соседу по выходу; см. алгоритм 6.7.
cons D : integer = диаметр сети; var recp[q]: 0..D init 0, для каждого q Î Inp; (* Количество сообщений, полученных от q *) Sentp: 0..D init 0; (* Количество сообщений, посланных каждому соседу по выходу *) begin if p - инициатор then begin forall r Î Outp do send < tok > to r; Sentp:= Sentp + 1 end; while minq Recp[q] < D do begin receive < tok > (от соседа q0); Recp[q0]:= Recp[q0] + 1; if minq Recp[q] ³ Sentp and Sentp < D then begin forall r Î Outp do send < tok > to r; Sentp:= Sentp + 1 end end; decide End
Алгоритм 6.7 Фазовый алгоритм. Действительно, из текста алгоритма очевидно, что через каждый канал проходит не более D сообщений (ниже показано, что через каждый канал проходит не менее D сообщений). Если существует ребро pq, то fpq(i) - i-е событие, в котором p передает сообщение q, а gpq(i) - i-е событие, в котором q получает сообщение от p. Если канал между p и q удовлетворяет дисциплине FIFO, эти события соответствуют друг другу и неравенство fpq(i) p gpq(i) выполняется. Каузальные отношения между fpq(i) и gpq(i) сохраняются и в случае, если канал не является FIFO, что доказывается в следующей лемме. Лемма 6.19 Неравенство fpq(i) p gpq(i) выполняется, даже если канал не является каналом FIFO. Доказательство. Определим mh следующим образом: fpq(mh) - событие отправления сообщения, соответствующее gpq(h), т.е. в своем h-м событии получения q получает mh-е сообщение p. Из определения каузальности fpq(mh) p gpq(h). Т.к. каждое сообщение в C получают только один раз, все mh различны, откуда следует, что хотя бы одно из чисел m1,..., mi больше или равно i. Выберем j £ i так, чтобы mj ³ i. Тогда fpq(i) p fpq(mj) p gpq(j) p gpq(i). Теорема 6.20 Фазовый алгоритм (Алгоритм 6.7) является волновым алгоритмом. Доказательство. Т.к. каждый процесс посылает не более D сообщений по каждому каналу, алгоритм завершается за конечное число шагов. Пусть ¡ - заключительная конфигурация вычисления C алгоритма, и предположим, что в C существует, по крайней мере, один инициатор (их может быть больше). Чтобы продемонстрировать, что в ¡ каждый процесс принял решение, покажем сначала, что каждый процесс хотя бы один раз послал сообщения. Т.к. в ¡ по каналам не передается ни одно сообщение, для каждого канала qp Recp[q] = Sentpq. Также, т.к. каждый процесс посылает сообщения, как только получит сообщение сам, Recp[q] > 0 Þ Sentp > 0. Из предположения, что существует хотя бы один инициатор p0, для которого Sentp0 > 0, следует, что Sentp > 0 для каждого p. Впоследствии будет показано, что каждый процесс принял решение. Пусть p - процесс с минимальным значением переменной Sent в ¡, т.е. для всех q Sentq ³ Sentp в ¡. В частности, это выполняется, если q - сосед по входу p, и из Recp[q] = Sentq следует, что minq Recp[q] ³ Sentp. Но отсюда следует, что Sentp = D; иначе p послал бы дополнительные сообщения, когда он получил последнее сообщение. Следовательно, Sentp = D для всех p, и Recp[q] = D для всех qp, откуда действительно следует, что каждый процесс принял решение. Остается показать, что каждому решению предшествует событие в каждом процессе. Если P = p0, p1,..., pl (l £ D) - маршрут в сети, тогда, по Лемме 6.19,
для 0 £ i < l и, по алгоритму,
для 0 £ i < l - 1. Следовательно,. Т.к. диаметр сети равен D, для любых q и p существует маршрут q = p0, p1,..., pl = p длины не более D. Таким образом, для любого q существует l £ D и сосед по входу r процесса p, такие, что; на основании алгоритма, предшествует dp. Алгоритм пересылает D сообщений через каждый канал, что приводит в сложности сообщений, равной |E|*D. Однако нужно заметить, что |E| обозначает количество направленных каналов. Если алгоритм используется для неориентированной сети, каждый канал считается за два направленных канала, и сложность сообщений равна 2|E|*D.
var recp : 0..N - 1 init 0; (* Количество полученных сообщений *) Sentp: 0..1 init 0; (* Количество сообщений, посланных каждому соседу *) begin if p - инициатор then begin forall r Î Neighp do send < tok > to r; Sentp:= Sentp + 1 end; while Recp < # Neighp do begin receive < tok >; Recp:= Recp + 1; if Sentp = 0 then begin forall r Î Neighp do send < tok > to r; Sentp:= Sentp + 1 end end; decide End
Алгоритм 6.8 Фазовый алгоритм для клики.
Фазовый алгоритм для клики. Если сеть имеет топологию клика, ее диаметр равен 1; в этом случае от каждого соседа должно быть получено ровно одно сообщение, и для каждого процесса достаточно посчитать общее количество полученных сообщений вместо того, чтобы считать сообщения от каждого соседа по входу отдельно; см. Алгоритм 6.8. Сложность сообщений в этом случае равна N(N-1) и алгоритм использует только O(log N) бит оперативной памяти.
6.2.6 Алгоритм Финна Алгоритм Финна [Fin79] - еще один волновой алгоритм, который можно использовать в ориентированных сетях произвольной топологии. Он не требует того, чтобы диаметр сети был известен заранее, но подразумевает наличие уникальных идентификаторов процессов. В сообщениях передаются множества идентификаторов процессов, что приводит к довольно высокой битовой сложности алгоритма. Процесс p содержит два множества идентификаторов процессов, Incp и NIncp. Неформально говоря, Incp - это множество процессов q таких, что событие в q предшествует последнему произошедшему событию в p, а NIncp - множество процессов q таких, что для всех соседей r процесса q событие в r предшествует последнему произошедшему событию в p. Эта зависимость поддерживается следующим образом. Изначально Incp = {p}, а NIncp = Æ. Каждый раз, когда одно из множеств пополняется, процесс p посылает сообщение, включая в него Incp и NIncp. Когда p получает сообщение, включающее множества Inc и NInc, полученные идентификаторы включаются в версии этих множеств в процессе p. Когда p получит сообщения от всех соседей по входу, p включается в NIncp. Когда два множества становятся равны, p принимает решение; см. Алгоритм 6.9. Из неформального смысла двух множеств следует, что для каждого процесса q такого, что событие в q предшествует dp, выполняется следующее: для каждого соседа r процесса q событие в r также предшествует dp, откуда следует зависимость алгоритма. В доказательстве корректности демонстрируется, что это выполняется для каждого p, и что из равенства двух множеств следует, что решению предшествует событие в каждом процессе. Теорема 6.21 Алгоритм Финна (Алгоритм 6.9) является волновым алгоритмом. Доказательство. Заметим, что два множества, поддерживаемые каждым процессом, могут только расширяться. Т.к. размер двух множеств в сумме составляет не менее 1 в первом сообщении, посылаемом по каждому каналу, и не более 2N в последнем сообщении, то общее количество сообщений ограничено 2N*|E|. Пусть C - вычисление, в котором существует хотя бы один инициатор, и пусть ¡ - заключительная конфигурация. Можно показать, как в доказательстве Теоремы 6.20, что если процесс p отправил сообщения хотя бы один раз (каждому соседу), а q - сосед p по выходу, то q тоже отправил сообщения хотя бы один раз. Отсюда следует, что каждый процесс переслал хотя бы одно сообщение (через каждый канал).
var Incp : set of processes init {p}; NIncp : set of processes init Æ; recp[q]: boolean for q Î Inp init false; (* признак того, получил ли p сообщение от q *)
begin if p - инициатор then forall r Î Outp do send < sets, Incp, NIncp> to r; while Incp ¹ NIncp do begin receive < sets, Inc, NInc> from q0; Incp:= Incp È Inc; NIncp:= NIncp È NInc; recp[q0]:= true; if "q Î Inp: recp[q] then NIncp:= NIncp È {p}; if Incp или NIncp изменились then forall r Î Outp do send < sets, Incp, NIncp> to r end; decide End
Алгоритм 6.9 Алгоритм Финна. Сейчас мы покажем, что в ¡ каждый процесс принял решение. Во-первых, если существует ребро pq, то Incp Í Incq в ¡. Действительно, после последнего изменения Incp процесс p посылает сообщение < sets, Incp, NIncp>, и после его получения в q выполняется Incq:= Incq È Incp. Из сильной связности сети следует, что Incp = Incq для всех p и q. Т.к. выполняется p Î Incp и каждое множество Inc содержит только идентификаторы процессов, для каждого p Incp = P. Во-вторых, подобным же образом может быть показано, что NIncp = Nincq для любых p и q. Т.к. каждый процесс отправил хотя бы одно сообщение по каждому каналу, для каждого процесса p выполняется: " q Î Inp: recp[q], и следовательно, для каждого p выполняется: p Î NIncp. Множества NInc содержат только идентификаторы процессов, откуда следует, что NIncp = P для каждого p. Из Incp = P и NIncp = P следует, что Incp = NIncp, следовательно, каждый процесс p в ¡ принял решение. Теперь нужно показать, что решению dp в процессе p предшествуют события в каждом процессе. Для события e в процессе p обозначим через Inc(e) (или, соответственно, NInc(e)) значение Incp (NIncp) сразу после выполнения e (сравните с доказательством Теоремы 6.12). Следующие два утверждения формализуют неформальные описания множеств в начале этого раздела. Утверждение 6.22 Если существует событие e Î Cq: e p f, то q Î Inc(f). Доказательство. Как в доказательстве Теоремы 6.12, можно показать, что e p f Þ Inc(e) Í Inc(f), а при e Î Cq Þ q Î Inc(e), что и требовалось доказать. Утверждение 6.23 Если q Î NInc(f), тогда для всех r Î Inq существует событие e Î Cr: e p f. Доказательство. Пусть aq - внутреннее событие q, в котором впервые в q выполняется присваивание NIncq:= NIncq È {q}. Событие aq - единственное событие с q Î NInc(aq), которому не предшествует никакое другое событие a¢, удовлетворяющее условию q Î NInc(a¢); таким образом, q Î NInc(f) Þ aq p f. Из алгоритма следует, что для любого r Î Inq существует событие e Î Cr, предшествующее aq. Отсюда следует результат. Процесс p принимает решение только когда Incp = NIncp; можно записать, что Inc(dp) = NInc(dp). В этом случае (1) p Î Inc(dp) ; и (2) из q Î Inc(dp) следует, что q Î NInc(dp), откуда следует, что Inq Í Inc(dp). Из сильной связности сети следует требуемый результат: Inc(dp) = P. 6.3 Алгоритмы обхода В этом разделе будет представлен особый класс волновых алгоритмов, а именно, волновые алгоритмы, в которых все события волны совершенно упорядочены каузальным отношением, и в котором последнее событие происходит в том же процессе, где и первое.
Воспользуйтесь поиском по сайту: ©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...
|