Если метки уникальны, для графа размером N
имеется O(N^2)
ребер, при условии, что между каждой парой вершин нет самокругов или нескольких ребер. Давайте использовать E
для количества ребер.
Если вы хэшируете заданные ребра в родительском графике, вы можете пройти через ребра подграфа, проверяя, есть ли каждое из них в хеш-таблице (и в правильном количестве, если это необходимо). Вы делаете это один раз для каждого края, поэтому O(E)
.
Давайте назовем граф G
(с N
вершинами) и возможный подграф G_1
(с M
вершинами), и вы хотите найти G_1 is in G
.
Поскольку метки не уникальны, с помощью динамического программирования вы можете вместо этого построить подзадачи как таковые - вместо наличия O(2^N)
подзадач, по одной на каждый подграф, у вас есть O(M 2^N)
подзадач - по одной для каждой вершины в G_1
(с M
вершинами) с каждым из возможных подграфов.
G_1 is in G = isSubgraph( 0, empty bitmask)
и состояния устанавливаются так:
isSubgraph( index, bitmask ) =
for all vertex in G
if G[vertex] is not used (check bitmask)
and G[vertex]'s label is equal to G_1[index]'s label
and isSubgraph( index + 1, (add vertex to bitmask) )
return true
return false
с базовым регистром index = M
, и вы можете проверить равенство ребер, учитывая битовую маску (и неявное отображение меток). В качестве альтернативы вы также можете выполнить проверку в операторе if - просто проверьте, что с учетом текущего index
текущий подграф G_1[0..index]
равен G[bitmask]
(с тем же неявным отображением метки) перед повторением.
Для N = 20
это должно быть достаточно быстро.
(добавьте вашу заметку или вы можете переписать ее, используя нижнюю часть DP).