Вопрос

У меня есть графический генеракодицетагCode и список списков G=(V+E), где каждый сублист - подмножество Node.Я хочу выяснить узлы каждого сублиста, которые не достигаются от других узлов этого сублиста и добавляют кромки между этими узлами.Предположим, генеракодицетагкод= [[1,2,3,4,5,7,8], [9,10], ....] и в сублиста= [1,2,3,4,5,7,8], {1,7,3,8}, достижимый друг от друга и {2,4,5}, достижимых друг от друга, поэтому край необходимо добавить между 1/7/3/8 и 2/4/5.Я использовал следующее:

for each sublist in Node
 SG=node_induced_subgraph(sublist) of G
 C=connected_components(SG) 
 for each component c_i in C
  add edge between c_i and c_{i+1}
 end
end
.

Сложность Node_induced_subgraph () is o (v + e) Сложность подключенных_Components () is o (m + n) # m нет.узлов и n нет.краев в подмахе

Так как уменьшить общую сложность?

Это было полезно?

Решение

Я собираюсь решить ваш вопрос в двух частях. Во-первых, как обеспечить доступность между узлами в одном «подсублении» с добавлением минимального количества ребер (если вы можете добавить столько ребра, поскольку вы хотите, чтобы вы могли пройти список и подключить один элемент к двум двум соседним элементам - стоимость= «Математический контейнер»> $ o (n) $ операции присоединения к краю, что теоретически самый быстрый метод ...). Если мы хотим добавить как можно меньше ребер, мы только хотят подключить «подключенные компоненты». Я полагаю, что ваш график $ g $ хранится в виде списка смежности.

//reused arrays
visited := bool array of size |V| initialized to false
active  := bool array of size |V| initialized to false
//simple dfs
def dfs(node):
  if visited[node] or not active[node]: return
  visited[node] = true
  for child in neighbors(node):
    dfs(child)
//algo
def connect_node_list(list):
  for node in list: active[node] = true
  last := null
  for node in list:
    if not visited[node]: 
      dfs(node)
      if last != null: add_edge(last,node)
      last = node
  for node in list: 
    active[node]  = false
    visited[node] = false
.

Теперь это Algo имеет время выполнения $ O (n + | E |) $ где $ n $ Это длина генеракодицетагкода. Что ж, честно говоря, это так же, как и ваш Algo, который я просто хочу подчеркнуть, что использование Bool массивов очень желательно в целом; Также я не знаю, как работает ваш «неисправный субграф» - но вы должны избегать создания нового графа.

Теперь идея, которая может быть новой: Вы можете уменьшить количество сублистов, подключив те, которые имеют перекрывающийся элемент. (Конечно, это полезно только в том случае, если они не обязательно отличаются.) Вы можете использовать use-one-struction для этого:

uf := union find structure with |V| elements
for list in sublists:
  first = list[0]
  for node in list:
    uf.unify(first, node)
index := array of length |V|
counter := 0
for element in uf:
  index[element]  = -1
  if uf.parent(element) = element and uf.size(element) > 1:
      index[element] = counter
      counter++
new_sublists = list of <counter> many lists
for element in uf:
  set = uf.find(element)
  if index[set] != -1:
    new_sublists[index[set]].add(element)
.

Теперь'new_subliest содержит только необходимое количество сублистов (также все сублисты размера 1 удалены). Процедура требует $ O (MAX (| V |, N \ CDOT \ alpha (| v |))) $ где $ N=sum_i \ text {| сублисты [i] |} $ . $ \ alpha (| v |) $ в основном можно рассматривать как постоянную, но вы можете прочитать на https Структура usion-find-структура . Если вы работаете со многими перекрывающимися списками узла, это ALGO должно быть выполнено первым.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с cs.stackexchange
scroll top