Транзитивное замыкание. Поиск кратчайшего пути на графе 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Транзитивное замыкание. Поиск кратчайшего пути на графе



 

Пусть задан граф G = (V, E), и нас интересует, какие вершины связаны между собой, не только напрямую, но и через посредство других вершин. Чтобы ответить на этот вопрос, воспользуемся матрицей смежности.

                  

 

 

Рис. 3.5. G * — транзитивное замыкание графа G

 

Поиск кратчайшего пути

 

Предполагаем, что имеем простой взвешенный ориентированный граф. Несуществующие ребра будем считать ребрами с бесконечным весом. Сумму весов ребер пути будем называть весом или длиной этого пути.

Алгоритм поиска кратчайшего пути следующий.

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

 

Если учесть, что в начале алгоритма вершине s присваивается окончательная метка 0 (нулевое расстояние до самой себя), а каждой из остальных вершин присваивается метка ¥, то на каждом шаге алгоритма одной из вершин присваивается окончательная метка и поиск продолжается дальше.     

 

Рис. 3.6. Простой взвешенный граф

 

Как видно из нижнего рисунка граф G из b в g имеет три кратчайших пути, длины которых равны 12. Это путь b, c, e, d, g; b, c, a, d, g и b, c, d, g.

На каждом шаге метки меняются следующим образом:

1. Каждой вершине j, не имеющей окончательной метки, присваивается новая временная метка с учетом расстояния от s до j.

2. Находится наименьшая из временных меток, она и становится окончательной меткой своей вершины. В случае равенства выбирается любая из них. Процесс продолжается до тех пор, пока вершине f не присваивается окончательная метка.

 

 

4. Генерирование случайных последовательностей

Генерирование равномерно распределенных случайных чисел

«Каждый, кто использует арифметические методы генерирования случайных чисел, безусловно, грешит.»

Джон фон Нейман

 

Числа, которые выбираются случайным образом, находят множество полезных применений в

· моделировании. Это позволяет сделать модели похожими на реальные явления;

· выборочном методе. Часто невозможно исследовать все варианты, но случайная выборка обеспечивает понимание того, что можно назвать «типичным поведением»;

· численном анализе. Для решения сложных задач численного анализа была разработана техника, использующая случайные числа;

· компьютерном программировании. Случайные числа являются хорошим источником данных для тестирования эффективности компьютерных алгоритмов;

· принятии решений;

· эстетике;

· развлечениях.

 

Равномерным распределением на конечном множестве чисел называется такое распределение, при котором любое из возможных чисел имеет одинаковую вероятность появления. Если не задано определенное распределение на конечном множестве чисел, то принято считать его равномерным [8].

 Джон фон Нейман первым предложил в 1946 г. идею возвести в квадрат предыдущее случайное число и выделить средние цифры. Например, необходимо получить 10 -значное число, предыдущее равнялось 5772156649. Возводим в квадрат и получаем

 

33317792380594909200.

 

Значит, следующим числом будет 7923805949. Претензии к такому подходу касаются вопроса: как может быть случайной последовательность, генерируемая таким образом, если каждое число полностью определяется предыдущим? Ответ состоит в том, что эта последовательность не случайна, но кажется такой. Последовательности, генерируемые детерминистическим путем, таким как этот, называются псевдослучайными или квази- случайными.

Метод середины квадратов фактически является сравнительно бедным источником случайных чисел. Опасность состоит в коротком цикле (периоде) повторяющихся элементов. Рассмотрим методы генерирования последовательности случайных дробей [8], т.е. случайных действительных чисел Un, равномерно распределенных между нулем и единицей. Будем генерировать целое число Х n между нулем и некоторым числом U, тогда дробь

Un = Х n / m

будет принадлежать [0,1]. Обычно m выбирают равным размеру слова компьютера. Обозначим m = be, где b — основание системы счисления, используемой ЭВМ, а e — число разрядов машины. Поэтому Х n можно по традиции рассматривать как целое число, занимающее все компьютерное слово с точкой в правом конце слова, а Un — как содержание того же слова с точкой в левом конце слова.

 

Линейный конгруэнтный метод

Выберем четыре числа [5]:

m — модуль, m > 0;

a — множитель, 0 £ a < m;

