Implementierung eines Algorithmus (Farthest Insertion zur Lösung des TSP) in O(n²)

amb42

Neues Mitglied
Hallo zusammen,

ich habe lange überlegt, ob dies der richtige Weg ist, um zu einer Lösung meines Problems zu kommen, da ich nicht einschätzen kann, ob das Nicht-Auffinden einer Lösung an meinen geringen Programmierkenntnissen liegt oder aber ein größeres Problem darstellt.

Nun zur Aufgabe: Ich schreibe in meiner Masterthesis über das Thema Traveling Salesman Problem. Genauer gesagt muss ich einen von mir gewählten Algorithmus in Java implementieren, diesen analysieren und im Anschluss Modifikationen vornehmen, um entweder Laufzeit oder Lösungsgüte zu verbessern. Da der Farthest Insertion Algorithmus eine sehr gute Heuristik zur Lösung des TSP ist, habe ich mich dazu entschieden, diesen zu implementieren. Was ich soweit auch geschafft habe. Das Problem ist nun, dass dieser Algorithmus laut Literatur eine Laufzeit von O(n²) hat. Die von mir implementierte Version dieses Algorithmus läuft allerdings in O(n³). Ich versuche seit einigen Wochen eine Lösung zu finden, da ich die Implementierung nicht als Grundlage für meine Analyse verwenden kann, wenn er ja eigentlich "schneller" läuft.

Nun noch kurz der Art, wie ich den Farthest Insertion implementiert habe:

1. Zwei Knoten des Graphen, die maximal zueinander entfernt sind, werden markiert (Laufzeit O(n²)).
2. Solange die Tour nicht vollständig ist, tue Folgendes:
2a. Der nächste einzufügende Knoten wird ausgewählt, indem die Abstände der verbleibenden Knoten zu den bereits markierten Knoten überprüft werden. Davon wird der minimale Abstand jedes verbleibenden Knoten zu den markierten zwischengespeichert und dann wiederum der Knoten gewählt, der von den Minima der Kantengewichte den maximalen Wert hat (Laufzeit O(n³)).
2b. Der ausgwählte Knoten wird an der günstigsten Stelle in die Subtour eingefügt (Laufzeit O(n²)).

Hier die Methode, die den Punkt 2 umfasst:

Java:
/** Returns a hamiltonian path in an array list.*/
	public ArrayList<Integer> getPath(UndirectedGraphAsAdjacencyMatrix g, 
			int [] insertedVertices, int [] leftVertices){
		
		double[][]adj = g.getAdjacencyMatrix();
		
		int wMin = Integer.MAX_VALUE;
		int wIns = Integer.MAX_VALUE; 
		int index = 0; 
		int vertex = -1;
		
		Set<Integer> inserted = new HashSet<Integer>();
		Set<Integer> left = new HashSet<Integer>();
				
		for(int i = 0; i<insertedVertices.length; i++){
			inserted.add(insertedVertices[i]);
			path.add(insertedVertices[i]);
		}
		for(int i = 0; i<leftVertices.length; i++)
			left.add(leftVertices[i]);

		while(path.size()<(insertedVertices.length+leftVertices.length)){
						
			double minDist = Double.POSITIVE_INFINITY;
			double maxDist = Double.NEGATIVE_INFINITY;
			double minDistTour = Double.POSITIVE_INFINITY;
			
			Integer [] ins = inserted.toArray(new Integer[inserted.size()]);
			Integer[] le = left.toArray(new Integer[left.size()]);
			
			if(le.length>1){
			//Die beiden folgenden verschachtelten for-Schleifen innerhalb der while-Schleife 
                        //führen zur kubischen Laufzeit, da jedes Mal alle Kanten überprüft werden.	
				for(int w = 0; w<le.length; w++){
					for(int v = 0; v<ins.length; v++){
						//Comparison of the edge weights 
						//between inserted and left Vertices
						//and buffering of the minimal distance.
						if(minDist>adj[ins[v]][le[w]]) {
							minDist = adj[ins[v]][le[w]];
							wMin = le[w];
						}	
					}
					//Selecting the left vertex 
					//of the buffered minimal distances
					//which has the highest value.
					if(maxDist<minDist){
						maxDist = minDist;
						wIns = wMin;
					}
					minDist = Double.POSITIVE_INFINITY; 
				}
			}

			else wIns = le[0];
			
			for(int i=0; i<ins.length-1;i++){
				//Insertion of the vertex based on
				//min(c_(i)(wIns) + c_(wIns)(i+1) - c_(i)(i+1)).
				if(minDistTour > 
				(adj[path.get(i).intValue()][wIns]
				+adj[wIns][path.get(i+1).intValue()]
				-adj[path.get(i).intValue()][path.get(i+1).intValue()])){
					minDistTour = 
					adj[path.get(i).intValue()][wIns]
					+adj[wIns][path.get(i+1).intValue()]
					-adj[path.get(i).intValue()][path.get(i+1).intValue()];
					
					index = i+1;
					vertex = wIns;
				}
				//Insertion of the vertex based on
				//min(c_(0)(wIns) + c_(wIns)(ins.length-1) - c_(0)(ins.length-1))
				//to proof if return to first vertex is better 
				//than the other insertion positions.
				if(minDistTour > 
				(adj[path.get(0).intValue()][wIns]
				+adj[wIns][path.get(ins.length-1).intValue()]
				-adj[path.get(0).intValue()][path.get(ins.length-1).intValue()])){
					minDistTour = 
					adj[path.get(0).intValue()][wIns]
					+adj[wIns][path.get(ins.length-1).intValue()]
					-adj[path.get(0).intValue()][path.get(ins.length-1).intValue()];
					
					index = ins.length;
					vertex = wIns;
				}
			}
			
			inserted.add(vertex);
			left.remove(vertex);
			minDistTour = Double.POSITIVE_INFINITY;
			
			path.add(index, vertex);
		}	
		return path;
	}

