Jak ustalić, czy dwa węzły są połączone?

głosy
13

Martwię się, że może to być praca na problem NP-zupełny. Mam nadzieję, że ktoś może mi dać odpowiedź, czy jest, czy nie. I szukam więcej niż tylko odpowiedzi tak lub nie. Chciałbym wiedzieć, dlaczego. Jeśli można powiedzieć: „To jest w zasadzie ten problem«x», który jest / nie jest NP-zupełny. (Link do Wikipedii)”

(Nie to nie jest praca domowa)

Istnieje sposób, aby określić, czy dwa punkty są połączone w dowolnej nieukierunkowanych wykresie. na przykład, następujące

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

Punkty A chociaż M (nie „I”) są punkty kontrolne (jak zawór w przewodzie gazowym), które mogą być otwarte lub zamknięte. Te „+” s są węzły (takie jak rury T), i myślę, Studnia i domu są także węzły, jak również.

Chciałabym wiedzieć, czy mogę zamknąć dowolny punkt kontrolny (np c) czy No i są jeszcze podłączone Dom (inne punkty kontrolne mogą być również zamknięte). Na przykład, jeśli B, K i D są zamknięte, wciąż mamy ścieżkę przez AEJFCGLM i zamykanie C rozłączy dobrze i domu. Oczywiście; jeśli tylko D został zamknięty, zamykając tylko C nie odłącza domu.

Innym sposobem realizacji tej, to C pomost / odcinanie krawędzi / przesmyk?

Mogę traktować każdy punkt kontrolny jako ciężar na wykresie (wartość 0 lub 1 w otwartym na zamknięte); a następnie znaleźć najkrótszą ścieżkę między dobrze i Domu (wynik> = 1 wskazuje, że zostały one odłączone. Istnieje wiele sposobów mogę zwarcie algorytm znajdowania najkrótszej ścieżki zbyt (np wyrzucić ścieżkę po osiągnięciu 1, stop poszukiwań raz mamy jakieś ścieżki, która łączy dobrze i domu, itp.) i oczywiście, mogę również umieścić w jakiejś sztucznej limitu na ile chmielu sprawdzić przed poddaniem się.

Ktoś musiał przed sklasyfikowany tego rodzaju problemu, po prostu brakuje nazwy.

Utwórz 09/12/2008 o 22:41
źródło użytkownik
W innych językach...                            


11 odpowiedzi

głosy
2

Nie NP-zupełny, rozwiązano za pomocą znanego rozwiązania - algorytm Dijkstry

Odpowiedział 09/12/2008 o 22:43
źródło użytkownik

głosy
6

Zobacz http://en.wikipedia.org/wiki/Dijkstra%27s_algorithm , swoją jednego okienka dla wszystkich problemów związanych z wykresu. Wierzę, że problem jest w rzeczywistości nierozwiązywalnym w kwadratowego czasu.

Odpowiedział 09/12/2008 o 22:45
źródło użytkownik

głosy
2

Dla mnie wydaje się, że jesteś do rozwiązania, ale jest możliwe, że źle problemu. Jeśli tak jak mówisz, i dać zamkniętym krawędzie 1 jako masy, można po prostu zastosować Algorytm Dijkstry, http://en.wikipedia.org/wiki/Dijkstra%27s_algorithm . To powinno rozwiązać problem w czasie O (E * lg (V))

Odpowiedział 09/12/2008 o 22:49
źródło użytkownik

głosy
3

Problem znalezienia najkrótszej ścieżki nie jest NP-zupełny. To się nazywa najkrótsza droga problem (pierwotnie tyle) i istnieją algorytmy rozwiązujące wiele różnych odmian tego.

Problem określenia, czy dwa węzły są połączone jest NP-zupełny albo. Można użyć przeszukiwanie wgłąb zaczynając od obu węzła celu ustalenia, czy jest on podłączony do innego węzła.

Odpowiedział 09/12/2008 o 22:51
źródło użytkownik

głosy
31

Twój opis wskazuje na to, że jesteś po prostu zainteresowany czy dwa węzły są połączone, nie znalezienie najkrótszej drogi.

Znalezienie jeśli dwa węzły są połączone jest stosunkowo proste:

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.

W przypadku korzystania z tabeli mieszania lub coś podobnego do toDoSet i doneSet, wierzę, że jest to algorytm liniowy.

Zauważ, że ten algorytm jest w zasadzie część znak mark-and-sweep śmieci kolekcji.

Odpowiedział 09/12/2008 o 22:52
źródło użytkownik

głosy
5

Nie trzeba Algorytm Dijkstry dla tego problemu, ponieważ używa sterty, które nie są potrzebne i wprowadza czynnik log (N) do swojej złożoności. To jest po prostu przeszukiwanie wszerz - nie zawierają zamknięte krawędzie jak krawędzie.

Odpowiedział 09/12/2008 o 23:08
źródło użytkownik

głosy
2

Zakładając, że masz macierz sąsiedztwa:

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

Gdzie bool [i, j] = true, jeśli istnieje otwarta droga między I i J oraz bool [i, j] = false.

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;
}