c — приращение, 0 £ с < m;

Х0 — начальное значение, 0 £ Х0 < m.

Последовательность случайных чисел n } можно получить, полагая

 

Хn+1 = (a Хn + c) mod m, n ³ 0                       (4.1)

 

Эта последовательность называется линейной конгруэнтной последовательностью. Например, для m = 10 и Х0 = a = c = 7 получим последовательность

 

                                7, 6, 9, 0, 7, 6, 9, 0, …

 

В примере отражен факт, что конгруэнтная последовательность всегда образует петли, т.е. обязательно существует цикл, повторяющийся бесконечное число раз. Это свойство является общим для всех последовательностей вида Xn +1 = f (Xn), где f — функция, преобразующая конечное множество само в себя. Повторяющиеся циклы называют периодами. Задача генерации случайных последовательностей состоит в использовании относительно длинного периода, что связано с выбором довольно большого m, так как период не может иметь больше m элементов. Другой фактор — скорость генерирования. При выборе множителя а следует принимать во внимание выводы следующей теоремы.

Теорема А. Линейная конгруэнтная последовательность, определенная числами m, a, c и X 0, имеет период длиной m тогда и только тогда, когда:

· числа с и m взаимно простые;

· b = a - 1 кратно p для каждого простого p, являющегося делителем m;

· b кратно 4, если m кратно 4.

 

Пример. Для m = 120 назначить а и построить последовательность случайных чисел в интервале [0,1].

Решение. Выберем с = 7, a = 5, тогда при x 0 = 1 получим следующие числа: X 1= 12, X 2 = 67, X 3= 102, … Далее генерируем u 0 = 1/120, u 1 = 12/120, u 2 = 67/120, u 3 = 102/120, …

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

 

Xn +1 = ((a Xn) mod (m + 1) + c) mod m

быть еще более случайной? Ответ: новая последовательность является менее случайной с большей долей вероятности, т.е. мы попадаем в область генераторов типа Xn +1= f (Xn) с выбранной на удачу функцией f. Но известно, что эти последовательности, вероятно, ведут себя намного хуже, чем последовательности, полученные при использовании более регулярных функций (4.1). Отметим, что период линейной конгруэнтной последовательности довольно длинный; когда m приблизительно равно длине слова компьютера, обычно получаются периоды порядка 109 или больше и в типичных вычислениях используется лишь маленькая часть последовательности.

Рассмотрим аддитивный генератор, предложенный Дж. Ж. Митчелом (G. J. Mitchell) и Д.Ф. Муром (D.P. Moore):

 

Xn= (Xn-24 + Xn-55) mod m n ³ 55,                        (4.2)

 

где m — четное число, числа 24 и 55 — специальные числа, выбранные для того, чтобы определить такую последовательность, младшие значащие двоичные разряды (Xnmod 2) которой имеют длину периода 255 – 1. Далее рассмотрим реализацию этой последовательности с помощью циклической таблицы [5].

Алгоритм В. (Аддитивный генератор чисел). В ячейки памяти Y [1], Y [2], …, Y [55] записано множество значений X 54, X 53, …, X 0 соответственно; j вначале равно 24, k равно 55.

При реализации этого алгоритма на выходе последовательно получаем числа X 55, X 56, …

В1. [Суммирование] (Если на выходе мы оказываемся в точке Xn, то Y [ j ] равно
Xn -24, а Y [ k ] равно Xn -55). Y [ k ] (Y [ k ] + Y [ j ]) mod 2 e.

В2. [Продвижение] Уменьшим j и k на 1. Если j = 0, то присвоим j 24, иначе, если k = 0, присвоить k 55.

Числа 24 и 55 в выражении (4.2) называются запаздыванием, а числа Xn, определенные в (4.2) — последовательностью Фибоначчи с запаздыванием.

Вместо рассмотрения исключительно аддитивных или исключительно мультипликативных последовательностей можно построить достаточно хороший генератор случайных чисел, используя всевозможные линейные комбинации Xn -1, …, Xn - k для малых k. В этом случае наилучший результат получается, когда модуль m является большим простым числом; например, m может быть выбрано так, чтобы оно было наибольшим простым числом, которое можно записать одним компьютерным словом. Формула для генерации может быть выбрана такой:

 

