Поиск одного из фундаментальных множеств циклов данного связного неориентированного графа

Страницы работы

8 страниц (Word-файл)

Содержание работы

1.  Условие задачи

Найти одно из фундаментальных множеств циклов данного связного неориентированного графа.

2.  Анализ задачи

Дано: граф G, а именно количество его вершин nver, количество рёбер nreb и список рёбер.

Результат: фундаментальное множество циклов, если такое существует, или сообщение о том, что граф ацикличен в противном случае. Фундаментальное множество циклов представляется в виде матрицы циклов.

Структура данных: для внутреннего представления графа используем список рёбер, а именно трёхмерный динамический целочисленный массив rebra, состоящий из nreb строк и 3х столбцов. Третий столбец будет содержать метку о том, использовано ли данное ребро. Такое представление удобно тем, что занимает меньше всего памяти по сравнению с другими способами представления. Неудобством является то, что для поиска вершин, смежных с данной, приходится проходить весь список от начала до конца. Улучшение возможно путём упорядочения рёбер по номерам вершин, входящих в них.

Для представления матрицы циклов, содержащей в себе фундаментальные циклы,  воспользуемся двумерным динамическим целочисленным массивом result, который содержит nreb строк и nrebnver + 1 столбцов, где nrebnver + 1 – количество циклов, входящих в фундаментальное множество. Элемент result[i][j] равен 1, если ребро rebra[i] входит в j-ый цикл, и равен нулю в противном случае.

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

Метод решения: прежде всего ещё при вводе рёбер будем упорядочивать вершины в ребре по возрастанию, что позволит уменьшить количество сравнений при поиске нужного ребра. Условимся, что вершины нумеруются по порядку, начиная с 1. После ввода рёбер посчитает количество фундаментальных циклов, и если это число положительное то инициализируем  массивы result и versh, который будет содержать метки вершин. Для порождения фундаментального множества циклов используем метод поиска в глубину. Он строит остовное дерево, и каждое обратное ребро порождает цикл относительно этого дерева. Чтобы следить за рёбрами дерева, используется стек, в котором хранятся все текущие вершины пройденного пути в данный момент. При попадании на обратное ребро, обнаруженный цикл будет состоять из этого ребра и рёбер, соединяющих вершины из верха стека до той вершины, в которую мы вернулись. Построение остовного дерева будем начинать с вершины под номером 1.

Этот алгоритм можно представить следующим образом:

верш. стека = 1;

в_стек(1);

CYCLE (1);

void CYCLE (int x)

{  versh[x] = 1; // вершина x исследована

   for (все рёбра)

   { v = 0;

      if (rebra[k] не использовано)

      if (x инцидентна rebra[k]) v = вторая вершина, инцидентная rebra[k];

      if (v 0)

      { rebra[k][2] = 1; // ребро k исследовано

         в_стек(v);

         if (v не исследована) СYCLE (v);

         elseвывести_цикл_из_стека;

         из_стека;

      }

    }

  }

Функция вывести_цикл_из_стека выполняет вывод в файл последовательности вершин графа, входящих в найденный цикл, а также заполняет один столбец матрицы циклов путём поиска ребра, входящего в цикл, в массиве rebra и записи в соответствующую ячейку матрицы циклов значения 1.

3.  Пример работы алгоритма

Исходный файл:

4 4

1 2

1 4

4 2

3 2

Основная программа

CYCLE - 1

CYCLE - 2

CYCLE - 3

write

nver = 4; nreb = 4;

rebra =

{{1,2,0},{1,4,0},{2,4,0},{2,3,0}};

cycles =  4 – 4 + 1 = 1;

stek {1}; CYCLE (1)

versh {1,0,0,0};

k = 0; v = 2;

rebra[2] = {1,0,0,0};

stek{1,2};

CYCLE (2);

versh {1,1,0,0};

k = 0; rebra[0][3] = 1;

k = 2; v = 4;

rebra[2] = {1,0,1,0};

stek {1,2,4};

CYCLE (4)

versh {1,1,0,1};

k = 1; v = 1;

rebra[2] = {1,1,1,0};

stek {1,2,4,1};

write (1);

вывод: 1 4 2

result =

= {{13},{11},{22},{0}}

индекс – очерёдность

stek {1,2,4};

k = 2; rebra[2][2] = 1;

stek {1,2};

k = 3; v = 3;

rebra[2] = {1,1,1,1};

stek {1,2,3};

CYCLE (3)

versh {1,1,1,1};

k = 3; rebra [3][2] = 1;

stek {1,2}

stek {1}

k = 1; rebra[1][2] = 1;

stek {}

Похожие материалы

Информация о работе