Kann der Dijkstra-Single-Source-Shortest-Path-Algorithmus erkennt einen unendlichen Zyklus in einem graph?
So kam ich zu diesem schönen problem, das Sie auffordert, ein Programm zu schreiben, die feststellt, ob eine negative Unendlichkeit kürzesten Pfad in einem gerichteten Graphen. (Kann auch gedacht werden, als herauszufinden, ob ein "negativer Zyklus" existiert in der Grafik). Hier ist ein link für das problem:
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=499
Habe ich erfolgreich gelöst ist das problem mit Bellman-Ford-Algorithmus zweimal durch starten von einer beliebigen Quelle in das Diagramm. Das zweite mal, dass ich den Algorithmus, den ich überprüfen, ob ein Knoten gelockert werden können. Wenn dem so ist, dann gibt es definitiv einen negativen Zyklus in dem Graphen. Unten ist mein C++ - code:
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main()
{
int test;
cin>>test;
for(int T=0; T<test; T++)
{
int node, E;
cin>>node>>E;
int **edge= new int *[E];
for(int i=0; i<E; i++)
{
edge[i]= new int [3];
cin>>edge[i][0]>>edge[i][1]>>edge[i][2];
}
int *d= new int [node];
bool possible=false;
for(int i=0; i<node;i++)
{
d[i]= 999999999;
}
d[node-1]=0;
for(int i=0; i<node-1; i++)
{
for(int j=0; j<E; j++)
{
if(d[edge[j][1]]>d[edge[j][0]]+edge[j][2])
d[edge[j][1]]=d[edge[j][0]]+edge[j][2];
}
}
//time to judge!
for(int i=0; i<node-1; i++)
{
for(int j=0; j<E; j++)
{
if(d[edge[j][1]]>d[edge[j][0]]+edge[j][2])
{
possible=true;
break;
}
}
if(possible)
break;
}
if(possible)
cout<<"possible"<<endl;
else
cout<<"not possible"<<endl;
}
}
Professor sagte mir einmal, dass Dijkstra ' s shortest path Algorithmus nicht finden können, solche negativen Zyklus, aber er Tat nicht rechtfertigen. Ich eigentlich bezweifle diese Behauptung.
Meine Frage ist, kann Dijktstra single-source-shortest-path-Algorithmus zu erkennen, dass die negativen Zyklus?
Natürlich kann ich versuchen, Dijkstra und überprüfen, ob es funktionieren wird, aber ich war begeistert, diese Idee teilen mit Ihnen.
- was bedeutet unendlich?
- Sorry, ich denke, der richtige Begriff ist "negativen Kreislauf". Im gewichteter graph einen negativen Zyklus ist ein Zyklus, dessen Summe der kantengewichte negativ ist.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Du missverstanden Ihrem professor: er muss gesagt haben, dass der Dijkstra-Algorithmus wird nicht funktionieren, wenn es eine negative Zyklus in dem Graphen. Positive Zyklen sind erlaubt.
Den Grund, warum der Algorithmus funktioniert nicht für Graphen mit negativen Zyklen ist, dass der kürzeste Pfad in einem solchen Graphen ist nicht definiert: sobald man zu einem negativen Zyklus, können Sie die Kosten für Ihre "kürzesten Weg" so niedrig, wie Sie möchten, indem Sie nach dem negativen Zyklus mehrere Male.
Betrachten Sie das Beispiel oben: Sie beginnen bei der vertex
Start
, und kommen zuA
mit den Kosten der1
. Dann gehen Sie zuB
mit den Gesamtkosten-1
zuC
mit insgesamt-4
, und jetzt Sie können gehen Sie zurück zuA
mit den Gesamtkosten gleich null. Durch die Verlängerung der SequenzStart
-A
-B
-C
-A
-B
-C
-A
-B
-C
-...-Finish
Sie könnten die Kosten für einen Pfad vonStart
zuFinish
als kleine negative Zahl, wie Sie wollen.Beachten Sie, dass der negative Zyklus Einschränkung gilt für alle algorithmen zum finden von kürzesten Pfad in einem Graphen. Die Beschränkung auf Dijkstra ' s Algorithmus ist sogar noch stärker: er verbietet alle negativen Kanten.
Ist es durchaus möglich, zu ändern Dijkstra-Algorithmus zur Erkennung negativer Zyklen, aber es hat keinen Sinn, so zu tun, denn Sie haben eine stärkere Einschränkung, keine negativen Kanten.
Finish
. Dies ist wegen 2 Gründen: Sobald ein Knoten als "besucht" markiert mit Dijkstra, es ist nicht erneut besucht werden; Siehe die Antwort für eine Erläuterung. Nächste Grund ist, weil der Abstand zu C ist -3 dann ist der nächste gangbare option, nach dem Besuch von C istFinish
weil-3 + 1 < -3 + 4
Kein Algorithmus weder Dijkstra und Bellman-Ford noch Floyd-Warshall Arbeit auf Graphen mit negativen Zyklus, aber die letzten beiden kann erkennen, einer in der Erwägung, dass Dijkstra ' s nicht, weil Dijkstra ist greedy, während andere verwenden Sie dynamische Programmierung. Außerdem Dijkstra funktioniert nicht mit negativen Gewichtungen auch ohne negative Zyklen.