2017-07-15 97 views
1

我正在編寫一個應用程序,其中性能是最重要的,我必須遍歷一組工作站,這些工作站都具有x - 和y座標。這是工作站的相關部分和位置:獲取一組對象的兩個屬性的最小值和最大值的最有效方法是什麼

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) 
    } 
} 

在這種特定的情況下,我們的目標是讓對角線周圍的所有工作站的矩形的長度的一半,但我後來做了一些其他的計算(例如獲取所有工作站的中心座標)。

我想出了兩種可能的解決方案(注:layout.workstationsSet<Workstation>類型):

解決方案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 
} 

解決方案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 
} 

我的理解是解決方案1遍歷工作區只有一次,並在一次填充所有需要的座標變量。解決方案2的可讀性更好,但必須迭代兩次工作站集合和最終的數組四次,所以我猜這是更糟糕的。所以我的問題是,如果我的假設是正確的,如果有更高效的計算方法?

+2

我認爲O(n)對於這個問題來說可能是最好的複雜性,所以你的第一個解決方案可能就像它得到的那樣好。 – Carcigenicate

+0

x和y座標是否相互獨立?如果他們是那麼你將能夠達到O(log n),這是顯着更快。如果不是,那麼恐怕O(n)最有可能是你最好的選擇(當然,如果我正確理解你的問題,這當然沒有看到應用程序/算法的其餘要求) – TNguyen

+0

@ TPN1994:它們是獨立的這個計算是的,因爲我只需要所有x值和所有y值中的最小值來形成兩個新的位置(與找到所有給定位置的最小和最大位置(x,y)相對比 - 這在此不需要) 。那麼我將如何實現O(log n)呢? –

回答

2

首先,不要猜測哪一個更糟。運行它並測量它。 (除了兩者之外,還有一個選項,它使用內置的排序例程,然後查看結果的結尾。)

其次,如果要求訪問此信息的速度始終儘可能快,然後使用支持該要求的數據結構。一次找到初始集合的值,然後在每次添加元素時更新它們。除了丟棄信息並重復進行相同的比較外,每次添加新的Workstation時只做四次。然後,每當你需要他們時,你都可以隨時閱讀四肢。

+0

對於一般的編碼我相對比較陌生,效率是這個項目的第一次要求,所以你的回答對我有很大的幫助。在早期階段解決這個問題,而不是在需要進行測量的地方進行,這並沒有超出我的想法。我現在將以這種方式實施:) –

+1

太棒了,很高興我能幫到你。也可以查看[「堆」](https://en.wikipedia.org/wiki/Heap_(data_structure))。 –

相關問題