Как определить, если подключены два узла?

голоса
13

Я обеспокоен тем, что это может работать на NP-полной задачи. Я надеюсь, что кто-то может дать мне ответ, как того, является ли он или нет. И я ищу больше ответа, чем просто да или нет. Я хотел бы знать, почему. Если вы можете сказать: «Это в основном эта проблема„х“, который является / не является NP-полной. (Википедия ссылка)»

(Нет, это не домашнее задание)

Есть ли способ, чтобы определить, если две точки соединены на произвольном неориентированный граф. например, следующее

Well
  |
  |
  A
  |
  +--B--+--C--+--D--+
  |     |     |     |
  |     |     |     |
  E     F     G     H
  |     |     |     |
  |     |     |     |
  +--J--+--K--+--L--+
                    |
                    |
                    M
                    |
                    |
                  House

Точки А, хотя М (не «я») не являются контрольные точки (например, клапан в трубопроводе природного газа), который может быть открытым или закрытым. В «+» s являются узлами (например, труба Т-х), и я думаю, ну и дом также узлы, а также.

Я хотел бы знать, если я закрою произвольную контрольную точку (например, C), являются ли все еще подключен Ну и дом (другие контрольные точки также могут быть закрыты). Например, если B, K и D закрыты, у нас есть еще путь через AEJFCGLM, и закрытие C отключит Ну и дом. Конечно; если только D был закрыт, закрывалась C не отсоединяет дом.

Другой способ сдачи этого, представляет собой С мост / отрезанный край / перешеек?

