Автор: Пользователь скрыл имя, 08 Марта 2011 в 22:55, курсовая работа
Первый, самый большой пункт данной работы содержит изложение наиболее важных понятий теории графов (определения, характеристики).
Во втором пункте представлен алгоритм поиска гамильтонова пути в графе, а затем примеры, иллюстрированные рисунками и объяснением основных приемов. В следующем разделе рассматривается этот алгоритм, реализованный на языке Python. В конце представлено заключение о курсовой работе и список использованной литературы.
Введение…………………………………………………………… 3
Основные понятия………………………………………………… 4
Алгоритм поиска гамильтонова пути в графе…………………… 8
Заключение………………………………………………………… 11
Список использованной литературы…………………………….. 12
Будем говорить, что графы G = (V,E), G¢ = (V¢,E¢) изоморфны, если существует такое взаимно однозначное отображение f из V на V¢, что для произвольных u, v Î V имеем
{u, v}Î E Û {f(u), f(v)} Î E¢ ((u, v) Î E Û (f(u), f(v)) Î Е¢
в случае ориентированных графов. Обычно изоморфные графы не различаются между собой.
Для произвольного
Перейдем теперь к понятиям, связанным
с алгоритмами. Алгоритмы
Рассмотрим теперь задачу, где нас
будет интересовать путь, проходящий в
точности один раз через каждую вершину
(а не каждое ребро) данного графа. Вспомним,
что путь с указанным свойством называется
гамильтоновым путем
(гамильтонов цикл
определяется очевидным образом). Пример
гамильтонова пути в графе и графа, в котором
такого пути не существует, показан на
рис. 1.2.
Рис 1.2: а) Гамильтонов
путь в графе; б) Граф, в котором
не существует гамильтонова пути.
В отличие от эйлеровых путей
не известно ни одного
такого алгоритма не существует. Проблема существования гамильтонова пути принадлежит к классу так называемых NP-полных задач. Отметим здесь только, что это — широкий класс задач, включающий фундаментальные задачи из теории графов, логики, теории чисел, дискретной оптимизации и других дисциплин, ни для одной из которых неизвестен полиномиальный алгоритм (т.е. с числом шагов, ограниченным полиномом от размерности задачи).
Вернемся к конкретной задаче
существования гамильтонова
Опишем теперь общий метод,
позволяющий значительно
(x1, . . . , xi, xi +1) можно расширить до некоторого решения (либо
(x1, . . . , xi+1) уже является решением). Если такое предполагаемое, но еще не использованное значение xi+1 существует, то мы добавляем его к нашему частичному решению и продолжаем процесс для последовательности (x1, . . . , xi, xi+1). Если его не существует, то мы возвращаемся к нашему частичному решению (x1, . . . , xi−1) и продолжаем наш процесс, отыскивая новое, еще не использованное допустимое значение xi¢ — отсюда название «алгоритм с возвратом» (англ.: backtracking).
Точнее говоря, мы предполагаем,
что для каждого k >
0 существует некоторое множество Ak,
из которого мы будем выбирать кандидатов
для k-й координаты частичного решения.
Очевидно, что множества Ak
должны быть определены таким образом,
что для каждого целочисленного решения
(x1, . . . , xn) нашей
задачи и для каждого k ≤
n множество Ak
содержало элемент xk
(на практике мы не можем вообще исключить
ситуацию, когда множество Ak
содержит некоторые «лишние» элементы,
не появляющиеся в k-й координате ни
одного целочисленного решения).
Мы предполагаем также, что существует
некоторая простая функция, которая произвольному
частичному решению (x1, . . .
, xi)
ставит в соответствие значение P(x1,
. . . , xi) (истина либо ложь) таким
образом, что если P(x1, .
. . , xi)=ложь, то последовательность (x1,
. . . , xi)
несомненно нельзя расширить до решения.
Если P(x1, . . . , xi)=истина,
то мы говорим, что значение xi
допустимо (для частичного решения (x1,
. . . , xi−1), но это отнюдь
не означает, что (x1, . . . , xi−1),
обязательно расширяется до полного решения.
Этот процесс можно записать в виде следующей
схемы:
1 begin
2 k := 1;
3 while k > 0 do
4 if существует еще не использованный элемент y Î Ak,
такой что P(X[1], . . .,X[k − 1], y)
then
5 begin X[k] := y; (* элемент y использован*)
6 if (X[1], . . .,X[k]) является целочисленным решением then
7 write(X[1], . . .,X[k]);
8 k := k + 1
9 end
10 else (* возврат на более короткое частичное решение;
все элементы множества Ak вновь становятся неиспользованными *)
11 k := k − 1
12 end
Этот алгоритм находит все решения в предположении, что множества Ak конечные и что существует n, такое что P(x1, . . . , xn)=ложь для всех x1 Î A1, . . . , xn Î An (последнее условие означает, что все решения имеют длину меньше n).
Алгоритм, организованный на языке
Python, представлен в Приложении 1.
Заключение
Часто бывает полезно и
Благодаря своему широкому
Поэтому в данной работе
Определяющим для моего
Список
использованной литературы
1. Липский В.,
Комбинаторика для
2. Кристофидес Н., Теория графов. Алгоритмический подход., 1978, Москва
3. Татт У., Теория
графов., 1988, Москва
Приложение 1.
def Hamilt(G):
n = len(G)
k = 0
res = []
cur = 0
used = [False for i in range(n)]
while (k >= 0):
flag = False
for i in range(cur, n):
if not used[i] and ((k == 0) or (G[res[k-1]][i] == 1)):
res.append(i)
used[i] = True
k = k + 1
cur = 0
flag = True
break
if (k == n):
print res
break
if not flag:
if (k > 0):
cur = res[-1] + 1
used[res[-1]] = False
del(res[-1])
k = k - 1
if (k < 0):
print "No solution."
примеры:
g1 =[[0, 0, 1, 1],
[0, 0, 1, 1],
[1, 1, 0, 1],
[1, 1, 1, 0]]
Hamilt(g1)
Информация о работе Алгоритм поиска гамильтонова пути в графе