
- •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. Примеры
- •Литература
- •Алфавитный указатель функций
16. Примеры
Пример 1
В приведенной ниже программе используются:
- конструкторы graph(graph&), graph(matad), matad(matad), matad(graph);
- перегруженные операции присваивания graf=graf,graf=matad,graf=int,
matad = matad, matad = graf, matad = int;
- операции сравненияgraf==graf,matad==matad.
Используется также функция определения числа ребер графа nrib(g)и функцияabout_algraph(), которая возвращает указатель на строку, содержащую краткую информацию о модулеAlgraph/C++.
// Example 001
#include "algraph.cpp"
void main()
{ cout << about_algraph();
FILE* f= fopen("t_1.gt","r");
char q=0, s[80];
int r;
graph g1;
fscanf(f,"%s",s); printr(s); puts("");
g1<<f;
fclose(f);
r=nrib(g1);
printr("Число ребер = "); printf("%d \n",r);
if (r!=613) { q=1; puts("Error 001"); }
graph g2(g1);
if (!(g1==g2)) { q=2; puts("Error 002"); }
matad M1(g1);
matad M2(M1);
if (!(M1==M2)) { q=3; puts("Error 003"); }
g2=0;
g2=graph(matad(g1));
if (!(g1==g2)) { q=4; puts("Error 004"); }
if (q==0) puts("Test was Passed Ok");
}
Пример 2
В следующем примере открывается файл "002.gt" для записи в текстовом режиме, затем с помощью вызова функцииrandgraph(50, 0.5) создается случайный графgс 50 вершинами и с реберным заполнением 0.5 в виде таблицы связей, которая затем записывается в файл "002.gt". При этом в первую строку файла "002.gt" записывается заголовок к таблице связей графа.
// Example 002
#include "algraph.cpp"
void main()
{ FILE* f= fopen("002.gt","w");
graph g= randgraph(50,(float)0.5);
fprintf(f,"Случайный_граф_с_50_вершинами \n");
g>>f;
fclose(f);
}
Пример 3
В следующем примере тестируется работа функций, которые находят плотность графа: - dens(g) - используетсяNB-метод;
- densi(g) - используетсяVP-алгоритм.
В программе используются функция complete(n) - получение полного графа сnвершинами иrandgraph(n,r) - получение случайного графа сnвершинами иrребрами.
// Example 003
#include "algraph.cpp"
void main()
{ int n,D1,D2,q=0;
graph g;
for (n=0;n<5;n++)
{ g=complete(n);
D1=dens(g); D2=densi(g);
printf("*");
if (n!=D1 || D1!=D2)
{ printf("\n Error: n=%d D1=%d D2=%d \n",n,D1,D2); q=1; break; }
}
puts("");
for (n=0;n<80;n++)
{ g=randgraph(n,n*n/4);
D1=dens(g); D2=densi(g);
printf("*");
if (D1!=D2)
{ printf("\n Error: n=%d D1=%d D2=%d \n",D1,D2); q=1; }
}
puts("");
if (q) puts("Test was Failed");
else puts("Test was finished OK");
}
Пример 4
В следующем примере тестируется работа функций:
- o_graph(n) - получение графа типа "кольцо" сnвершинами;
- complete(n) - получение полногоn-вершинного графа;
- join(g1,g2) - получить граф, который является соединением графовg1 иg2;
- iseuler(g) - проверить, является ли графgэйлеровым.
// Тестирование функций: o_graph, join, complete, iseuler
// Example 004
#include "algraph.cpp"
void main()
{ graph g1,g2,g3;
g1=o_graph(5);
g2=join(g1,g1);
g3=complete(5);
int i1=iseuler(g1),
i2=iseuler(g2),
i3=iseuler(g3);
if (i1==1 && i2==0 && i3==1) puts("Test Ok");
else puts("Test Fail");
}
Пример 5
В этом примере тестируется функция findcycl(g,k,L,e) , которая находит в графеgциклe, который имеет длинуLи проходит через вершину с номеромk. Для чтения графа изgt-файла используется перегруженная операция g << f .
// Example 005
#include "algraph.cpp"
void main()
{ printr("Проверка функции поиска цикла findcycl\n");
int i,q, k=2, er=0;
vert e[8];
graph g;
FILE* f = fopen("005.gt","r"); errhalt(f==0,"File not found");
g << f;
fclose(f);
q= findcycl(g,k,8,e);
if (q) { printr("Цикл длиной 8 найден: ");
for (i=0;i<8;i++) printf("%d ",e[i]+1);
}
else { printr("ОШИБКА: цикл не найден"); er=1; }
puts("");
q= findcycl(g,k,5,e);
if (!q) printr("Цикла длиной 5 нет\n");
else { printr("ОШИБКА: найден цикл, которого нет"); er=1; }
if (er==0) printr("Тест выполнен успешно \n");
}
Пример 6
Показано использование функции hamilt_n(g), которая находит количество гамильтоновых циклов в графеg. При выполнении строки программы
(A<<f)>>stdout;
выполняется чтение графа gиз файлаfи этот граф сразу же выводится на экран.
// Example 006
// Тестирование функции hamilt_n 04.1998-01.2004
#include "Algraph.cpp"
void main()
{ graph g;
FILE *f=rfopen("006.gt");
puts("Graph for testing:");
(g<<f)>>stdout;
fclose(f);
int Nhc= hamilt_n(g);
printf("Number of the Hamilton Cycles = %d \n",Nhc);
if (Nhc==284112) puts("Testing: OK");
else puts("Testing: Failed");
}
Пример 7
В этом примере показано использование следующих функций:
- ishamilt(g), определяет, является ли графgгамильтоновым;
- hamilt_c(g,hc), находит гамильтонов циклhcв графеg;
- hamilt_n(g), вычисляет количество гамильтоновых циклов в графеg.
// Example 007
#include "Algraph.cpp"
void main()
{ puts("Testing of functions: ishamilt, hamilt_c, hamilt_n");
char* mes;
char* mes1 ="Graph is hamiltonous!";
char* mes2 ="Graph is NOT hamiltonous!";
FILE* f= fopen("007.gt","r"); errhalt(f==0,"File was Not Found!");
graph g; (g<<f)>>stdout; ;
fclose(f);
vert* hc= new vert[g.nv];
int i,q; ulong Nhc;
printf("hamilton: ");
mes= ishamilt(g)? mes1 : mes2;
printf("%s \n",mes);
printf("hamilt_c: ");
q= hamilt_c(g,hc);
if (q==0) puts(mes2);
else { printf("Hamilton cycle was found: (");
for (i=0;i<g.nv-1;i++) printf("%d,",hc[i]+1);
printf("%d) \n",hc[g.nv-1]+1); }
printf("hamilt_n: number of hamiltonous cycles = %lu \n", Nhc=hamilt_n(g));
delete[] hc;
if (Nhc==284112) puts("Testing: OK");
else puts("Testing: Failed");
}
Пример 8
В примере, приведенном ниже, из файла gt-формата "008.gt" считывается набор графов, для каждого из них определяется параметрNhc- количество гамильтоновых циклов и полученная информация выводится на экран в виде таблицы.
// Example 008
#include "Algraph.cpp"
void main()
{ graph g;
char infa[40];
FILE *f=rfopen("008.gt");
puts("Numbers of Hamiltonous Cycles");
puts("---------------------------------");
puts(" Graph Nhc ");
puts("---------------------------------");
for (;;)
{ fscanf(f,"%s",infa); if (feof(f)) break;
g<<f;
printf(" %8s %lu \n", infa, hamilt_n(g));
}
puts("---------------------------------");
fclose(f);
}
Пример 9
В этом примере из файла r-формата "009.r" считывается набор графов и определяется, сколько из них принадлежит к графам определенного вида:
- двухсвязные (функция isnonbridge(g)),
- блоки (функция isblock(g)),
- эйлеровы графы (функция iseuler(g)),
- гамильтоновы (функция ishamilt(g)),
- двудольные (функция isdual(g)),
- регулярные (функция isregular(g)).
Такие же данные вычисляются и для семейства дополнительных графов. Результаты выводятся на экран в виде таблицы. Для получения дополнительного графа используется унарная операция ~g.
// Example 009
#include "algraph.cpp"
void main()
{ word nv,nr,dr;
ulong k,ng,ks;
ulong Nconn =0, Mconn =0, // 0
Nnonbr=0, Mnonbr=0, // 1
Nblock=0, Mblock=0, // 2
Neuler=0, Meuler=0, // 3
Nham =0, Mham =0, // 4
Ndual =0, Mdual =0, // 5
Nreg =0, Mreg =0; // 6
FILE* in= fopen("009.r","rb"); errhalt(in==0,"Cannot open Input File!");
hread(in,nv,nr,ng,ks);
graph g(nv);
for (k=0;k<ng;k++)
{ g.read_r(in);
if (isconn(g)) { Nconn++;
if (isnonbridge(g)) Nnonbr++;
if (isblock(g)) Nblock++;
if (iseuler(g)) Neuler++;
if (ishamilt(g)) Nham++;
if (isdual(g)) Ndual++;
if (isregular(g)) Nreg++;
}
g=~g;
if (isconn(g)) { Mconn++;
if (isnonbridge(g)) Mnonbr++;
if (isblock(g)) Mblock++;
if (iseuler(g)) Meuler++;
if (ishamilt(g)) Mham++;
if (isdual(g)) Mdual++;
if (isregular(g)) Mreg++;
}
}
gotoxy(1,wherey());
if (k!=ng) { printr("Неверное чтение файла!\n");
goto exit; }
fclose(in);
dr=(word)(nv*(nv-1)/2-nr);
puts("");
printr("Число ребер = "); printf("%8u %7u \n",nr,dr);
printr("Всего графов = "); printf("%8lu %8lu \n",ng,ng);
printr("Связных = "); printf("%8lu %8lu \n",Nconn, Mconn);
printr("В том числе: \n");
printr("Без мостов = "); printf("%8lu %8lu \n",Nnonbr,Mnonbr);
printr("Блоков = "); printf("%8lu %8lu \n",Nblock,Mblock);
printr("Эйлеровых = "); printf("%8lu %8lu \n",Neuler,Meuler);
printr("Гамильтоновых = "); printf("%8lu %8lu \n",Nham, Mham);
printr("Двудольных = "); printf("%8lu %8lu \n",Ndual, Mdual);
printr("Регулярных = "); printf("%8lu %8lu \n",Nreg, Mreg);
exit: pause;
}
Пример 10
В этом примере тестируется функция isblock(g), которая проверяет, является ли графgблоком. Вначале, с помощью функцииcomplete(n) создается пара полных трехвершинных графовgиh. Затем находится их простое объединениеr1, которое формируется с помощью перегруженной операции "+". В графеr1 создается ребро, соединяющее вершины 2 и 3. После этого создается копия графаr1 с именемr2. В графе r2 создается ребро, соединяющее врешины 1 и 4. Для создания ребра используется функцияadd_r(g,i,k). Далее выполняется проверка, являются ли графыr1 иr2 блоками.
// Example 010
#include "algraph.cpp"
void main()
{ graph g=complete(3), h=complete(3), r1=g+h, r2;
add_r(r1,2,3); r2=r1; add_r(r2,1,4);
int q1=isblock(r1), q2=isblock(r2);
if (q1==0 && q2==1) puts("\nAll Steps of the Test Passed Ok");
else puts("\nTest Failed");
}
Пример 11
В следующем примере тестируется функция n_orbit(g) , которая определяет количество вершинных орбит группы автоморфизмов графаg.
// Example 011
#include "algraph.cpp"
void main()
{ FILE* in= fopen("011.gt","r"); errhalt(in==0,"File could not opened");
char str[100];
graph g;
puts("Graph for testing:");
fscanf(in,"%s",str); puts(str);
(g<<in)>>stdout;
int Norb= n_orbit(g);
printf("Norb = %d \n",Norb);
fclose(in);
if (Norb==15) puts("Test was Passed OK");
else printf("Error: Wrong Value Norb = %d \n",Norb);
}
Пример 12
В примере, приведенном ниже, из файла gt-формата "012.gt" считывается набор графов, для каждого из них определяется порядок группы автоморфизмов, полученная информация выводится на экран в виде таблицы. Для определения порядка группы автоморфизмов используется функцияnaut(g).
// Example 012
#include "algraph.cpp"
void main()
{ graph g;
char infa[40];
FILE *f=fopen("012.gt","r"); errhalt(f==0,"Illegal File Name!");
puts(" Automorphism Group Orders");
puts("-----------------------------");
puts(" Graph Naut ");
puts("-----------------------------");
for (;;)
{ fscanf(f,"%s",infa); if (feof(f)) break;
g<<f;
printf("%8s %8lu \n", infa, naut(g));
}
puts("-----------------------------");
fclose(f);
}
Пример 13
В этом примере тестируются функции:
- nisos(g1,g2), количество изоморфизмов для графовg1 иg2;
- naut(g), число автоморфизмов для графаg;
-n_orbit(g), количество вершинных орбит группы автоморфизмов графаg.
Из файла, который содержит набор графов в gt-формате, считываются графы и для каждого из них подсчитывается число автоморфизмов, вначале используя вызов функции видаnisos(g,g) и, затем, используя функциюnaut(g). Результаты выводятся на экран в виде таблицы и проверяется правильность данных, которые в ней содержатся. Во второй части программы предлагается ввести номер графа, для которого далее вычисляются вершинные орбиты группы автоморфизмов.
// Example 013
#include "algraph.cpp"
void main()
{ graph g[15];
ulong Naut1, Naut2, S=0;
int i,j;
char infa[40];
FILE *f=fopen("013.gt","r");
errhalt( f==0, "Illegal File Name!");
puts("\nTesting of the function nisos(graf&,graf&).");
puts("Set of Strong Regular (25,12)-graphs");
puts("---------------------------------");
puts(" Graph Naut ");
puts("---------------------------------");
for (i=0;i<15;i++)
{ fscanf(f,"%s",infa);
g[i]<<f;
Naut1=nisos(g[i],g[i]); Naut2=naut(g[i]);
if (Naut1!=Naut2) printf("Error for graph number %d \n",i);
S+=Naut2;
printf(" %8s %6lu \n", infa, Naut2);
}
puts("---------------------------------");
fclose(f);
if (S!=784) { printf("Error: S=%lu , must be = 784",S);
goto exit;
}
int Num, q[100],M,nv,Norb1,Norb2;
graph* vg;
for (;;)
{ puts("\nPut in graph number for calculation of the vertex orbits");
printf("Graph Number = "); scanf("%d",&Num); Num--;
if (Num<0 || Num>14) { puts("Program is completed"); pause; break; }
nv=g[Num].nv;
vg= new graph[nv];
for (i=0;i<nv;i++) vg[i]=dlv(g[Num],i);
for (i=0;i<nv;i++) q[i]=1;
M=1;
for (i=0;i<nv;i++)
{ if (q[i]==0) continue;
q[i]=0;
printf("Orbit %2d : ( %2d ", M++,i+1);
for (j=i+1;j<nv;j++)
if (q[j] && iso(vg[i],vg[j])) { q[j]=0; printf("%2d ", j+1); }
puts(")");
}
Norb1=M-1; Norb2=n_orbit(g[Num]);
printf("Number of the Orbits = %d \n",Norb1);
if (Norb1 != Norb2) printf("Error: Norb1=%d Norb2=%d \n", Norb1,Norb2);
delete[] vg;
}
exit:
}
Пример 14
Тестирование функции o_graph(n), которая позволяет получить граф типа "кольцо" сnвершинами. Очередной граф преобразуется в матрицу смежности с помощью перегруженной операции присваивания видаM=gи матрица смежностиMвыводится на экран путем вызова функцииwrite() классаmatadM.
// Example 014
#include "algraph.cpp"
void main()
{ int n;
graph g; matad M;
for (n=5;n<11;n++) { M = g = o_graph(n);
M.write(); pause;
}
}
Пример 15
В программе выполняется преобразование файла, содержащего набор графов, из r-формата (графы представлены бинарными кодами) вgt-формат (графы представлены таблицами связей). Вначале выполняется проверка правильностиr-файла с помощью функцииverification_r(f), затем собственно преобразование с помощью функцииr_gt(in,out). Последняя возвращает количество записанных в выходной файл графов.
// Example 015
#include "algraph.cpp"
void main()
{ printr("Преобразование файлов вида r->gt \n");
printr("Входной файл: "); puts("015.r");
printr("Выходной файл: "); puts("015.gt");
FILE* in= fopen("015.r","rb");
if (in==0) { printr("Не найден входной файл\n"); pause; exit(0); }
ulong Ng;
verification_r(in);
FILE* out= fopen("015.gt","w");
Ng=r_gt(in,out);
fclose(out); fclose(in);
printr("В выходной файл записано ");
printf("%lu ",Ng); printr("графов в gt-формате\n");
}
Отметим, что такое же преобразование r-файла можно выполнить с помощью утилитыconvert_r_gt. Для этого требуется выполнить такую командную строку:
convert_r_gt 015.r 015.gt
Пример 16
Программа осуществляет проверку правильности r-файла. Имя проверяемого файла указывается в командной строке. Если файл не поврежден, на экран выводится информация о числе вершин и числе ребер семейства графов, а также количество графов, которые записаны в тестируемый файл. Для получения информации о параметрах и количестве графов используется функцияhread(in,nv,nr,Ng,KS), которая считывает эту информацию из заголовкаr-файла. Функцияrewind(in) из модуляsyst.hустанавливает указатель файла в начало и и приводит соответствующий поток в исходное состояние, подготавливая файл для повторного чтения.
По образцу этой программы построена утилита verr.exe, которая входит в состав пакетаAlgraph/C++ и которая осуществляет проверку правильностиr-файла.
// Example 016
#include "algraph.cpp"
void main(int N, char** inf)
{ if (N!=2) { puts("Error: You must specify a name of r-file in command line!)");
pause; exit(0);
}
FILE* in= fopen(inf[1],"rb");
errhalt(in==0,"Error: Cannot open r-file!");
word nv,nr;
ulong Ng,KS;
hread(in,nv,nr,Ng,KS); rewind(in);
printf("Name of r-file: %s \n",inf[1]);
printf("Parameters of r-file: nv=%d nr=%d Ng=%lu \n",nv,nr,Ng);
printf("Verification in progress ... ");
if (verification_r(in)==0) puts("Checked r-file is Correct");
fclose(in);
}
Пример 17
Программа, приведенная ниже, считывает содержимое gt-файла и для каждого из графов определяет параметры сильной регулярностиm0 иm1, значения которых выводятся на экран.
// Example 017
#include "algraph.cpp"
void main()
{ graph g; int m0,m1;
char ngr[80];
FILE* f;
f=fopen("017.gt","r"); errhalt(!f,"Cannot open the file!");
for (;;)
{ fscanf(f,"%s",ngr); if (feof(f)) break;
g<<f; streg(g,m0,m1);
printf("Graph %s m0=%d m1=%d \n",ngr,m0,m1);
}
fclose(f);
}
Пример 18
В этой программе показана работа следующих функций:
- конструкторы копирования и преобразования вида graph(graph),matad(matad),graph(matad),matad(graph);
- k_line(n,k), создает граф вида "прямоугольная сетка",n- число вершин вдоль сетки,k- ширина сетки;
- g.form(), возвращает значение форм-фактора графаg;
- g.nrib(), возвращает число ребер графаg;
- M.form(), возвращает значение форм-фактора графа, представленного матрицей смежностиM;
-M.nrib(), возвращает число ребер графа, представленного матрицей смежностиM;
- g.size(), возвращает размер объектаgклассаgraph(таблица связей) в байтах;
- M.size(), возвращает размер объектаMклассаmatad(матрица смежности) в байтах;
- перегруженные операции присваивания вида graph=graph,matad=matad,graph=matad,matad=graph;
- операции сравнения graph==graph,matad==matad;
- g.write(f), вывод графаg в текстовый файл fили на экран в форматеgt;
- g.read(f), ввод графаgиз текстового файла в форматеgt, функция возвращает значениеform-фактора графаg;
-M.write(f), вывод матрицы смежностиMв текстовый файлfили на экран в форматеmt;
- M.read(f), ввод матрицы смежностиMиз текстового файла в форматеmt, функция возвращает значениеform-фактора соответствующего графа;
- перегруженные операции ввода графа gиз из текстового файла в форматеgtвидаg<<fи вывода графа в текстовый файл форматаgtвидаg>>f;
- операция получения pi-инварианта графаg(упорядоченный вектор степеней вершин), реализованная как операция присваивания с преобразованием видаpin=g;
- операции записи значения pi-инварианта в текстовый файлpin.write(f) и чтенияpi-инварианта из текстового файлаpin.read(f);
- операция сравненияpi-инвариантов видаpin1 ==pin2.
// Example 018
#include "algraph.cpp"
void main()
{ int Sf=0, Sr=0, Err=0;
graph g = k_line(12,4);
Sf+=sqr(g.form()); Sr+=sqr(g.nrib());
matad m(g);
if ((g.form()!=m.form()) || (g.nrib()!=m.nrib()))
{ printr("Ошибка 01\n"); Err=1; }
graph g1(g), g2;
g2=graph(matad(g1));
matad m1(m), m2;
m2=matad(graph(m));
g2=g2; m2=m2;
if (!(g1==g2) || !(m1==m2)) { printr("Ошибка 02\n"); Err=1; }
g1=0; g2=0; m1=0; m2=0;
g1=g; m1=g1; g2=m1;
m1=g; g=m1; m2=g;
if (!(g1==g2) || !(m1==m2)) { printr("Ошибка 02\n"); Err=1; }
m.s[10][0]=1; g=m; // создание дуги
Sf+=sqr(g.form()); Sr+=sqr(g.nrib());
if ((g.form()!=m.form()) || (g.nrib()!=m.nrib()))
{ printr("Ошибка 03\n"); Err=1; }
m.s[5][5]=1; g=m; // создание петли
Sf+=sqr(g.form()); Sr+=sqr(g.nrib());
if ((g.form()!=m.form()) || (g.nrib()!=m.nrib()))
{ printr("Ошибка 04\n"); Err=1; }
m.s[5][6]++; g=m; // создание кратной дуги
Sf+=sqr(g.form()); Sr+=sqr(g.nrib());
if ((g.form()!=m.form()) || (g.nrib()!=m.nrib()))
{ printr("Ошибка 05\n"); Err=1; }
if (Sf!=59 || Sr!=19698 ) { printr("Ошибка 06\n"); Err=1; }
graph g3(25), g4; g4=25;
matad m3(25), m4; m4=25;
if ((g3+g4).nv + m3.nv + m4.nv != 100) {printr("Ошибка 07\n"); Err=1;}
FILE *gt=fopen("test_01.gt","w"),
*mt=fopen("test_01.mt","w");
g.write(gt); m.write(mt);
fclose(gt); fclose(mt);
gt=fopen("test_01.gt","r");
mt=fopen("test_01.mt","r");
graph gg; gg.read(gt); gg.write(); pause;
matad mm; mm.read(mt); mm.write();
fclose(gt); fclose(mt);
if (!(g==gg)) { printr("Ошибка при чтении graph-объекта \n"); Err=1; }
if (!(m==mm)) { printr("Ошибка при чтении matad-объекта \n"); Err=1; }
if (g.size()!=218) { printr("Ошибка 07\n"); Err=1; }
if (m.size()!=200) { printr("Ошибка 08\n"); Err=1; }
gt=fopen("test.gt","w");
g>>gt;
fclose(gt);
gt=fopen("test.gt","r");
gg=0; gg<<gt;
fclose(gt);
if (!(g==gg))
{ printr("Ошибка при выполнении операций чт/зап '<<','>>' \n");
Err=1;
}
printr("\nЗапись pinv-инварианта\n");
pinv p1; p1=gg; p1.write();
gt=fopen("test.gt","w"); p1.write(gt); fclose(gt);
pinv p2;
printr("Чтение pinv-инварианта\n");
gt=fopen("test.gt","r"); p2.read(gt); fclose(gt);
p2.write();
if (!(p1 == p2))
{ printr("Ошибка при выполнении операций с pinv-объектами\n");
Err=1;
}
system("del test.gt"); // удаление временного файла
if (Err==0) printr("\nТест завершен УСПЕШНО\
\nСм. файлы test_01.gt, test_01.mt \n\7\7");
else printr("\nТест НЕ завершен УСПЕШНО\n");
}
Пример 19
Показано использование функций:
- randgraph(n,r), создание случайного графа сnвершинами и сrребрами (можно указывать абсолютное число ребер или относительное реберное заполнение);
- g.write_r(f), записать бинарный код графаgвr-файл (бинарный файл форматаr);
- g.read_r(f), прочитать графgизr-файла.
// Example 019
#include "algraph.cpp"
void main()
{ int r1,r2, q=0; float rx=0.5;
graph g,g1,g2;
printr("\nОперация: randgraph(15,0.5) >> stdout \n");
(g1=randgraph(15,rx)) >> stdout;
FILE* f= fopen("test.r","wb");
r1=g1.write_r(f);
fclose(f);
f= fopen("test.r","rb");
g2=15; r2=g2.read_r(f);
fclose(f);
if ((r1+r2) != 106) { printr("Ошибка 01 \n"); q=1; }
if (!(g1==g2)) { puts("Ошибка 02 \n"); q=1; }
if (q==0) printr("\nТест завершен УСПЕШНО\n");
else printr("\nТест НЕ завершен УСПЕШНО\n");
system("del test.r");
}
Пример 20
Тестируется выполнение следующих функций:
- randgraph(n,r), получить случайный граф с числом вершинnи с числом реберr;
- randgraph(n,rx), получить случайный граф с числом вершинnи с относительным реберным заполнениемrx;
- graph(graph), graph(matad), matad(matad), matad(graph), конструкторы копирования и преобразования класса graph;
- операции сравнения видаgraph==graph;matad==matad;
- операции присваивания для переменных типа graphвидаg1 =g2 и переменных типаmatadвидаM1 =M2;
- операция присваивания с преобразованием вида graph=matad,graph=int,matad=graph,matad=int;
- операция вывода значения переменнойgтипаgraphв файл видаg>>f;
- операция ввода значения переменоой gтипаgraphиз файла видаg<<f;
-print(M), процедура вывода матрицы смежностиMна экран;
-g.read_r(f), чтение значения переменнойgтипаgraphиз бинарногоr-файла;
-g.rgl(), упорядочивание элементов строк таблицы связей графаg.
// Example 020
#include "algraph.cpp"
void main()
{ randomize();
int r1,r2, q=1; float rx=0.5;
graph g,g1,g2;
FILE* f= fopen("test_1.dat","w");
puts("\nOperation: randgraph(15,0.5)>>f>>stdout ");
g1=randgraph(15,rx); g1>>f>>stdout; pause;
fclose(f);
f=fopen("test_1.dat","r");
g2<<f;
if (!(g1==g2)) { puts("Fail: Error 01"); q=0; }
matad M; M=g2; print(M); pause;
g2=0; g2=M;
if (!(g1==g2)) { puts("Fail: Error 02"); q=0; }
graph g3(g2), g4(M);
if (!(g3==g4)) { puts("Fail: Error 03"); q=0; }
matad Ma(M),Mb(g3);
if (!(Ma==Mb)) { puts("Fail: Error 04"); q=0; }
Ma=0; Mb=randgraph(15,50); Ma=Mb;
if (!(Ma==Mb)) { puts("Fail: Error 05"); q=0; }
Ma=10;
g3=8;
g1= o_graph(10); g1.rgl();
g2= 10;
f= fopen("020.r","wb");
g1.write_r(f);
r1=g1.write_r(f);
fclose(f);
f= fopen("020.r","rb");
g2.read_r(f);
r2=g2.read_r(f);
fclose(f);
if (!(g1==g2)) { puts("Fail: Error 08"); q=0; }
if (!(r1==r2)) { puts("Fail: Error 09"); q=0; }
if (q) puts("\nAll Steps of the Test Passed Ok");
else puts("\nTest Failed");
system("del 020.r");
}
Пример 21
В этом примере тестируется правильность работы функций, которые создают графы различных видов:
- complete(n), создается полный граф сnвершинами;
- fatring(n,c), создает граф типа fatring с n вершинами и с заданным параметром с;
- hamming(m,d), создается граф ХэммингаH(n,d) с числом вершинnи параметромd;
- johnson(m,w,dist), получить граф Джонсона с числом вершинnи с параметрамиw,d;
- keller(m),получить граф Келлера с n вершинами;
- o_graph(n), получить граф типа "кольцо" сnвершинами;
- double_o_graph(m), получить граф типа "двойное кольцо" сmсекциями;
- sanchis(n,r,d), получить граф Санчиса с числом вершинnи с параметрамиr,d;
- k_line(n,k),получить граф типа k-line с n секциями шириной k;
-k_ring(n,k),получить граф типа k-ring с n секциями шириной k;
-star(n), получить граф вида "звезда" сnлучами;
- wheel(n), получить граф вида "колесо" сnсекциями.
Кроме того, в программе использована функция nrib(g), которая возвращает число ребер графаg.
// Example 021
#include "algraph.cpp"
void main()
{ int n, r, d, x, q=1; matad M;
puts("Generating of the Complete graph (n=12):");
graph g(complete(12)); r=nrib(g);
printf("r=%d \n",r);
if (!(r==66)) { puts("Fail: Error 01"); q=0; }
puts("Generating of the c-fat rings type graph (n=100, c=3):");
g=fatring(100,3);
r=nrib(g); d=dens(g);
if (!(r==2094 && d==30)) { puts("Fail: Error 02"); q=0; }
printf("r=%d d=%d \n",r,d);
puts("Generating of the Hamming graph (m=6, dist=3):");
g=hamming(6,3); n=g.nv; r=nrib(g); d=dens(g);
if (!(n==64 && r==1344 && d==8)) {puts("Fail: Error 03"); q=0;}
printf("n=%d r=%d d=%d \n",n,r,d);
puts("Generating of the Johnson graph (m=8, w=3, dist=4):");
g=johnson(8,3,4); n=g.nv; r=nrib(g); d=dens(g);
printf("n=%d r=%d d=%d \n",n,r,d);
if (!(n==56 && r==1120 && d==8)) {puts("Fail: Error 04"); q=0;}
puts("Generating of the Keller graph (m=3):");
g=keller(3); n=g.nv; r=nrib(g); d=dens(g);
printf("n=%d r=%d d=%d \n",n,r,d);
if (!(n==64 && r==1088 && d==5)) {puts("Fail: Error 05"); q=0;}
puts("Generating of the O-graph (n=12):");
g=o_graph(12); r=nrib(g);
printf("r=%d \n",r);
if (!(r==12)) { puts("Fail: Error 06"); q=0; }
puts("Generating of the double_o_graph (n=8):");
g=double_o_graph(8); r=nrib(g);
printf("n=%d r=%d \n",g.nv,r);
if (!(r==24)) { puts("Fail: Error 07"); q=0; }
puts("Generating of the Sanchis graph (n=90, r=2003, d=5):");
g=sanchis(90,2003,5); r=nrib(g); d=dens(g);
printf("r=%d d=%d \n",r,d);
if (!(r==2003 && d==5)) { puts("Fail: Error 08"); q=0; }
puts("Generating of the k-line graph (n=10, k=3):");
g=k_line(10,3); r=nrib(g);
printf("r=%d \n",r);
if (!(r==24)) { puts("Fail: Error 09"); q=0; }
puts("Generating of the k-ring graph (n=12, k=3):");
g=k_ring(12,3); r=nrib(g);
printf("r=%d \n",r);
if (!(r==36)) { puts("Fail: Error 10"); q=0; }
puts("Generating of the star graph (n=9):");
g=star(9); r=nrib(g); x=naut(g);
printf("n=%d r=%d Naut=%d \n",g.nv,r,x);
if (!(x==fact(9))) { puts("Fail: Error 11"); q=0; }
puts("Generating of the wheel graph (n=15):");
g=wheel(15); r=nrib(g); x=naut(g);
printf("n=%d r=%d Naut=%d \n",g.nv,r,x);
if (!(x==30)) { puts("Fail: Error 12"); q=0; }
if (q) puts("\nAll Steps of the Test Passed Ok");
else puts("\nTest Failed");
}
Пример 22
В этом примере тестируется работа следующих функций:
- add_v(g), процедура, которая создает дополнительную изолированную вершину в графеg;
- del_v(g,k), процедура, которая удаляет вершину номерkв графеg;
- add_vc(g), процедура, которая создает дополнительную вершину в графе g, причем новая вершина смежна ко всем остальным вершинам графа g;
- del_iv(g), удалить из графаgвсе изолированные вершины;
- add_r(g,i,k), создать ребро или пару встречных дуг с концевыми вершинами {i,k} в графеg;
- del_r(g,i,k), удалить из графаgребро или пару встречных дуг с концевыми вершинамиi,k;
- dist(g,i,j), функция, которая возвращаетрасстояние между вершинами i,k в графе g;
- excenter(g,i), функция, которая возвращает эксцентриситет вершиныiв графеg.
// Example 022
#include "algraph.cpp"
void main()
{ int i,j,n,r, q=1; float rx=0.3;
graph g(randgraph(10,rx));
for (i=0;i<3;i++) add_v(g);
del_iv(g);
add_vc(g); n=g.nv;
del_v(g,n-1);
add_v(g);
graph h(g); r=nrib(g);
for (i=0;i<g.nv-1;i++) add_r(g,g.nv-1,i);
if (!(nrib(g)==r+g.nv-1)) { puts("Fail: Error 01"); q=0; }
for (i=0;i<g.nv-1;i++) del_r(g,g.nv-1,i);
if (!(h==g)) { puts("Fail: Error 02"); q=0; }
n=g.nv;
puts("\n Distance Matrix:\n");
printf(" "); for (i=0;i<n;i++) printf("%3d ",i+1); puts("\n");
for (i=0;i<n;i++)
{ printf("%3d ",i+1);
for (j=0;j<n;j++) printf("%3d ",dist(g,i,j));
puts("");
}
int d, exc=0; i=5;
for (j=0;j<n;j++) { d=dist(g,i,j); if (exc<d) exc=d; }
if (!(exc==excenter(g,i))) { puts("Fail: Error 03"); q=0; }
if (q) puts("\nAll Steps of the Test Passed Ok");
else puts("\nTest Failed");
}
Пример 23
В этом примере проверяется работа следующих функций:
- операция присваивания вида pin=n, выполнение которой приводит к созданиюpi-инварианта безреберного графа с числом вершинn;
- операция сравнения pi-инвариантов видаpin1 ==pin2;
- print(pi), процедура, которая выводит на экран значениеpi-инварианта;
-sigma(graph), функция, которая возвращает значениеsigma-инварианта графаg;
-iso(g1,g2), функция, выполняющая проверку изоморфности графовg1 иg2;
- isisos(g1,g2,p), установить, является ли подстановкаp, отображающая множество вершин графаg1 на множество вершин графаg2, изоморфизмом; -isos(g1,g2,p), функция, которая проверяет изоморфность графовg1 иg2 и, если они изоморфны, находит изоморфизмpграфаg2 на графg1;
- nisos(g1,g2), функция, которая возвращает количество изоморфных подстановок графаg1 на графg2.
// Example 023
#include "algraph.cpp"
void main()
{ randomize();
int q=1; float rx=0.3;
puts("Generating of the Random Graph:");
graph g1(randgraph(10,rx));
int n=g1.nv, r=nrib(g1);
printf("n=%d r=%d \n",n,r);
puts("pinv-invariant:");
pinv pin1; pin1=g1; print(pin1);
graph g2(renum(g1));
pinv pin2; pin2=g2;
if (!(pin1==pin2)) { puts("Fail: Error 01"); q=0; }
ulong s1,s2; s1=sigma(g1); s2=sigma(g2);
printf("\nsigma-invariant = %X \n",s1);
if (!(s1==s2)) { puts("Fail: Error 02"); q=0; }
if (!iso(g1,g2)) { puts("Fail: Error 03"); q=0; }
printf("nisos=%d \n",nisos(g1,g2));
int p[10];
isos(g1,g2,p);
if (!isisos(g1,g2,p)) { puts("Fail: Error 04"); q=0; }
graph g3(k_ring(15,1));
if (!(nisos(g3,g3)==30)) { puts("Fail: Error 05"); q=0; }
graph g4(o_graph(15)); g4.rgl();
if (!(g3==g4)) { puts("Fail: Error 06"); q=0; }
graph g5(line(15));
if (!(nisos(g5,g5)==2)) { puts("Fail: Error 07"); q=0; }
if (q) puts("All Steps of the Test Passed Ok");
else puts("Test Failed");
}
Пример 24
В этом примере тестируются функции:
- radius(g), вычисление радиуса графа;
- diameter(g), вычисление диаметра графа;
- k_ring(n,k), создание графа типаk_ringcпараметрамиn,k;
- o_graph(n), создание графа типа "кольцо" сnвершинами;
- join(g1,g2), создание графа путем выполнения операции соединения графовg1 иg2;
- sigma(g), функция, возвращает значениеsigma-инварианта графаg.
// Example 024
#include "algraph.cpp"
void main()
{ randomize();
int q=1; float rx=0.3;
puts("Testing of the randgraf, pinv and first invariants");
graph g(randgraph(10,rx));
int n=g.nv, r=nrib(g);
printf("n=%d r=%d \n",n,r);
printf("pinv-invariant = ");
pinv pin; pin=g; print(pin); puts("");
int diam,rad;
rad=radius(g); diam=diameter(g);
printf("radius = %d diameter = %d \n",rad,diam);
puts("Testing of the k_ring, o_graph, join, first invariant");
g=k_ring(10,3); g=join(g,o_graph(10));
printf("sigma=%08X \n",sigma(g));
if (!(sigma(g)==0xFF8D6D20)) { puts("Fail: Error 01"); q=0; }
int na=10, nb=15;
graph A(complete(na)), B(complete(nb));
graph C(joinc(A,B));
r= nrib(C);
if (!(r==300)) { puts("Fail: Error 02"); q=0; }
A=na; B=nb;
r= nrib(joinc(A,B));
if (!(r==150)) { puts("Fail: Error 03"); q=0; }
if (q) puts("All Steps of the Test Passed Ok");
else puts("Test Failed");
}
Пример 25
В этом примере тестируются функции:
- операция присваивания видаg=n, в результате которой переменнойgтипаgraphприсваивается значение, которое соответствует безреберному графу сnвершинами;
- операция сравнения вида g==n, которая проверяет, имеет ли переменнаяgтипаgraphзначение, которое соответствует безреберному графу сnвершинами;
- copmplete(n), создание полного графа сnвершинами;
- modmul(g1,g2), функция возвращает модульное произведение графовg1 иg2;
- dens(g), функция, вычисляет плотность графаg;
- randgraph(n,rx), функция, которая возвращает случайный граф с числом вершинn и относительнымреберным заполнением rx.
// Example 025
#include "algraph.cpp"
void main()
{ randomize();
int na=5, nb=8;
graph A(complete(na)), B(complete(nb));
graph C(modmul(A,B)); printf("ver=%d \n",ver(C));
printf("dens(C) = %d \n",dens(C));
graph g(randgraph(15,float(0.5)));
graph h=modmul(g,g);
printf("dens(g*g) = %d \n",dens(h));
h= randgraph(15,float(0.5));
printf("dens(g*h) = %d \n",dens(modmul(g,h)));
g=100; if (g==100) puts("g==100");
}
Пример 26
В этом примере тестируются функции:
- graph::.size(),
- matad::size().
Кроме того проверяется освобождение памяти при выполнении операций вида graf = 0, matad = 0
// Example 026
#include "algraph.cpp"
void main()
{ randomize();
int i, nv;
float rx;
graph g; matad M;
printf("nv,rx = "); scanf("%d %f",&nv,&rx);
for (i=1;i<=5;i++)
{ printf("test %d \n",i);
g=randgraph(nv,rx); M=g;
printf("nv= %5d r= %7d graf size= %8d matad size= %8d \n",
g.nv, nrib(g), g.size(), M.size());
M=0; g=0;
printf("nv= %5d r= %7d graf size= %8d matad size= %8d \n",
g.nv, nrib(g), g.size(), M.size());
}
}
Пример 27
В этом примере показано действие форм-фактора, фунцкия g.form(). Кроме того тестируется работа функций ввода/выводаg.write(f),g.read(f),M.write(f),M.read(f), гдеg,M- объекты типаgraphиmatadсоответственно.
// Example 027
#include "algraph.cpp"
void form_print(int frm)
{ char *s1 = "есть\n",
*s2 = "нет\n";
printr("Ориентир. ребра - ");
if (frm & 0x1) printr(s1); else printr(s2);
printr("Наличие петель - ");
if (frm & 0x2) printr(s1); else printr(s2);
printr("Кратные ребра/петли - ");
if (frm & 0x4) printr(s1); else printr(s2);
}
void main()
{ graph g= k_line(12,4);
printr("\nСоздан граф типа k_line(12,4)\n");
form_print(g.form());
printr("Число ребер: "); printf("g.nrib() = %d \n",g.nrib());
printr("\nСоздана дуга (11,1)\n");
matad mx(g); mx.s[10][0]=1; g=mx;
form_print(g.form());
printr("Число ребер: "); printf("g.nrib() = %d \n",g.nrib());
printr("\nСоздана петля (6,6)\n");
mx.s[5][5]=1; g=mx;
form_print(g.form());
printr("Число ребер: "); printf("g.nrib() = %d \n",g.nrib());
printr("\nСоздана кратная дуга (6,7)\n");
mx.s[5][6]++; g=mx;
form_print(g.form());
printr("Число ребер: "); printf("g.nrib() = %d \n",g.nrib());
printr("\nФункции write/read для graph/matad: ");
FILE *gt=fopen("t_wr.gt","w"),
*mt=fopen("t_wr.mt","w");
g.write(gt);
matad m(g);
m.write(mt);
fclose(gt); fclose(mt);
gt=fopen("t_wr.gt","r");
mt=fopen("t_wr.mt","r");
graph gg; matad mm;
gg.read(gt);
mm.read(mt);
fclose(gt); fclose(mt);
int q=0;
if (!(g==gg)) { printr("Ошибка чтения graph-объекта \n"); q=1; }
if (!(m==mm)) { printr("Ошибка чтения matad-объекта \n"); q=1; }
if (q==0) printr(" OK \n");
}
Пример 28
Программа генерирует полный набор неизоморфных графов с 10 вершинами и с 15 ребрами. Входной файл должен представлять собой r-файл, содержащий полный набор 10-вершинных графов с 14 ребрами. В этом примере используются функции из модуляbicod.h. Об используемом методе получения полных наборов графов см.[].
// Example 028
#include "algraph.cpp"
const word Nv = 10; // Число вершин
#include "bicod.h"
const word sh = 16; // константа сдвига
const ulong nbmax = 1L<<sh; // Размеры большой таблицы
const word mbmax = 20; // Длина строки большой таблицы
const ulong Cnb = nbmax-1; // маска для выделения ном. строки б.табл.
word ns = 0; // текущее число строк малой таблицы
bicod Br[rmax]; // буфер для генерации семейства
ulong Sr[rmax]; // текущего бикода
byte q[rmax]; // (малая таблица)
bicod B[nbmax][mbmax]; // таблица
ulong S[nbmax][mbmax]; // большая
void gener(bicod B) // генерация семейства
{ int r; // для очередного бикода
unsigned short c,t=0; // (формирование малой таблицы)
bicod A;
ns=0;
for (int J=0;J<rmax;J++)
{ if (t==0) t=0x8000;
r=J/16; c=B.c[r];
if ((c|t)>c) { A=B; A.c[r]|=t;
Br[ns]=A;
Sr[ns]=sigma(grafbic(A));
q[ns++]=1; }
t>>=1;
}
}
main()
{ ulong i,j,k;
word nv,nr,c;
int p;
ulong ss, // sigma-инвариант графа
N, // число сгенерированных графов
max, // максимальная длина строки большой таблицы
ii,n,na,ks,z=0;
int nb[nbmax]; // nb[i] - заполнение i-той строки большой табл.
char inf[40],outf[40];
puts("Program of Graph Generating");
printf("Nv = %d Lmax=%d \n",Nv,mbmax);
printf("Input File = "); scanf("%s",inf);
printf("Output File = "); scanf("%s",outf);
FILE* in= fopen(inf,"rb"); errhalt(in==0,"Cannot to open Input File!");
printf("Large Tables Size = %lu \n",sizeof(S)+sizeof(B));
bicod A;
FILE* out= fopen(outf,"wb");
n=0; N=0; for (i=0;i<nbmax;i++) nb[i]=0;
hread(in,nv,nr,na,ks);
errhalt(nv!=Nv,"The value nv inside of infile don't match const Nv !");
printf("nv=%u nr=%u na=%lu \n",nv,nr,na);
nr++; ks=0;
hwrite(out,nv,nr,z,z);
runtimer();
for (ii=0;ii<na;ii++)
{ if (n%1000==0) printf("%8lu %8lu %8lu \xD",n,na-n,N);
A<<in; n++;
gener(A);
for (j=0;j<ns-1;j++) // редукция
{ if (q[j]==0) continue; // малой
for (k=j+1;k<ns;k++) // таблицы
{ if (q[k]==0) continue; //
if (Sr[j]==Sr[k] && iso(grafbic(Br[j]),grafbic(Br[k]))) q[k]=0;
}
}
for (j=0;j<ns;j++)
{ if (q[j]==0) continue;
ss=Sr[j]; ss>>=1; i= ss&Cnb;
for (k=0;k<nb[i];k++)
if (Sr[j]==S[i][k] && iso(grafbic(Br[j]),grafbic(B[i][k]))) break;
if (k==nb[i])
{ S[i][nb[i]]=Sr[j]; // занесение данных графа
B[i][nb[i]]=Br[j]; // в большую таблицу
nb[i]++; N++; //
errhalt(nb[i]==mbmax,"Large tables are too small!");
for (k=0;k<Nw;k++) { c=Br[j].c[k]; // запись бикода и
fwrite(&c,2,1,out); // формирование ks+=c; // контр.суммы
}
}
}
}
printf("\nTime = %6.2f sec\n",timer());
fseek(out,4,0); fwrite(&N,4,1,out); fwrite(&ks,4,1,out);
fclose(in); fclose(out);
p=verr(outf); if (p) printf("Error %u in out file %s \n",p,outf);
puts("");
printf("Number of scanned graphs = %lu \n",na);
printf("Number of generated graphs = %lu \n",N);
max=nb[0]; for (i=1;i<nbmax;i++) if (max<nb[i]) max=nb[i];
printf("Lmax = %lu \n",max);
puts(" ==================== That's All ====================");
}