2009-04-25 7 views

Répondre

5

EDIT: Oups, mal lu la question. Merci @jfclavette d'avoir choisi ça. La vieille réponse est à la fin.

Le problème que vous essayez de résoudre s'appelle le Travelling salesman problem. Il y a beaucoup de potential solutions, mais c'est NP-complet donc vous ne pourrez pas résoudre les grands graphiques.

ancienne réponse:

Qu'est-ce que vous essayez de trouver est appelé girth d'un graphe. Il peut être résolu en définissant les distances d'un nœud à lui-même à l'infini et en utilisant l'algorithme Floyd-Warshall. La longueur du plus court cycle à partir du nœud i est alors juste l'entrée en position ii.

+0

Il veut trouver le chemin le plus court qui visite tous les nœuds, et non le cycle le plus court qui ramène à l'original. Au moins, c'est ce que j'ai compris de la question. – jfclavette

+0

Merci, édité ma réponse. – marcog

+7

Il pourrait ne pas être tout à fait le problème de vendeur itinérant car il ne semble y avoir aucune restriction dans la question que les nœuds soient visités exactement une fois. Donc, ce problème ne nécessite pas que le graphique ait un cycle hamiltonien. – jfclavette

1

Pour un graphe non pondéré, BFS fera le travail. Comme il y a un cycle potentiel dans votre graphique, vous devez garder une trace du nœud visité (vous avez en quelque sorte besoin de le faire pour BFS de toute façon).

Pour le graphe pondéré, l'algorithme de bellman-Ford peut être utilisé. Il est également capable de détecter les cycles.

2

En pseudocode:

//INPUT: graph G = (V,E) 
//OUTPUT: shortest cycle length 
min_cycle(G) 
    min = ∞ 
    for u in V 
    len = dij_cyc(G,u) 
    if min > len 
     min = len 
    return min  

//INPUT: graph G and vertex s 
//OUTPUT: minimum distance back to s 
dij_cyc(G,s) 
    for u in V 
    dist(u) = ∞ 
        //makequeue returns a priority queue of all V 
    H = makequeue(V) //using dist-values as keys with s First In 
    while !H.empty? 
    u = deletemin(H) 
    for all edges (u,v) in E 
     if dist(v) > dist(u) + l(u,v) then 
     dist(v) = dist(u) + l(u,v) 
     decreasekey(H,v) 

    return dist(s) 

Cela va une années Dijkstra légèrement différentes sur chaque sommet. Le Dijkstras muté a quelques différences clés. Tout d'abord, toutes les distances initiales sont définies sur ∞, même le sommet de départ . Deuxièmement, le sommet de départ doit d'abord être mis dans la file d'attente pour que le résultat soit le premier, car ils ont tous la même priorité. Enfin, le Dijkstras muté renvoie la distance au nœud de départ. S'il n'y avait pas de retour au point de départ , la distance reste ∞. Le minimum de tous ces retours des Dijkstras mutés est le chemin le plus court. Puisque Dijkstras court au pire dans O (| V |^2) et que min_cycle court cette forme de Dijkstras | V | fois, le temps final pour trouver le cycle le plus court est O (| V |^3). Si min_cyc renvoie ∞ alors le graphe est acyclique.

Pour retourner le chemin réel du cycle le plus court, seules de légères modifications doivent être effectuées.

Questions connexes