25301-1 (AGraph: библиотека классов для работы с помеченными графами), страница 3

2016-07-30СтудИзба

Описание файла

Документ из архива "AGraph: библиотека классов для работы с помеченными графами", который расположен в категории "". Всё это находится в предмете "информатика" из 1 семестр, которые можно найти в файловом архиве . Не смотря на прямую связь этого архива с , его также можно найти и в других разделах. Архив можно найти в разделе "курсовые/домашние работы", в предмете "информатика, программирование" в общих файлах.

Онлайн просмотр документа "25301-1"

Текст 3 страницы из документа "25301-1"

G:=TGraph.Create;

V:=G.AddVertex;

E:=G.AddEdge(V, G.AddVertex);

// создание динамического массива для хранения целого

атрибута вершин графа (первый параметр - количество

элементов, второй - значение по умолчанию)

AttrVector1:=TIntegerVector.Create(G.VertexCount, 0);

// создание динамического массива для хранения строкового

атрибута ребер графа

AttrVector2:=TStrLst.Create;

AttrVector2.Count:=G.EdgeCount;

// присваивание значений атрибутам вершины V и ребра E графа

AttrVector1[V.Index]:=1;

AttrVector2[E.Index]:='AGraph';

Пример 2. Использование динамического массива для хранения атрибутов вершин и ребер графа в библиотеке AGraph.

В библиотеке LEDA для реализации аналогичного способа привязки атрибутов к вершинам и ребрам графа необходимо использовать специальные структуры данных - классы node_array и edge_array (либо отличные от них по реализации, но эквивалентные в данном контексте классы node_map и edge_map). Это связано с тем, что в LEDA объекты-вершины и объекты-ребра хранятся в списках, а не в динамических массивах.

// создание графа

graph G;

node v = G.new_node();

edge e = G.new_edge(v, G.new_node());

// создание структуры node_arrray для хранения атрибута типа int

для вершин графа G

node_array attr1(G);

// создание структуры edge_arrray для хранения атрибута типа

string для ребер графа G

edge_array attr2(G);

// присваивание значений атрибутам вершины v и ребра e графа G

attr1[v]:=5;

attr2[e]:="Saarbruecken";

Пример 3. Использование классов node_array и edge_array для хранения атрибутов вершин и ребер графа в библиотеке LEDA.

Описанный способ хранения атрибутов подходит только для статических графов, т.к. при модификации графа соответствие между вершинами (ребрами) графа и элементами вспомогательной структуры данных теряется. Кроме того, определенные таким образом атрибуты не могут автоматически сохраняться при записи графа в поток или копироваться при копировании графов. Наиболее естественным способом "надежной" привязки атрибутов к вершинам (ребрам) графа является хранение атрибутов (или ссылок на атрибуты) непосредственно в объектах-вершинах (объектах-ребрах) графа. Библиотеки LEDA и GTL (University of Passay) предлагают для этого параметризуемый класс графов, библиотека GTL (Н-Новгород) - использование классов-"привкусов" (Flavor) и множественного наследования. Оба этих метода хорошо работают, когда набор атрибутов вершин (ребер) графа известен во время компиляции программы. В библиотеке AGraph реализованы еще более гибкие средства, позволяющие создавать и уничтожать атрибуты динамически, в процессе исполнения.

Параметризуемый класс графов в LEDA позволяет создавать графы, с каждой вершиной и каждым ребром которого связан атрибут заданного типа (см. пример 4). Доступ к таким атрибутам является в LEDA более эффективным, чем доступ к атрибутам, определенным с помощью node_array и edge_array.

// создание графа

GRAPH H;

node v = H.new_node();

edge e = H.new_edge(v, H.new_node());

// присваивание значений атрибутам вершины v и ребра e графа G

H[v]:=5;

H[e]:="Saarbruecken";

Пример 4. Использование параметризуемого класса графов LEDA.

В библиотеке GTL (Н-Новгород) для создания вершин и ребер с заданными свойствами используется механизм классов-"привкусов" (Flavor). Данный механизм может использоваться для привязки атрибутов к вершинам и ребрам графа, хотя его возможности этим не ограничиваются. Flavor - это абстрактный (чисто виртуальный в терминологии С++) класс, который применяется в качестве "добавки" при порождении новых классов с использованием множественного наследования. Flavor требует, чтобы объект обладал некоторыми свойствами, но не привносит их в объект сам. Например, класс CWeightedEdge ("взвешенное ребро") порождается от классов CEdge ("ребро") и специального класса CWeightFlavor. В классе CWeightFlavor определены два абстрактных виртуальных метода - SetWeight и GetWeight, которые должны быть перекрыты в классе CWeightedEdge. GTL предоставляет ряд "привкусов" для построения распространенных типов объектов (при необходимости пользователи могут расширить набор Flavor). Порожденные с помощью Flavor классы, в свою очередь, используются в качестве параметров шаблонных классов графов для создания классов графов, вершины и ребра которых обладают заданными свойствами (см. пример 5).

