Существует различных моделей для генерации случайных графов с определенными статистическими свойствами. В комментариях вы сказали, что распределение на самом деле не имеет значения для вашего варианта использования, поэтому простой моделью для использования является та, которая включает каждое потенциальное ребро с некоторой фиксированной вероятностью, независимо от того, включены ли другие ребра. Это распределение обычно называется G(n, p)
, где n
- количество узлов, а p
- вероятность включения ребра.
Алгоритм генерации графа из G(n, p)
прост:
- Инициализация графа с
n
узлами и без ребер. - Для каждой (неупорядоченной / упорядоченной) пары узлов
u
, v
: - Генерация случайного действительного числа в диапазоне [0, 1].
- Если это число меньше
p
, добавьте ребро u-v
к графику.
Выбор между неупорядоченными парами и упорядоченными парами зависит от того, требуется ли вам неориентированный или ориентированный граф соответственно.
Поскольку требуется список смежности, на этапе инициализации будет создан список. содержит n
пустых списков, и шаг «Добавить ребро» добавит v
к u
(и u
к v
списку, если график должен быть ненаправленным).
Вот пример реализации в Python:
from random import random
from itertools import product, combinations
def random_graph(n, p, *, directed=False):
nodes = range(n)
adj_list = [[] for i in nodes]
possible_edges = product(nodes, repeat=2) if directed else combinations(nodes, 2)
for u, v in possible_edges:
if random() < p:
adj_list[u].append(v)
if not directed:
adj_list[v].append(u)
return adj_list
Примеры:
>>> random_graph(4, 0.5)
[[1, 2, 3],
[0, 3],
[0],
[0, 1]]
>>> random_graph(5, 0.25, directed=True)
[[0, 2, 4],
[1, 4],
[0, 1, 2, 3],
[1],
[1, 2]]