Scala實現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