// определение класса CWEdge (взвешенное ребро)

template class CWEdge:public CEdge,CWeightFlavor

{

protected:

double m_dWeight;

public

...

virtual void SetWeight(double dWeight) {m_dWeight=dWeight;}

virtual double GetWeight() const {return m_dWeight;}

...

};

// определение синонимов для вершин и ребер

#define V CVertex

#define E CWEdge

...

// создание ориентированного графа с использованием представления

в виде списков смежности

CGraphAdjList xGraphAL(TRUE);

// создание графа с использованием макросов

VPOS xPos1,xPos2,xPos3;

AL_ADDVERTEX(&xGraphAL,new V,xPos1);

AL_ADDVERTEX(&xGraphAL,new V,xPos2);

AL_ADDVERTEX(&xGraphAL,new V,xPos3);

AL_ADDEDGE(&xGraphAL,xPos1,xPos2,new E(1.0));

AL_ADDEDGE(&xGraphAL,xPos1,xPos3,new E(3.0));

// доступ к весу ребра (методы GetWeight и SetWeight определены в

классе CWeightFlavor)

E* e = xGraphAL.GetIncidEdgeAt(xPos1, 0);

double w = e->GetWeight;

e->SetWeight(1.0);

Пример 5. Использование классов-"привкусов" в GTL (Н-Новгород).

Смысл в использовании Flavor проявляется, когда объект должен обладать несколькими свойствами: например, требуется "взвешенное ребро с пропускной способностью". Если использовать обычное наследование, то можно построить два различных класса, которые фактически представляют один и тот же вид ребра. Множественное наследование от классов "взвешенное ребро" и "ребро с пропускной способностью" также не помогает, т.к. при этом класс "ребро" будет наследоваться дважды. Проблема легко решается с помощью Flavors: достаточно определить Flavor "пропускная способность" и породить требуемый класс от класса TEdge и двух Flavor.

Методы привязки атрибутов к элементам графа с помощью параметризуемых классов графов, реализованные в библиотеке LEDA, или с помощью классов-"привкусов", реализованные в GTL (Н-Новгород), используют средства языка C++, которые отсутствуют в Object Pascal - шаблоны и множественное наследование. Данное обстоятельство привело к реализации в библиотеке AGraph собственного механизма поддержки атрибутов. С одной стороны, это решение является единственно возможным; с другой стороны, данный механизм является более высокоуровневым и обладает большей гибкостью, чем средства других библиотек.

Атрибуты в AGraph фактически являются переменными, определенными на элементах графа. Каждый атрибут имеет уникальное имя и тип, относящийся к одному из нескольких предопределенных типов. Типы атрибутов соответствуют основным типам языка программирования Object Pascal (Integer, Boolean, Char, Double, String и др.). Библиотека позволяет динамически создавать и уничтожать атрибуты вершин и ребер графа, причем можно создавать как общие для всех вершин (ребер) графа атрибуты, так и локальные атрибуты, определенные только для отдельных вершин (ребер) графа (см. пример 6). Доступ к атрибутам осуществляется с помощью реализованного в Object Pascal механизма свойств (property). Для каждого из поддерживаемых типов атрибутов определены свои методы доступа (AsBool, AsChar, AsInt8, AsInt16, AsInt32, AsFloat, AsString и т.д.), благодаря чему на атрибуты распространяется контроль типов. Поскольку граф "владеет" всеми своими атрибутами, их сохранение, восстановление и копирование при выполнении соответствующих операций над графом осуществляется автоматически, полностью "прозрачно" для программиста - пользователя библиотеки.

// создание графа

G:=TGraph.Create;

// создание общего атрибута вершин графа типа String с именем 'Name'

G.CreateVertexAttr('Name', AttrString);

// присваивание значений атрибуту 'Name' вершин 0 и 1 графа

G[0].AsString['Name']:='Moscow';

G[1].AsString['Name']:='Minsk';

// уничтожение общего атрибута вершин графа с именем 'Name'

G.DropVertexAttr('Name');

// создание локального атрибута типа Integer с именем 'Color'

для вершины 0 графа и присваивание ему значения

G[0].Local.Map.CreateAttr('Color', AttrInteger);

G[0].Local.AsInteger['Color']:=1;

Пример 6. Работа с атрибутами в библиотеке AGraph.

