2011-04-23 14 views
7

Wiem, że zostało to wcześniej zadane, ale nie znalazłem odpowiedzi w żadnym z postów. Czy ktoś może zaproponować mi algorytm wyliczający WSZYSTKIE ścieżki Hamilton na wykresie?Wyliczenie * wszystkich * ścieżek hamiltonianskich

Nieco tła: Pracuję nad problemem, w którym muszę wyliczyć każdą ścieżkę Hamiltona, wykonać analizę i zwrócić wynik. W tym celu muszę umieć wyliczyć wszystkie możliwe ścieżki hamiltonian.

Dzięki.

+0

Próbowałaś zwykłego poszukiwania? BFS/DFS? Jak duże są twoje wykresy? – slezica

+0

Santiago, dzięki za odpowiedź. Moje wykresy są małe (6-7 węzłów). Myślałem o BFS i DFS, ale zakładam, że BFS/DFS są używane do wyszukiwania określonego klucza, zamiast wyliczać wszystkie możliwe ścieżki. Jak sprawić, aby BFS/DFS generował * wszystkie * możliwe cykle .. –

+0

Regularne BFS/DFS jest warunkowane, aby zatrzymać po znalezieniu pierwszego pasującego klucza. Musisz to zmienić, poprowadź cały wykres (jeśli to możliwe) i zanotuj go jako rozwiązanie. – slezica

Odpowiedz

3

Użyj BFS/DFS zgodnie z sugestią, ale nie zatrzymuj się przy pierwszym rozwiązaniu. Głównym zastosowaniem BFS/DFS (w tym przypadku) będzie znalezienie całego rozwiązania, musisz ustawić warunek, aby zatrzymał się na pierwszym.

+0

Dzięki. Czy możesz wyjaśnić, co masz na myśli przez "rozwiązanie"? O ile mi wiadomo, uruchomienie DFS na wykresie po prostu da sekwencję odwiedzanych węzłów (np. A-> B-> C-> D dla wykresu z wierzchołkami A, B, C, D). Ale nigdy nie "odkryłoby" WSZYSTKICH możliwych ścieżek. Czy mógłbyś to rozwinąć? –

+1

Zarówno DFS, jak i BFS podadzą WSZYSTKIE możliwe ścieżki zaczynające się od określonego węzła. Z tych ścieżek Hamiltona są te, których długości są dokładnie takie same jak rozmiar wykresu, a każdy węzeł istnieje dokładnie jeden raz. Więc jeśli masz wykres z 5 węzłami i istnieje ścieżka p1-> p2-> p3-> p4-> p5, jest to ścieżka hamiltonowska. Zauważ również, że będziesz musiał rozpocząć wyszukiwanie od każdego węzła. – SinistraD

+0

Dzięki SinistraD, to bardzo pomocne! –

3

mojego kodu Java: (absolutnie opartą na metodzie rekurencyjnego)

algorytmu:

+ Rozpocznij w 1 punkt podłączenia do innego punktu to widzę (w celu utworzenia ścieżki).

+ Usuń ścieżkę i rekursywnie znajdź nową ścieżkę w najnowszym punkcie, aż do połączenia wszystkich punktów wykresu.

+ usunąć ścieżkę i wracać do wyjściowego wykresu Jeśli nie tworzą ścieżkę Hamiltona z najnowszego punktu

public class HamiltonPath { 
public static void main(String[] args){ 
    HamiltonPath obj = new HamiltonPath(); 

    int[][]x = {{0,1,0,1,0}, //Represent the graphs in the adjacent matrix forms 
       {1,0,0,0,1}, 
       {0,0,0,1,0}, 
       {1,0,1,0,1}, 
       {0,1,0,1,0}}; 

    int[][]y = {{0,1,0,0,0,1}, 
       {1,0,1,0,0,1}, 
       {0,1,0,1,1,0}, 
       {0,0,1,0,0,0}, 
       {0,0,1,0,0,1}, 
       {1,1,0,0,1,0}}; 

    int[][]z = {{0,1,1,0,0,1}, 
       {1,0,1,0,0,0}, 
       {1,1,0,1,0,1}, 
       {0,0,1,0,1,0}, 
       {0,0,0,1,0,1}, 
       {1,0,1,0,1,0}}; 

    obj.allHamiltonPath(y); //list all Hamiltonian paths of graph 
    //obj.HamiltonPath(z,1); //list all Hamiltonian paths start at point 1 


} 

static int len; 
static int[]path; 
static int count = 0;  

public void allHamiltonPath(int[][]x){ //List all possible Hamilton path in the graph 
    len = x.length; 
    path = new int[len]; 
    int i; 
    for(i = 0;i<len;i++){ //Go through column(of matrix) 
     path[0]=i+1; 
     findHamiltonpath(x,0,i,0); 
    } 
} 

public void HamiltonPath(int[][]x, int start){ //List all possible Hamilton path with fixed starting point 
    len = x.length; 
    path = new int[len]; 
    int i; 
    for(i = start-1;i<start;i++){ //Go through row(with given column) 
     path[0]=i+1; 
     findHamiltonpath(x,0,i,0); 
    } 
} 

private void findHamiltonpath(int[][]M,int x,int y,int l){ 

    int i; 
     for(i=x;i<len;i++){   //Go through row 

      if(M[i][y]!=0){  //2 point connect 

       if(detect(path,i+1))// if detect a point that already in the path => duplicate 
        continue; 

       l++;   //Increase path length due to 1 new point is connected 
       path[l]=i+1; //correspond to the array that start at 0, graph that start at point 1 
       if(l==len-1){//Except initial point already count =>success connect all point 
        count++; 
        if (count ==1) 
       System.out.println("Hamilton path of graph: "); 
        display(path); 
        l--; 
        continue; 
       } 

       M[i][y]=M[y][i]=0; //remove the path that has been get and 
       findHamiltonpath(M,0,i,l); //recursively start to find new path at new end point 
       l--;    // reduce path length due to the failure to find new path   
       M[i][y] = M[y][i]=1; //and tranform back to the inital form of adjacent matrix(graph) 
      } 
    }path[l+1]=0; //disconnect two point correspond the failure to find the.. 
}      //possible hamilton path at new point(ignore newest point try another one)   

public void display(int[]x){ 

    System.out.print(count+" : "); 
    for(int i:x){ 
     System.out.print(i+" "); 
    } 
     System.out.println(); 
} 

private boolean detect(int[]x,int target){ //Detect duplicate point in Halmilton path 
    boolean t=false;       
    for(int i:x){ 
     if(i==target){ 
      t = true; 
      break; 
     } 
    } 
    return t; 
} 

}

0

rozwiązanie w Python3:

def hamiltonians(G, vis = []): 
    if not vis: 
     for n in G: 
      for p in hamiltonians(G, [n]): 
       yield p 
    else: 
     dests = set(G[vis[-1]]) - set(vis) 
     if not dests and len(vis) == len(G): 
      yield vis 
     for n in dests: 
      for p in hamiltonians(G, vis + [n]): 
       yield p 
G = {'a' : 'bc', 'b' : 'ad', 'c' : 'b', 'd' : 'ac'} 
print(list(hamiltonians(G))) 
Powiązane problemy