Ich würde mich sehr freuen, wenn jemand eine Idee hätte, wie ich aus dieser kubischen Laufzeit eine quadratische machen könnte. Ich habe schon versucht eine zweidimensionale Array-List zu erstellen, die die bereits überprüften Kanten zwischenspeichert. Da sie allerdings dynamisch sind (also sich ständig ändern) und Methoden wie remove() (O(n)) und sort() (O(nlogn)) ebenfalls Laufzeit verursachen, wodurch ich am Ende eine Laufzeit von O(n³logn) hatte, hab ich diesen Ansatz wieder verworfen.

Vielen Dank im Voraus fürs Grübeln!

Liebe Grüße
amb42

PS.: Hoher Speicherbedarf soll egal sein. Wichtig ist die Laufzeit.
 

Marco13

Top Contributor
Eine Websuche liefert schnell sowas wie TSP Heuristics mit Code ganz unten, habe aber nicht nachvollzogen, ob das wirklich O(n^2) ist.

Ich dachte erst, dass man die inneren beiden Schleifen durch irgendeinen Heap ersetzen könnte, habe aber wiederum nicht nachvollzogen, welche Laufzeit da rauskäme - wenn auf dem Heap 'removeFirst' eine Amortisierte konstante Laufzeit hätte, müßte es aber insgesamt O(n^2) sein...
 

amb42

Neues Mitglied
Hallo Marco13,

vielen Dank für deine Antwort! Ich bin mittlerweile auf eine Lösung gekommen, die völlig simpel ist und weniger mit meinen Programmierkenntnissen zu tun hat, sondern vielmehr ein algorithmisches Problem ist.

