
- •1. Введение
- •2. Модуль общего назначения syst.H
- •2.1. Общие сведения
- •2.2. Системные функции и макрооперации
- •2.3. Операции ввода/вывода
- •2.4. Математические функции
- •2.5. Специальные классы. Класс Spline для интерполяции данных сплайнами
- •3. Представление графов, классы и граф-объекты
- •3.1. Представление графов
- •3.2. Таблица связей, класс graph.
- •3.3. Матрицы смежности, класс matad.
- •3.4. Бинарные коды
- •3.5. Таблицы связей с весами вершин, класс graph_v
- •3.6. Таблицы связей с весами ребер, класс graph_r
- •3.7. Таблицы связей с весами вершин и ребер, класс graph_vr
- •3.8. Таблицы связей с координатами вершин, класс imgraph
- •3.9. Класс pinv
- •4. Форматы данных и преобразование форматов
- •4.1. Нумерация вершин графа
- •4.2. Представление графов
- •Int biclen(int n)
- •Int bic_graph(const graph& g, word* bic)
- •Int bic_mat(const matad& m, word* bic)
- •5. Функции создания графа
- •Imgraph::imgraph()
- •Imgraph::imgraph(const imgraph&)
- •6. Операции над графами и граф-объектами
- •Void add_edge(graph& g, int I, int k)
- •7. Ввод/вывод и преобразование файлов
- •Int write_r(file*)
- •Int read_r(file*)
- •Int gt_r(file* in, file* out)
- •Int cmp(const pinv& a, const pinv& b)
- •16. Примеры
- •Литература
- •Алфавитный указатель функций
3. Представление графов, классы и граф-объекты
3.1. Представление графов
Ниже приводятся структуры, представляющие графы различных видов, и соответствующие им классы библиотеки Algraph:
- класс graph, таблица связей;
- класс matad, матрица смежности;
- бинарные коды;
- класс graph_v, таблица связей с весами вершин;
- класс graph_r, таблица связей с весами ребер;
- класс graph_vr, таблица связей с весами вершин и ребер;
- класс imgraph, таблица связей с координатами вершин.
Каждый из классов определяет некоторую структуру данных - классовый тип, который используется для представления графов различных видов и выполнения операций над ними. Объект (экземпляр) некоторого из таких классов будем называть граф-объектом. Таким образом, граф-объект есть объект одного из следующих классов: graph,matad,graph_v,graph_r,grap_vr,imgraph.
3.2. Таблица связей, класс graph.
Класс graphможет использоваться для представления неориентированных графов, ориентированных графов, графов с петлями и кратными ребрами. Объект классаgraphсодержит следующую информацию:
- число вершин графа nv;
- вектор степеней вершин p;
- таблицу связей вершин r.
В таблице 1 приведен пример таблицы связей и вектора степеней вершин для неориентированного графа из рис.1 (используется внешняя нумерация вершин).
Рис.1.
Пример графа
Таблица 1. Вектор степеней и таблица связей графа
-
Номер вершины
p
r
1
2
2 , 5
2
3
1 , 4 , 6
3
1
4
4
4
2 , 3 , 6 , 7
5
2
1 , 6
6
4
2 , 4 , 5 , 7
7
2
4 , 6
Ниже приводится текст объявления класса graphс комментариями.
class graph
{ public:
int nv; // число вершин
vert *p; // вектор степеней вершин
vert **r; // таблица связей
graph(); // конструктор без параметров
graph(const graph&); // конструктор копирования
graph(const matad&); // конструктор преобразования
graph(int); // конструктор безреберного графа
~graph(); // деструктор
graph& operator=(const graph&); // операция присваивания
graph& operator=(const matad&); // присваивание с преобразованием
graph& operator=(int); // создать безреберный граф с n вершинами
graph& operator<<(FILE*); // ввод из текстового gt-файла
graph& operator>>(FILE*); // вывод в текстовый gt-файл
int operator==(int); // явл. ли граф безреберным с n верш.
int write_r(FILE*); // запись графа в r-файл, возвр. число ребер графа
int read_r(FILE*); // чтение графа из r-файла, возвр. число ребер
void write(FILE*); // вывод в текстовый файл или на экран
int read(FILE*); // ввод из текстового файла, возвр. form-фактор
void cnv(); // свернуть graph-объект
void rgl(); // упорядочить строки таблицы связей по возрастанию
int size(); // размер graph-объекта в байтах
int form(); // форм-фактор графа
int nrib(); // число ребер
};
Если g- переменная типаgraph, представляющая неориентированный граф из рис.1, тоg.p[i] представляет собой степеньi-той вершины графа, аg.r[i][k] есть номерk-той по счету вершины из числа тех, которые смежны вершине с номеромi.
Для номеров вершин и других данных, связанных с номерами вершин, использован тип vert, который представляет собой синоним, определенный с помощью оператораtypedefв файлеalgraph.h. По умолчанию типvertопределен как двухбайтовый типunsignedshort, что дает возможность использовать числа из интервала [0 , 65535]. При необходимости, синонимуvertможно поставить в соответствие другой тип (см. начало текста файлаalgraph.h) . Например, если типуvertпоставить в соответствиеunsignedchar, объектыgraphстанут более компактными, однако интервал значений для представления номеров вершин существенно уменьшится.
Вызов конструктора без параметров graph()приводит к созданиюgraph-объекта, соответствующего пустому (не имеющему ни одной вершины) графу. Размер такого объекта составляет 12 байтов (по 4 байта на каждый из трех основных компонент). Таким образом, выполнение строки программы
graph g;
приведет к созданию graph-объектаg, соответствующего пустому графу. В последствии, используя операций присваивания, добавления вершин и ребер можно сформировать требуемый граф.
Конструктор копирования graph(const graph&) позволяет создать копиюgraph-объекта. Следующие строки приведут к созданию двух одинаковых графов с именамиg1 иg2, каждый из которых будет представлять собой полный 10-вершинный граф:
graph g1 = complete(10);
graph g2(g1);
Конструктор преобразования graph(const matad&) создает таблицу связей (graph-объект) по заданной матрице смежности (matad-объект). При выполнении следующих двух строк вначале создается матрица смежностиMдля 15-вершинного безреберного графа, а затем создается таблица связейg, соответствующая матрице смежностиM:
matad M(15);
graph g(M);
Конструктор безреберного графа graph(int) создает таблицу связей безреберного графа с заданным числом вершин.
Задачей деструктора ~graph() является удаление всех компонент (включая динамические - массивыpиr)graph-объекта при его уничтожении.
Функция класса graph& operator = (const graph&) реализует операцию динамического присваивания дляgraph-объектов. Эта функция дает возможность выполнять операцию присваивания в тех случаях, когда левый и правый операнды операции " = " соответствуют графам с разным числом вершин и, следовательно, имеют разные размеры.
graph g1 = complete(5);
graph g2 = complete(20);
graph g3(g1);
g1 = g2;
g2 = g3;
В этом примере создаются graph-объекты:
g1 - полный граф с 5 вершинами (размер объекта 72 байт),
g2 - полный граф с 20 вершинами (размер объекта 852 байт),
g3 - копия графаg1.
После выполнения присваивания g1 =g2graph-объектg1 становится точной копиейg2, увеличивая при этом свой размер с 72 до 852 байт. При этом дополнительные 780 байт изымаются из динамически распределяемой области памяти - кучи.
При выполнении второго присваивания g2 =g3 объектg2 уменьшает свой размер на 780 байт, возвращая их в общий пул памяти.
Функция класса graph& operator = (const matad&) реализует присваивание с преобразованием типа. В следующем примере
matad M;
graph g;
........
g = M;
после выполнения присваивания переменная gполучает значение, соответствующее матрице смежностиM.
Функция класса graph& operator = (int)позволяет преобразовать граф (левый операнд) к значению, которое соответствует безреберному графу с заданным числом вершин. Например, выполнение следующих строк
graph g;
g = 100;
формирует значение g, соответствующее 100-вершинному безреберному графу.
Операция вида g= 0 превращает графgв пустой.
Функция класса int operator == (int) перегружает операцию сравнения, которая проверяет, является ли граф - левый операнд безреберным с заданным числом вершин. Например, в следующей строке проверяется, является ли графgпустым:
if (g==0) ...
Функция класса int size()возвращает размерgraph-объекта в байтах. Результат, возвращаемый этой функцией, зависит не только от числа вершин и числа ребер графа, но также и от того, какой тип поставлен в соответствие имениvert.
Процедура класса void cnv() выполняет свертываниеgraph-объекта, т.е. приведение его к значению, соответствующему пустому графу (то же самое делает операция присваивания видаg= 0 ). Пример использования функцийsize() иcnv() :
graph g = complete(20); // создать 20 вершинный полный граф g
cout << g.size() << endl; // получить размер объекта g (852 байт)
g.cnv(); // свернуть g в пустой граф
cout << g.size() << endl; // получить размер объекта g (12 байт)
Процедура класса void rgl() упорядочивает строки таблицы связей по возрастанию номеров вершин. Эта процедура может использоваться, если таблица связей некоторого графа готовится к публикации. Процедура может также понадобиться при проверке изоморфности помеченных графов.
Функция класса int nrib()возвращает число ребер текущего графа.
Функция класса int form()возвращаетform-фактор текущего графа, значение которого определено следующим образом:
0 - если граф не ориентирован, не имеет петель и не имеет кратных ребер,
1 - если граф имеет ориентированные ребра (дуги),
2 - если граф имеет петли,
4 - если граф имеет кратные дуги или петли
или сумму значений из этого набора в любой комбинации. Например, орграф с кратными дугами, но без петель, будет иметь form-фактор равный 5, а неориентированный граф без краных ребер, но с петлями - 2.