Графы и их представление в STL Выполнила Тагирова Лиана 271 ПИ Что такое граф? Граф или неориентированный граф G — это упорядоченная пара G = <V,E>, для которой выполнены следующие условия: V это множество вершин или узлов, E это множество пар (неупорядоченных) различных вершин, называемых рёбрами. Свойства графа: •Два ребра называются смежными, если они имеют общую концевую вершину. •Два ребра называются кратными, если множества их концевых вершин совпадают. Ориентированный граф Ориентированный граф (сокращенно орграф) G — это упорядоченная пара G = <V,A>, для которой выполнены следующие условия: V это множество вершин или узлов, A это множество (упорядоченных) пар различных вершин, называемых дугами или ориентированными рёбрами. Дуга — это упорядоченная пара вершин (v,w), где вершину v называют началом, а w — концом дуги. Можно сказать, что дуга v w ведёт от вершины v к вершине w. Смешанный граф Смешанный граф G — это граф, в котором некоторые рёбра могут быть ориентированными, а некоторые — неориентированными. Записывается упорядоченной тройкой G= <V,E,A>, где V, E и A определены так же, как для ориентированного графа. Путь: виды и свойства Путём (или цепью) в графе называют конечную последовательность вершин, в которой каждая вершина (кроме последней) соединена со следующей в последовательности вершин ребром. Путь: виды и свойства Ориентированным путём в орграфе называют конечную последовательность вершин , для которой все пары являются (ориентированными) рёбрами. Циклом называют путь, в котором первая и последняя вершины совпадают. При этом длиной пути (или цикла) называют число составляющих его рёбер. Заметим, что если вершины u и v являются концами некоторого ребра, то согласно данному определению, последовательность (u,v,u) является циклом. Чтобы избежать таких «вырожденных» случаев, вводят следующие понятия. Дополнительные характеристики графов Граф называется: связным, если для любых вершин u,v есть путь из u в v. сильно связным или ориентированно связным, если он ориентированный, и из любой вершины в любую другую имеется ориентированный путь. деревом, если он связный и не содержит простых циклов. Представление графов Абстрактный граф в С++ class Graph { public: Graph (int numV_, bool directed_): numV(numV_), numE(0), directed(directed_) {} virtual ~Graph() {} int V() const {return numV;} int E() const {return numE;} bool isDirected() const {return directed;} virtual void insert(Edge) = 0; virtual void remove (Edge) = 0; virtual bool isEdge(int,int) const = 0; protected: int numV; int numE; bool directed; }; Представление графов Матрица смежности Список смежных вершин Матрица смежности •Матрица M размером NxN (N – мощность множества вершин V (|V|=N) •Элемент матрицы M[i,j] равен 1, если (i,j) – ребро и 0 – если нет. Класс vector Контейнер vector обеспечивает структуру данных непрерывной областью памяти. Это позволяет обеспечивает эффективный прямой доступ к любому элементу контейнера vector посредством операции индексирования []. Все алгоритмы STL могут работать с контейнером vector. Итераторы для vector обычно реализуются как указатели на элементы контейнера vector. Матрица смежности-реализация class AdjMatrixGraph : public Graph {public: std::vector<std::vector<bool> > adj; // двухмерн. массив AdjMatrixGraph(int numV_, bool directed_ = false) : Graph(numV_, directed_) { adj.resize(numV_); for (int i = 0; i != numV; ++i) adj[i] = std::vector<bool>(numV_, false); } void insert (Edge e) { if (!adj[e.v][e.w]) { adj[e.v][e.w] = true; if (!directed) adj[e.w][e.v] = true; ++numE; } } Матрица смежности-реализация 2 } void remove (Edge e) { if (adj[e.v][e.w]) { adj[e.v][e.w] = false; if (!directed) adj[e.w][e.v] = false; --numE; } }; bool isEdge(int u, int v) const { return adj[u][v]; } Характеристики представления Проверка на существование ребра isEdge(i,j) – O(1) Перебор всех верших – O(n) Перебор всех ребер - O(n2) Список смежных вершин Представляет собой набор связных списков, в которых хранятся инцендентные соседи каждого ребра Реализация class AdjListGraph : public Graph { public: std::vector<std::list<int> > adj; AdjListGraph(int numV_, bool directed_ = false) : Graph(numV_, directed_), adj(numV_) {} void insert(Edge e) { if (!(0 <= e.v && e.v <= numV && 0 <= e.w && e.w < numV)) throw "Invalid vertex"; adj[e.v].push_back(e.w); ++numE; if (!directed) adj[e.w].push_back(e.v); } Реализация } void remove(Edge e) { std::list<int>::iterator itr = std::find(adj[e.v].begin(), adj[e.v].end(), e.w); if (itr != adj[e.v].end()){ adj[e.v].erase(itr); --numE; if (!directed) { itr = std::find(adj[e.w].begin(), adj[e.w].end(), e.v); adj[e.w].erase(itr); } } } bool isEdge(int u, int v) const { std::list<int>::const_iterator itr = std::find(adj[u].begin(), adj[u].end(), v); return itr != adj[u].end(); } Характеристики представления isEdge (i,j) – O(|E|) Перебор вершин - O(|E|) Перебор всех ребер - O(|E|) Обычно, |E|<<|V|2,поэтому чаще используют связный список смежных вершин Пример использования на задаче: Постановка задачи: Предположим, к примеру, что мы используем текстовые строки для кодирования названий городов и хотим сконструировать карту, где значения ребер графа — это расстояние между двумя соответствующими городами. Такой граф показан на рис.: Взвешенный граф Операторы инициализации графа: Можно использовать набор классических алгоритмов для обработки таких графов. Одним из примеров является алгоритм Дейкстры поиска кратчайшего пути. Требуется указать город, с которого начинается путь. При этом создается приоритетная очередь для пар расстояние/ город. Она инициализируется нулем для начального города. Приоритетная очередь содержит города в порядке от ближайшего до самого дальнего. При каждой итерации цикла мы извлекаем из очереди город. Если для него еще не найдено кратчайшего пути, записывается текущее расстояние и путем проверки графа вычисляется расстояние до соседних городов. Этот процесс продолжается до тех пор, пока не будет исчерпана приоритетная очередь. Список исрользованных материалов: Лекции по курсу «Алгоритмы и структуры данных» Г. Шилдт «Полный справочник по С++» электронная энциклопедия «wikipedia.org» http://www.freesource.info/