Я мог бы относиться к каждой контрольной точке в качестве веса на графике (либо 0 для открытого или 1 для закрытого); а затем найти кратчайший путь между Ну и дом (результат> = 1 указывает на то, что они были отключены. Там это различные способы можно закоротить алгоритм нахождения кратчайшего пути тоже (например, выбросить путь, когда он достигает 1, остановка поиск после того, у нас есть любой путь, который соединяет Ну и дом, и т.д.). и, конечно, я могу также поместить в какой-то искусственный предел на сколько прыжков, чтобы проверить, прежде чем давать.

Кто-то должен быть классифицирован такого рода проблемы раньше, я просто отсутствует имя.

Задан 09/12/2008 в 22:41
источник пользователем
На других языках...                            


11 ответов

голоса
2

не NP-полной, решается с помощью хорошо известного решения - Алгоритм Дейкстры

Ответил 09/12/2008 в 22:43
источник пользователем

голоса
6

См http://en.wikipedia.org/wiki/Dijkstra%27s_algorithm , ваша одна остановка магазин для всех проблем , связанных с граф. Я считаю , что ваша проблема в том , решаемой в квадратичное время.

Ответил 09/12/2008 в 22:45
источник пользователем

голоса
2

Мне кажется , что вы на решение, но это возможно , я неправильно понял проблему. Если вы делаете , как вы говорите, и дать замкнутые кромки 1 , как вес, вы можете просто применить алгоритм Дейкстры, http://en.wikipedia.org/wiki/Dijkstra%27s_algorithm . Это должно решить вашу проблему в O (E * LG (V))

Ответил 09/12/2008 в 22:49
источник пользователем

голоса
3

Задача нахождения кратчайшего пути не NP-полной. Это называется задача о кратчайшем пути (достаточно первоначально) и существуют алгоритмы для решения многих различных вариаций этого.

Задача определения, если подключены два узла не является NP-полной либо. Вы можете использовать глубину первый поиск, начиная с любым узлом, чтобы определить, если он подключен к другому узлу.

Ответил 09/12/2008 в 22:51
источник пользователем

голоса
31

Ваше описание, кажется, указывает, что вы просто заинтересованы в том подключены два узла, а не нахождение кратчайшего пути.

Обнаружение, если подключены два узла относительно легко:

Create two sets of nodes:  toDoSet and doneSet
Add the source node to the toDoSet 
while (toDoSet is not empty) {
  Remove the first element from toDoList
  Add it to doneList
  foreach (node reachable from the removed node) {
    if (the node equals the destination node) {
       return success
    }
    if (the node is not in doneSet) {
       add it to toDoSet 
    }
  }
}

return failure.

Если вы используете хэш-таблицу или что-то подобное для toDoSet и doneSet, я считаю, что это линейный алгоритм.

Обратите внимание, что этот алгоритм в основном метка часть сбора мусора отметь и выкинь.

Ответил 09/12/2008 в 22:52
источник пользователем

голоса
5

Вам не нужен алгоритм Дейкстров для этой проблемы, так как она использует вороха, который не нужен, и вводит фактор журнала (N) к вашей сложности. Это только первый поиск вширь - не включает закрытые края, как края.

Ответил 09/12/2008 в 23:08
источник пользователем

голоса
2

Если предположить, что у вас есть матрица смежности:

bool[,] adj = new bool[n, n];

Там, где BOOL [I, J] = верно, если существует открытый путь между I и J и BOOL [I, I] = ложь.

public bool pathExists(int[,] adj, int start, int end)
{
  List<int> visited = new List<int>();
  List<int> inprocess = new List<int>();
  inprocess.Add(start);

  while(inprocess.Count > 0)
  {
    int cur = inprocess[0];
    inprocess.RemoveAt(0);
    if(cur == end)
      return true;
    if(visited.Contains(cur))
      continue;
    visited.Add(cur);
    for(int i = 0; i < adj.Length; i++)
      if(adj[cur, i] && !visited.Contains(i) && !inprocess.Contains(i))
        inprocess.Add(i);
  }
  return false;
}

Вот рекурсивный вариант алгоритма выше (написанный на Ruby):

def connected? from, to, edges
  return true if from == to
  return true if edges.include?([from, to])
  return true if edges.include?([to, from])

  adjacent = edges.find_all { |e| e.include? from }
                  .flatten
                  .reject { |e| e == from }

  return adjacent.map do |a|
    connected? a, to, edges.reject { |e| e.include? from }
  end.any?
end
Ответил 09/12/2008 в 23:23
источник пользователем

голоса
0

Дейкстры является излишеством !! Просто используйте ширину первый поиск от A для поиска узла, который вы хотите достичь. Если вы не можете найти его, это не связано. Сложность O (нм) для каждого поиска, который является менее Дейкстрой.

Несколько связанных это / мин-макс вырезать проблема потока. Посмотрите на него, он может иметь отношение к вашей проблеме.

Ответил 12/12/2008 в 15:11
источник пользователем

голоса
0

Если все, что вам нужно, чтобы определить, является ли 2 узла соединены вы можете использовать наборы вместо этого, что быстрее, чем алгоритмы на графах.

  1. Разделить весь граф на кромки. Добавьте каждое ребро к набору.
  2. На следующей итерации, рисовать ребра между 2 внешними узлами краев вы сделали на шаге 2. Это означает, что добавление новых узлов (с их соответствующими множествами) на множество оригинального край был. (В основном набор сращивание)
  3. Повторите 2 до 2 узлов, которые вы ищете в том же наборе. Вам также необходимо сделать проверку после шага 1 (только в случае 2 узлов примыкают).

На первом ваши узлы будут каждый в своем наборе,

o   o1   o   o   o   o   o   o2
 \ /     \ /     \ /     \ /
 o o     o o     o o     o o
   \     /         \     /
   o o o o         o o o o 
      \               /
       o o1 o o o o o o2

Поскольку алгоритм прогрессирует и объединяет наборы, относительно половины входного сигнала.

В приведенном выше примере, я искал, чтобы видеть, был ли путь между o1 и o2. Я нашел этот путь только в конце после слияния всех краев. Некоторые графики могут иметь отдельные компоненты (отключены), который предполагает, что вы не будете в состоянии иметь один набор в конце. В таком случае вы можете использовать этот алгоритм для проверки связности и даже подсчитать количество компонентов в графе. Количество компонентов является число наборов вы можете получить, когда алгоритм завершается.

Возможный график (для приведенного выше дерева):

o-o1-o-o-o2
  |    |
  o    o
       |
       o
Ответил 17/12/2011 в 04:14
источник пользователем

голоса
-1

Любой граф алгоритм кратчайшего пути будет излишеством , если все , что вам нужно , это найти , если узел подключен к другому. Хорошая библиотека Java , которая выполняет это JGraphT . Это использование довольно просто, вот пример графа Integer:

public void loadGraph() {
    // first we create a new undirected graph of Integers
    UndirectedGraph<Integer, DefaultEdge> graph = new SimpleGraph<>(DefaultEdge.class);

    // then we add some nodes
    graph.addVertex(1);
    graph.addVertex(2);
    graph.addVertex(3);
    graph.addVertex(4);
    graph.addVertex(5);
    graph.addVertex(6);
    graph.addVertex(7);
    graph.addVertex(8);
    graph.addVertex(9);
    graph.addVertex(10);
    graph.addVertex(11);
    graph.addVertex(12);
    graph.addVertex(13);
    graph.addVertex(14);
    graph.addVertex(15);
    graph.addVertex(16);

    // then we connect the nodes
    graph.addEdge(1, 2);
    graph.addEdge(2, 3);
    graph.addEdge(3, 4);
    graph.addEdge(3, 5);
    graph.addEdge(5, 6);
    graph.addEdge(6, 7);
    graph.addEdge(7, 8);
    graph.addEdge(8, 9);
    graph.addEdge(9, 10);
    graph.addEdge(10, 11);
    graph.addEdge(11, 12);
    graph.addEdge(13, 14);
    graph.addEdge(14, 15);
    graph.addEdge(15, 16);

    // finally we use ConnectivityInspector to check nodes connectivity
    ConnectivityInspector<Integer, DefaultEdge> inspector = new ConnectivityInspector<>(graph);

    debug(inspector, 1, 2);
    debug(inspector, 1, 4);
    debug(inspector, 1, 3);
    debug(inspector, 1, 12);
    debug(inspector, 16, 5);
}

private void debug(ConnectivityInspector<Integer, DefaultEdge> inspector, Integer n1, Integer n2) {
    System.out.println(String.format("are [%s] and [%s] connected? [%s]", n1, n2, inspector.pathExists(n1, n2)));
}

Это Lib также предлагает все кратчайшие пути алгоритмы, а также.

Ответил 14/11/2016 в 06:34
источник пользователем

голоса
0

Я вижу, у вас есть свой ответ, что это определенно не NP-полные и это очень старый вопрос, как хорошо.

Тем не менее, я просто предлагаю другой подход , чтобы посмотреть на эту проблему. Вы можете использовать непересекающиеся наборы для этого. В большинстве случаев для данного сценария, подход приведет к лучшему времени , чем делать график обход (Это включает в себя постоянное время для большого куска тестов). Тем не менее, построение графика может занять хорошее количество времени, если объединение по рангу или пути сжатия используется.

Вы можете прочитать о структуре данных здесь .

Ответил 03/09/2018 в 13:36
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more