Xn= (a 1 Xn -1 + … + ak Xn - k) mod p                            (4.3)

 

с периодом pk – 1. Здесь X 0, X 1, …, Xk -1 могут быть выбранны произвольно, но не равные нулю одновременно.

Обратимся к процессу генерирования случайных чисел «0» и «1» по формуле (4.3). Зададим произвольно ненулевое двоичное слово (1 0 1 1), то есть X 1 = 1, X 2 = 0, X 3 = 1, X 4 = 1, k примем равным 4, а p равным 2. Зададим также произвольно коэффициенты а1, а2, а3, а4 двоичным словом (0 0 1 1), то есть а1 = 0, а2 = 0, а3 = 1, а4 = 1. Перепишем (4.3) с учетом введенных величин, получим

 

Xn= (a 1 × Xn -1 + a 2 × Xn -2 + a 3 × Xn -3 + a 4 × Xn -4) mod 2

                             Xn= (0 × Xn -1 + 0 × Xn -2 + 1 × Xn -3 + 1 × Xn -4) mod 2

                          Xn= (Xn -3 + Xn -4) mod 2

Откуда следует, что X 5 = (X 2 + X 1) mod 2 = 1

X6= (X3 + X2) mod 2 = 1;        X7= (X4 + X3) mod 2 = 0;

X8= (X5 + X4) mod 2 = 0;        X9= (X6 + X5) mod 2 = 0;

X10= (X7 + X6) mod 2 = 1;       X11= (X8 + X7) mod 2 = 0;

X 12 = (X 9 + X 8) mod 2 = 0; … и т.д.

 

То есть сгенерированные числа (коды) имеют значения:

 

1011 (начальное число); 1100; 0100; 1101; 0111; 1000; 1001 …

 

Период, т.е. число шагов, через которое начинается повтор, равняется 24 – 1 = 15.

   Для генерирования случайных чисел предложено множество других схем. Наиболее интересным из альтернативных методов является обратная конгруэнтная последовательность, предложенная Эйченауэром (Eichenauer) и Лехном (Lehn) [5]:

 

                                    (4.4)

 

Здесь p — простое число, Xn принимает значения из множества {0, 1, …, p-1, …¥}, а обращение определено как 0-1 = ¥, ¥-1 = 0. X -1 × X º 1 по модулю p.

Другой важный класс методов связан с комбинацией генераторов случайных чисел.

Допустим, имеются последовательности X 0, X 1, … и Y 0, Y 1, … случайных чисел, лежащих между 0 и m1 и предпочтительно сгенерированных двумя различными методами. Тогда можно использовать одну случайную последовательность для изменения порядка элементов другой. Рассмотрим алгоритм рандомизации перемешиванием.

 

Алгоритм М (рандомизации перемешиванием)

 

Если заданы методы генерирования двух последовательностей { Xn{ Yn }, этот алгоритм будет последовательно генерировать элементы «значительно более случайной» последовательности. Воспользуемся вспомогательной таблицей V [0], V [1], …, V [ k -1], где k — некоторое число, для удобства обычно выбираемое приблизительно равным 100. Вначале V -таблица заполняется первыми k значениями последовательности X.

М1. [Генерирование X, Y ]. Положим X и Y равными следующим членам последовательности { Xn } и { Yn } соответственно.

М2. [Выбор j ]. Присвоим j [ k × Y / m ], где m — модуль, используемый в последовательности {Y n }, т.е. j — случайная величина, определяемая Y, 0 £ j < k.

M3. [Замена]. Выведем V [ j ], а затем присвоим V [ j ] X.

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

 

Zn= (Xn - Yn) mod m,                          (4.5)

 

где 0 £ Xn < m и 0 £ Yn < m ¢ £ m.

Простейшим путем улучшения случайности при с = 0 является использование только каждого j -го элемента для некоторого малого j. Но лучшим способом, возможно, еще более простым, является применение (4.1) для получения скажем массива из 500 случайных чисел и использование только первых 55 чисел. После этого таким же методом генерируются следующие 55 чисел и т.д.

 



Поделиться:


Последнее изменение этой страницы: 2021-12-15; просмотров: 130; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.118.252.87 (0.045 с.)