2017-07-15 2 views
1

Ich schreibe eine App, wo Leistung ist am wichtigsten und ich muss durchlaufen eine Reihe von Arbeitsstationen, die alle Positionen mit x haben - und y-Koordinaten. Dies ist der relevante Teil des Arbeitsplatz und die Position:Was ist der effizienteste Weg, um den minimalen und maximalen Wert von zwei Eigenschaften einer Reihe von Objekten zu erhalten

struct Workstation { 
    let position: Position 
} 

struct Position { 
    let x, y: Int 

    func distance(to otherPosition: Position) -> Int { 
     return abs(self.x - otherPosition.x) + abs(self.y - otherPosition.y) 
    } 
} 

Das Ziel in diesem speziellen Fall ist rund um alle Arbeitsplätze der Hälfte der Länge der Diagonalen des Rechtecks ​​zu bekommen, aber ich habe später einige andere Berechnungen zu tun ebenfalls (wie zum Beispiel die Mittelkoordinate aller Workstations).

kam ich mit zwei möglichen Lösungen bis (Anmerkung: layout.workstations vom Typ Set<Workstation>):

Lösung 1

private func getSurroundingRectangeScore(for layout: FactoryLayout) -> Double { 
    var minX = Int.max 
    var maxX = Int.min 
    var minY = Int.max 
    var maxY = Int.min 
    for workstation in layout.workstations { 
     let pos = workstation.position 
     if pos.x < minX { minX = pos.x } 
     if pos.x > maxX { maxX = pos.x } 
     if pos.y < minY { minY = pos.y } 
     if pos.y > maxY { maxY = pos.y } 
    } 
    let minPosition = Position(x: minX, y: minY) 
    let maxPosition = Position(x: maxX, y: maxY) 
    return Double(minPosition.distance(to: maxPosition))/2 
} 

Lösung 2

private func getSurroundingRectangeScore(for layout: FactoryLayout) -> Double { 
    let xValues = layout.workstations.map { $0.position.x } 
    let yValues = layout.workstations.map { $0.position.y } 

    guard let minX = xValues.min(), let maxX = xValues.max(), let minY = yValues.min(), let maxY = yValues.max() else { 
     fatalError("Minima or Maxima could not be determined!") 
    } 

    let minPosition = Position(x: minX, y: minY) 
    let maxPosition = Position(x: maxX, y: maxY) 
    return Double(minPosition.distance(to: maxPosition))/2 
} 

Mein Verständnis ist, diese Lösung 1 iteriert durch die Worksta nur einmal und füllt alle benötigten Koordinatenvariablen auf einen Schlag. Lösung 2 ist besser lesbar, muss aber die Workstation zweimal und die resultierenden Arrays viermal wiederholen, also ist das bei weitem schlechter. Meine Frage wäre also, ob meine Annahme richtig ist und ob es eine noch effizientere Methode gibt, hier zu rechnen.

+2

Ich würde denken, O (n) wäre die bestmögliche Komplexität für dieses Problem, also ist Ihre erste Lösung wahrscheinlich so gut wie es geht. – Carcigenicate

+0

Sind die x- und y-Koordinaten voneinander unabhängig? Wenn dies der Fall ist, können Sie O (log n) erreichen, was wesentlich schneller ist. Wenn nicht, dann befürchte ich, dass O (n) höchstwahrscheinlich deine beste Wette ist (das ist natürlich ohne den Rest der Anforderungen der App/Algo zu sehen) – TNguyen

+0

@ TPN1994 wenn ich deine Frage richtig verstehe: sie sind unabhängig für diese Berechnung, ja, weil ich nur das Minimum aller x-Werte und alle y-Werte benötige, um zwei neue Positionen zu bilden (im Gegensatz zum Finden der minimalen und maximalen Position (x, y) aller gegebenen Positionen - was hier nicht benötigt wird) . Wie würde ich dann O (log n) erreichen? –

Antwort

2

Erstens raten Sie nicht, welche schlechter ist. Führen Sie es aus und messen Sie es. (Es gibt auch eine Option neben Ihren beiden, die die integrierte Sortierroutine verwendet und dann die Enden des Ergebnisses betrachtet.)

Zweitens, wenn es eine Voraussetzung ist, dass der Zugriff auf diese Informationen immer so schnell wie möglich ist, Verwenden Sie dann eine Datenstruktur, die die Anforderung unterstützt. Suchen Sie die Werte für die anfängliche Sammlung einmal und aktualisieren Sie sie dann jedes Mal, wenn ein Element hinzugefügt wird. Anstatt Informationen wegzuwerfen und wiederholt dieselben N Vergleiche zu tun, tun Sie nur vier jedes Mal, wenn ein neues Workstation hinzugefügt wird. Dann können Sie die Extremitäten ständig lesen, wann immer Sie sie brauchen.

+0

Ich bin relativ neu in der Programmierung im Allgemeinen und Effizienz ist eine Voraussetzung für das erste Mal mit diesem Projekt, so dass Ihre Antwort mir sehr geholfen hat. Es war mir nicht in den Sinn gekommen, dies zu einem früheren Zeitpunkt und nicht an dem Punkt zu lösen, an dem eine Messung erforderlich ist. Ich werde es jetzt so implementieren :) –

+1

Großartig, froh, dass ich helfen konnte. Schauen Sie sich auch [den "Heap"] an (https://en.wikipedia.org/wiki/Heap_ (data_structure)). –

Verwandte Themen