Oto rekurencyjny wersja algorytmu powyżej (napisany w 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
Odpowiedział 09/12/2008 o 23:23
źródło użytkownik

głosy
0

Dijkstra jest przesada !! Wystarczy użyć przeszukiwanie wszerz od A do wyszukiwania dla węzła, który chcesz osiągnąć. Jeśli nie możesz go znaleźć, to nie jest podłączony. Złożoność O (nm) dla każdej wyszukiwania, który jest mniejszy niż Dijkstra.

Nieco pokrewnych jest maksymalna przepływu / min cięcia problemu. To sprawdzić, może to mieć znaczenie dla Twojego problemu.

Odpowiedział 12/12/2008 o 15:11
źródło użytkownik

głosy
0

Jeśli wszystko, co potrzebne jest, aby ustalić, czy 2 węzły są połączone można zamiast używać zestawów, który jest szybszy niż algorytmów wykresu.

  1. Podzielić cały wykres na krawędziach. Dodaj każdej krawędzi do zestawu.
  2. Na następnej iteracji zwrócić krawędzi między 2 zewnętrzne węzły krawędzi dokonane w etapie 2. Oznacza to dodawanie nowych węzłów (z odpowiadającymi im zestawy) do nasady przy krawędź pochodzi. (Zasadniczo ustawione łączenie)
  3. Powtórz 2 aż do 2 węzłów, których szukasz są w tym samym zestawie. Potrzebny będzie również zrobić test po kroku 1 (tylko w przypadku 2 węzły sąsiadują).

Początkowo węzły będzie każdy w swoim zestawie,

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

Gdy algorytm rozwija się i łączy się zestawy, względnie połówki wejścia.

W przykładzie powyżej szukałem, aby zobaczyć, czy istnieje ścieżka pomiędzy O1 i O2. Znalazłem tę drogę tylko na końcu po scaleniu wszystkie krawędzie. Niektóre wykresy mogą mieć oddzielne elementy (odłączony), co oznacza, że ​​nie będą mogli mieć jeden zestaw na końcu. W takim przypadku można użyć tego algorytmu do testowania więzi, a nawet policzyć liczbę składników w postaci wykresu. Ilość składników jest liczba zestawów jesteś w stanie uzyskać, gdy algorytm kończy.

Możliwe wykres (na drzewie powyżej):

o-o1-o-o-o2
  |    |
  o    o
       |
       o
Odpowiedział 17/12/2011 o 04:14
źródło użytkownik

głosy
-1

Wszelkie algorytm najkrótszej ścieżki wykres będzie przesadą, jeśli wszystko, co potrzebne jest do znalezienia, jeśli węzeł jest podłączony do drugiego. Dobrym biblioteki Java, który realizuje to JGraphT . To użycie jest bardzo proste, oto przykładem wykresu 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)));
}

Ten lib oferuje również wszystkie najkrótsze ścieżki, jak również algorytmy.

Odpowiedział 14/11/2016 o 06:34
źródło użytkownik

głosy
0

Widzę, że masz swoją odpowiedź, że to na pewno nie NP zupełnych i jest to bardzo stare pytanie, jak dobrze.

Jednakże, po prostu zaproponować inne podejście do spojrzeć na problem. Można użyć rozłącznych zbiorów do tego. W większości przypadków, dla danego scenariusza, podejście spowoduje lepszego czasu niż robi przechodzenie wykresu (Obejmuje stały czas dla dużego fragmentu testów). Jednak budowanie wykres może wziąć dobry czas, jeśli unia przez kompresję rankingu lub ścieżka jest używana.

Można przeczytać o strukturze danych tutaj .

Odpowiedział 03/09/2018 o 13:36
źródło użytkownik

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