В ходе работы над дипломом мне пришлось столкнуться с необходимостью генерации дерева. Так как я точно не знаю, какое именно дерево будет описывать мою задачу (деревом представляется булева функция общего вида), я решил, что будет логично прогнать алгоритмы на достаточно большом количестве случайных деревьев. Итак, генерация случайного дерева.
В качестве структуры данных, для хранения была выбрана матрица смежности. Будем считать, что дерево — ориентированный граф с полустепенью захода у каждой вершины равной 1 (кроме корня: у него 0). Также нам нужно сделать так, чтобы у нас был всего один корень (то есть нам нужно именно дерево, а не лес).
Матрица смежности — это булева матрица, в (i, j) вершине которого содержится информация о том, присутствует ли в графе ребро изходящее из i и входящее в j. Из этого легко получить условия, которые мы должны наложить на матрицу, чтобы она описывала именно дерево.
Обратите внимание, что четвертая и пятая строки в матрице содержат только нули. На графе они стали листьями. Столбец содержащий одни нули (1-ый) является корнем.
В качестве структуры данных, для хранения была выбрана матрица смежности. Будем считать, что дерево — ориентированный граф с полустепенью захода у каждой вершины равной 1 (кроме корня: у него 0). Также нам нужно сделать так, чтобы у нас был всего один корень (то есть нам нужно именно дерево, а не лес).
Матрица смежности — это булева матрица, в (i, j) вершине которого содержится информация о том, присутствует ли в графе ребро изходящее из i и входящее в j. Из этого легко получить условия, которые мы должны наложить на матрицу, чтобы она описывала именно дерево.
- В столбце i (i > 0) должна стоять одна и только одна единица на месте j (j < i). Таким образом мы обеспечим полустепень захода равную 1 для всех вершин графа, кроме корня. Будем, для удобства считать, что корнем является нулевая вершина.
- Ниже главной диагонали (и на ней) должны стоять нули, это обеспечит ориентированность дерева, и тот факт, что вершины с большим номером будут являтся детьми, только вершинам с меньшим номером.
#include <iostream> #include <vector> #include <cstdlib> #include <ctime> int main(int argc, char** argv) { using namespace std; srand(time(NULL)); vector<vector<int> > matrix; #define size 1000 matrix.resize(size); for (int i = 0; i < size; i++) { matrix[i].resize(size); for (int j = 0; j < size; j++) { matrix[i][j] = 0; } } for (int i = size - 1; i > 0; i--) { /** * (rand() % i) - случайное число в множестве [0, i) * i-тый столбец */ matrix[rand() % i][i] = 1; } for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { if (matrix[i][j] == 1) { cout << i << " -> " << j << ";" << endl; } } } }И на закуску небольшой пример:
0 1 0 0 0 0 0 1 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0Дерево, представленное этой матрицей будет выглядеть так:
Обратите внимание, что четвертая и пятая строки в матрице содержат только нули. На графе они стали листьями. Столбец содержащий одни нули (1-ый) является корнем.