Scala實現DP(道格拉斯-普克)算法

Scala實現DP(道格拉斯-普克)算法

DP算法介紹

DP算法

算法實現

DP算法實現

scala實現

// 創建一個Point類
case class Point(x: Double, y: Double)


// 方法實現
 def dp(pts: Seq[Point], tolerance: Double): Seq[Point] = {

    if (pts.size < 3) return pts

    val listBuffer = new ListBuffer[Point]()
    listBuffer.append(pts.head)

    def dpRunner(pts: Seq[Point], tolerance: Double): Unit = {

      val head = pts.head
      val last = pts.last

      // 首尾點連成的線段
      val lineSegment: LineSegment = LineSegment(head, last)

      //求曲線上所有點到直線的垂直距離,並找出最大距離dmax
      //最大距離的點
      val maxDistancePoint = pts.maxBy(lineSegment.distancep)

      // 最大距離
      val maxDistance: Double = lineSegment.distancep(maxDistancePoint)

      //最大距離點的索引
      val maxPointIndex = pts.indexOf(maxDistancePoint)

      // 如果最大距離小於給定的閾值,則將曲線中間的所有點捨去
      if (maxDistance < tolerance) {
        listBuffer.append(last)
      } else {
        // 如果最大距離大於給定的閾值,則以該點爲界將曲線劃分爲兩部分,重複以上步驟
        dpRunner(pts.slice(0, maxPointIndex + 1), tolerance)
        dpRunner(pts.slice(maxPointIndex, pts.size), tolerance)
      }
    }

    dpRunner(pts, tolerance)
    listBuffer
  }
// 數據測試
def main(args: Array[String]): Unit = {

    val pts: Seq[Point] = Seq(
      Point(107.605, 137.329),
      Point(122.274, 169.126),
      Point(132.559, 179.311),
      Point(153.324, 184.276),
      Point(171.884, 174.654),
      Point(186.408, 168.634),
      Point(196.566, 145.204),
      Point(200.549, 127.877),
      Point(211.391, 118.179),
      Point(216.318, 116.547),
      Point(225.197, 122.796),
      Point(231.064, 135.459),
      Point(240.835, 143.398),
      Point(254.630, 144.933),
      Point(265.055, 158.761),
      Point(271.004, 159.660),
      Point(274.474, 173.979)
    )

    dp(pts, 8).foreach(println)

  }
結果:

Point(107.605,137.329)
Point(122.274,169.126)
Point(153.324,184.276)
Point(186.408,168.634)
Point(200.549,127.877)
Point(216.318,116.547)
Point(274.474,173.979)

參考資料

https://segmentfault.com/a/1190000016734779

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章