Danke trotzdem :)
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
D Input/Output Implementierung eines CommandHandlers/Parsers für viele Eingaben Allgemeine Java-Themen 26
Stonie Prüfen von direkter Implementierung eines Interfaces Allgemeine Java-Themen 7
L Implementierung eines AVT-Baums Allgemeine Java-Themen 2
R Implementierung eines Interface durch 2 verschiedene Klassen Allgemeine Java-Themen 6
K Objekt einer konkreten Implementierung eines Interfaces durch übergebenen String Allgemeine Java-Themen 2
B Elegantere Lösung bei der Implementierung eines Interfaces Allgemeine Java-Themen 2
L Unterschied zwischen List und LinkedList implementierung? Allgemeine Java-Themen 15
boschl2000 Springerproblem-Implementierung funktioniert nicht richtig Allgemeine Java-Themen 1
L rotateLeft implementierung Allgemeine Java-Themen 2
R In der Ausgabe sollte anstelle des obersten Sterns ein "+" stehen nur scheitere ich bei der Implementierung Allgemeine Java-Themen 9
S Mutable objects und Implementierung von ChangeEvents Allgemeine Java-Themen 5
W Queue Implementierung Allgemeine Java-Themen 6
C Ein Iterator ist eine Implementierung des Interface Iterable? Allgemeine Java-Themen 2
F Implementierung von Teilprogrammen [Java|Python] Allgemeine Java-Themen 7
I TimSort - Sortieralgorithmus - Erklärung und Pseudocode - Implementierung Allgemeine Java-Themen 2
ruutaiokwu burstsort-implementierung in java? Allgemeine Java-Themen 2
D Implementierung einer Mehrsprachigkeit, wichtig ? Allgemeine Java-Themen 5
D Implementierung einer Rechteverwaltung Allgemeine Java-Themen 2
R "Countdown" Implementierung Allgemeine Java-Themen 5
K A*-Implementierung flexibler machen Allgemeine Java-Themen 4
J Java-Implementierung diverser Beziehungen zwischen Klassen bzw. Objekten Allgemeine Java-Themen 2
S BlueJ Cäsar-Implementierung Allgemeine Java-Themen 6
S Implementierung Programmneustart Allgemeine Java-Themen 10
G Implementierung einer Kommunikation Allgemeine Java-Themen 7
S Implementierung einer PluginArchitektur Allgemeine Java-Themen 5
A OOP: Überschreiben/Implementierung von Methoden Allgemeine Java-Themen 5
R Intervall-Implementierung mit selbstgebauter LinkedList Allgemeine Java-Themen 7
J Best Practice für implementierung von equals(...) Allgemeine Java-Themen 7
Kr0e Eigene RMI Implementierung Allgemeine Java-Themen 3
V Wie finde ich die konkrete Implementierung? Allgemeine Java-Themen 8
G Implementierung vom AKS-Test Allgemeine Java-Themen 11
R software implementierung Allgemeine Java-Themen 3
N Observer/Observable der JAVA-API od. eigene Implementierung Allgemeine Java-Themen 2
K Design / Implementierung Allgemeine Java-Themen 5
B jre browser implementierung ? Allgemeine Java-Themen 4
G Klasse Queue Implementierung in Java Allgemeine Java-Themen 4
G Eigene PrintService Implementierung. Allgemeine Java-Themen 5
O regulärer Ausdruck zum durchsuchen eines Strings verwenden Allgemeine Java-Themen 2
T Rotationswinkel eines Bildes bestimmen Allgemeine Java-Themen 4
C Probleme beim Erstellen eines runnable-jar files Allgemeine Java-Themen 1
J JavaScript innerhalb eines Java Projekts ausführen Allgemeine Java-Themen 2
Encera Größe eines Objektes in Byte berechnen Allgemeine Java-Themen 2
8u3631984 Prüfen ob min. ein Element eines Sets in einem anderen Set enh Allgemeine Java-Themen 4
M Array Rang eines Elements Allgemeine Java-Themen 4
OnDemand Teile eines Links entfernen Allgemeine Java-Themen 6
H Auslesen eines (LDAP-)Attributs in Active Directory Allgemeine Java-Themen 2
W JSON parsen eines ,mit JS.stringify erstellten Strings Allgemeine Java-Themen 27
H Textposition eines gedrehten Textes verschieben Allgemeine Java-Themen 8
berserkerdq2 run-methode eines Threads so programmieren, dass 30x die Sekunde etwas ausgeführt wird. Allgemeine Java-Themen 44
E Ersetzen eines Bildes in der Kopfzeile eines Word-Docx-Dokuments mit Apache POI XWPF Allgemeine Java-Themen 0
N Fahrtrichtung eines selbstfahrenden Auto ändern Allgemeine Java-Themen 3
T Letztes Zeichen eines Strings enfernen Allgemeine Java-Themen 14
S Übergabe eines Sortierkriteriums für ein Artikel Array mittels BiPredicate<Artikel, Artikel> Allgemeine Java-Themen 13
gotzi242 Schatzsuche mithilfe eines O(log n) Algorithmus Allgemeine Java-Themen 2
C Koordinaten LONG/LAT eines neuen Punktes in bestimmter Entfernen und Winkel berechnen Allgemeine Java-Themen 3
Tobero Meine Funktion für das beinhalten eines Punktes in einem Kreis funktioniert nicht Allgemeine Java-Themen 5
LimDul Direktes return eines Array geht nicht Allgemeine Java-Themen 20
S Mittelwert anhand eines Stream berechnen Allgemeine Java-Themen 5
kodela Breite eines erweiterten Monitors feststellen Allgemeine Java-Themen 5
R Zeilen eines 2d Arrays abwechselnd links und rechts mit Nullen auffüllen Allgemeine Java-Themen 14
Zrebna Alternative Darstellung eines Codesnippets Allgemeine Java-Themen 33
kodela Inhalt eines Arrays ändert sich mysteriös Allgemeine Java-Themen 2
bueseb84 Wget mit Wildcards - oder wie lädt man bei JFrog die letzte Version eines Artifacts herunter Allgemeine Java-Themen 3
N Erkennen eines Programs Allgemeine Java-Themen 2
N Pausieren eines Programmes Allgemeine Java-Themen 4
M Gibt es eine API die den aktuellen Wert eines Indikators beim Trading zurückgibt? Allgemeine Java-Themen 7
F Wie bekommt man alle Filenamen eines Webserver Verzeichnisses Allgemeine Java-Themen 6
A Fehler beim Öffnen eines Projekts Allgemeine Java-Themen 6
N Eigenschaften eines Buttons per Setter verändern Allgemeine Java-Themen 5
S Ausfuehrung eines Programms aufzeichnen..? Allgemeine Java-Themen 4
X Ermittlung eines doppelte Paars mit Streams Allgemeine Java-Themen 50
S Vorbereitung eines Praktikums Allgemeine Java-Themen 4
H Aufruf eines Web Service anhand übergebenen Parameter Allgemeine Java-Themen 2
M Weiterleiten von empfangenen Nachrichten eines StompSessionHandlers Allgemeine Java-Themen 1
J Programm zum Suchen eines Wortes im Dateisystem Allgemeine Java-Themen 4
H Rename eines Projekts Allgemeine Java-Themen 1
J Fenstergröße eines anderen Programmes auslesen Allgemeine Java-Themen 9
ReinerCoder auf Klassen innerhalb eines package zugreifen Allgemeine Java-Themen 22
Meeresgott Erste Schritte Sourcetree - Git | Suchen eines Commits Allgemeine Java-Themen 2
E Status eines USB Mikrofon abfragen Allgemeine Java-Themen 2
DaCrazyJavaExpert OOP Ansätze und Tipps zum Porgrammieren eines Taschenrechners Allgemeine Java-Themen 25
A OOP Problem beim Berechnen der größten Fläche eines Ringes Allgemeine Java-Themen 19
JavaNewbie2.0 Start eines Anderen Programm erkennen Allgemeine Java-Themen 6
I Verbindung eines Java-Plugins mit Webserver Allgemeine Java-Themen 3
L Auswertung eines Testes funktioniert nicht Allgemeine Java-Themen 37
G Iteratoren - Wie kann man mithilfe von Iteratoren nur jeden zweiten Wert eines TreeSets ausgeben? Allgemeine Java-Themen 4
GreenTeaYT Elemente eines 2Dim LinkedList von links nach rechts ausgeben? Allgemeine Java-Themen 0
B Spalten eines 2d-Arrays Allgemeine Java-Themen 2
M Rechenprogramm eines wissenschaftlichen Taschenrechners Allgemeine Java-Themen 4
S Eigenschaften (hier Verknüpfung) eines Files lesen Allgemeine Java-Themen 2
E Typüberprüfung eines chars Allgemeine Java-Themen 5
H Hilfe bei Erstellung eines Hilfe Fenster bei Tastendruck (F1 bei Win98) Allgemeine Java-Themen 5
T Teile eines Double-Wertes verändern Allgemeine Java-Themen 2
R Rückgabe eines Arrays durch Funktion Allgemeine Java-Themen 9
H Datentypen Typ eines Arrays überprüfen Allgemeine Java-Themen 9
RalleYTN DPI eines Bildes ändern Allgemeine Java-Themen 4
N Methoden Methoden einer Klasse auf Grundlage eines Strings aufrufen Allgemeine Java-Themen 6
K Bestimmten Bereich eines Strings lesen Allgemeine Java-Themen 6
C -Verschiedene Versionen eines Programms verwalten Allgemeine Java-Themen 7
O Datentypen Erstellung eines Containers, der verschachtelte Map-Strukturen beherbergen kann Allgemeine Java-Themen 0

Ähnliche Java Themen

Neue Themen


Oben