2016-05-12 12 views
1

Ich habe eine Implementierung des Algorithmus von Bellman - Ford. Das Eingabeprogramm lieferte eine Liste von Kanten. Ohne Optimierung sieht es wie folgt aus:Kann rechten Graphen für Bellman-Ford-Algorithmus nicht erzeugen

int i, j; 
     for (i = 0; i < number_of_vertices; i++) { 
      distances[i] = MAX; 
     } 
     distances[source] = 0; 
     for (i = 1; i < number_of_vertices - 1; ++i) { 

      for (j = 0; j < e; ++j) { //here i am calculating the shortest path 
       if (distances[edges.get(j).source] + edges.get(j).weight < distances[edges.get(j).destination]) { 
        distances[edges.get(j).destination] = distances[edges.get(j).source] + edges.get(j).weight; 
       } 
      } 
     } 

es die Komplexität von O (V * E) Aber mit der Optimierung seiner Werke sehr schnell hat. es sieht aus wie

while (true) { 

      boolean any = false; 
      for (j = 0; j < e; ++j) { //here i am calculating the shortest path 
       if (distances[edges.get(j).source] + edges.get(j).weight < distances[edges.get(j).destination]) { 
        distances[edges.get(j).destination] = distances[edges.get(j).source] + edges.get(j).weight; 
        any = true; 
       } 
      } 
      if (!any) break; 
     } 

In der Praxis, wenn die Anzahl der Ecken, zum Beispiel zehntausend, in der äußeren Schleife nur hatte passiert 10-12 Wiederholungen statt 10 Tausend, und der Algorithmus seine Arbeit abgeschlossen.

Dies ist mein Code generieren:

//q - vertices 

for (int q = 100; q <= 20000; q += 100) { 
      List<Edge> edges = new ArrayList(); 
       for (int i = 0; i < q; i++) { 
        for (int j = 0; j < q; j++) { 
         if (i == j) { 
          continue; 
         } 

         double random = Math.random(); 
         if (random < 0.005) { 
          int x = ThreadLocalRandom.current().nextInt(1, 100000); 
          edges.add(new Edge(i, j, x)); 
          edges++; 
         } 
        } 

       } 
       //write edges to file edges 
      } 

Aber ich brauche eine Grafik zu erzeugen, auf dem es nicht so schnell sein wird, seine Arbeit zu beenden. Das kann im Generator geändert werden?

+0

Ihre Frage ist also: Wie sieht ein hartes Beispiel für Bellman-Ford aus (oder die Algorithmen für den kürzesten Weg im Allgemeinen)? – gilleain

+0

@gilleain ja, mit meinem Generator ist die Anzahl der Iterationen der äußeren Schleife zu klein, und es ist notwendig, zufällig "harte"/"einfache" Graphen für diesen Algorithmus zu generieren, mit denen er den Job nicht so schnell beenden konnte . – Birthright

+0

@gilleain Ich brauche es, weil ich die Realisierung von Dijkstra-Algorithmus, der einen binären Baum verwendet, und hat algorithmische Komplexität O (E * log (V)) und Arbeitszeit auch, wie diese Implementierung Bellman Ford mit Optimierung – Birthright

Antwort

1

Die Komplexität von Bellman Ford Algorithmus wie Sie sagten, ist O (| E | * | V |). In Ihrem Generator ist die Wahrscheinlichkeit, eine Kante hinzuzufügen, vernachlässigbar (0,005), weshalb der Code meiner Meinung nach schnell arbeitet.

Erhöhen Sie die Wahrscheinlichkeit, es soll mehr Kanten geben und folglich sollte der Bellman Ford dann längere Zeit brauchen.

+0

In meinem Generator, zum Beispiel, wenn Scheitelpunkte = 10000 -> Kanten ≈500000. Aber die Anzahl der Iterationen der äußeren Schleife ist nicht betroffen. Wenn ich den prozentualen erzeugenden Rand 30% exponiere, und zum Beispiel habe ich 3000 Scheitelpunkte, habe ich 10 Iterationen, während die (wahre) Schleife ohne Optimierung 3000 sein musste. In diesem Beispiel läuft Dijkstra 3523 Millisekunden, Bellman Ford 3024, obwohl der Komplexität von Dijkstra O (E * log (V)) – Birthright

+0

@ Birthright ein Graph mit 10000 Scheitelpunkte mit 500000 Kanten ist nicht dicht. Meiner Meinung nach wird der Unterschied nur bei größeren und dichteren Graphen (mehr Ecken und Kanten) sichtbar werden. –

+0

Ich teste Algorithmen in spärlichen Graphen. Aber ok. Wenn die Generationswahrscheinlichkeit 80% ist, verstehe ich das. Scheitelpunkte = 3000, Kanten = 7196374, Anzahl der Iterationen bei while (wahr) Schleife = 9. Bellman-Ford - 4851 Millisekunde, Dijkstra unter Verwendung des Binärbaums - 5311 Millisekunden – Birthright