Для поддержки атрибутов в библиотеке используется собственный механизм распределения памяти, который обеспечивает высокую эффективность операций создания и уничтожения атрибутов и малый расход памяти для хранения атрибутов. Единственным недостатком данного подхода является относительно медленный доступ к атрибутам: основным способом идентификации атрибута является его имя, поэтому при каждом обращении к атрибуту по имени осуществляется поиск в таблице имен атрибутов. Библиотека AGraph предоставляет низкоуровневые средства, позволяющие значительно понизить "накладные расходы" на доступ к атрибутам (ценой некоторого усложнения программирования и потенциального снижения надежности). Так, можно один раз вычислить смещение некоторого атрибута в блоке памяти, отведенном для хранения атрибутов, для того, чтобы впоследствии обращаться к данному атрибуту по смещению, а не по имени. Благодаря этому исключается относительно медленный этап поиска в таблице имен атрибутов, но снижается надежность. Существует и другой способ повышения производительности, наиболее эффективный при интенсивном использовании атрибутов: перед началом работы некоторой процедуры следует скопировать атрибуты во временную структуру данных, которая поддерживает прямой доступ (например, динамический массив), и в дальнейшем работать с этой структурой, т.е. использовать на "локальном уровне" способ привязки данных к графу, который уже был рассмотрен. Разумеется, в этом случае необходимо помнить о синхронизации графа и временной структуры данных.

Атрибуты в библиотеке AGraph предназначены не только для привязки пользовательских данных, но и активно используются внутри самой библиотеки. Например, для ребер графа (класс TEdge) определен метод RingEdge, который проверяет, является ли ребро кольцевым (т.е. при удалении данного ребра количество связных компонент графа не увеличивается). Поскольку эта проверка является относительно дорогой операцией (время выполнения может достигать O(n+m)), нежелательно осуществлять ее при каждом обращении к методу RingEdge. В библиотеке используется следующий прием: при первом обращении к методу RingEdge библиотека выполняет соответствующий алгоритм, создает глобальный атрибут ребер графа и запоминает в нем результат работы алгоритма. До тех пор, пока граф не подвергнется изменениям, которые могут повлечь нарушение правильности запомненных значений, при последующих обращениях к методу RingEdge возвращается запомненное значение. Если граф подвергнется таким изменениям, то атрибут будет автоматически уничтожен. То же самое можно было бы сделать, добавив в класс TEdge дополнительное поле для запоминания результатов выполнения метода RingEdge, однако в таком случае при отсутствии обращений к методу RingEdge память, необходимая для хранения данного поля, расходовалась бы напрасно.

6. Поддержка различных видов графов

Одна из проблем, которые возникают при разработке универсальной библиотеки для работы с графами - как реализовать поддержку различных видов графов: ориентированных и неориентированных графов, взвешенных графов, деревьев и т.д. Вид графа, во-первых, задает набор атрибутов, которые определены для вершин и ребер данного графа (например, вес ребра для взвешенного графа или указатель на родительскую вершину для дерева), во-вторых, определяет, какие методы можно применять к этому графу, и, в-третьих, может влиять на их выполнение (например, метод поиска кратчайшего пути между заданными вершинами графа выполняется по-разному для ориентированных и неориентированных графов).

Библиотеки LEDA явно поддерживает два вида графов - ориентированные и неориентированные графы: в библиотеке определены параметризуемые классы (GRAPH и UGRAPH) для каждого из этих видов. Какие-либо средства для поддержки других видов графов не предусмотрены. Если процедура или функция являются специфичной для графа определенного вида (например, функция нахождения максимального потока в транспортной сети), то все необходимые параметры (в последнем примере - пропускные способности дуг сети) непосредственно передаются в эту процедуру или функцию (например, с помощью динамических массивов).

Библиотека GTL (Н-Новгород) также непосредственно поддерживает ориентированные и неориентированные графы - конструкторы классов-графов по умолчанию строят неориентированный граф, однако существуют варианты конструкторов с явным заданием "ориентированности" графа. В то же время, библиотека поддерживает и другие виды графов с помощью классов-"привкусов". Алгоритмы, специфичные для конкретных видов графов, реализованы как обычные функции-члены (методы) параметризуемых классов графов, но в этих функциях неявно предполагается, что классы-вершины и классы-ребра, используемые при конкретизации данного параметризуемого класса графов, предоставляют необходимые интерфейсные функции. Это, в свою очередь достигается наследованием классов-вершин и классов-ребер от соответствующих классов-"привкусов".

Свежие статьи
Популярно сейчас
Почему делать на заказ в разы дороже, чем купить готовую учебную работу на СтудИзбе? Наши учебные работы продаются каждый год, тогда как большинство заказов выполняются с нуля. Найдите подходящий учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
5192
Авторов
на СтудИзбе
433
Средний доход
с одного платного файла
Обучение Подробнее