Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
133
Task/Closest-pair-problem/Scala/closest-pair-problem.scala
Normal file
133
Task/Closest-pair-problem/Scala/closest-pair-problem.scala
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
import scala.collection.mutable.ListBuffer
|
||||
import scala.util.Random
|
||||
|
||||
object ClosestPair {
|
||||
case class Point(x: Double, y: Double){
|
||||
def distance(p: Point) = math.hypot(x-p.x, y-p.y)
|
||||
|
||||
override def toString = "(" + x + ", " + y + ")"
|
||||
}
|
||||
|
||||
case class Pair(point1: Point, point2: Point) {
|
||||
val distance: Double = point1 distance point2
|
||||
|
||||
override def toString = {
|
||||
point1 + "-" + point2 + " : " + distance
|
||||
}
|
||||
}
|
||||
|
||||
def sortByX(points: List[Point]) = {
|
||||
points.sortBy(point => point.x)
|
||||
}
|
||||
|
||||
def sortByY(points: List[Point]) = {
|
||||
points.sortBy(point => point.y)
|
||||
}
|
||||
|
||||
def divideAndConquer(points: List[Point]): Pair = {
|
||||
val pointsSortedByX = sortByX(points)
|
||||
val pointsSortedByY = sortByY(points)
|
||||
|
||||
divideAndConquer(pointsSortedByX, pointsSortedByY)
|
||||
}
|
||||
|
||||
def bruteForce(points: List[Point]): Pair = {
|
||||
val numPoints = points.size
|
||||
if (numPoints < 2)
|
||||
return null
|
||||
var pair = Pair(points(0), points(1))
|
||||
if (numPoints > 2) {
|
||||
for (i <- 0 until numPoints - 1) {
|
||||
val point1 = points(i)
|
||||
for (j <- i + 1 until numPoints) {
|
||||
val point2 = points(j)
|
||||
val distance = point1 distance point2
|
||||
if (distance < pair.distance)
|
||||
pair = Pair(point1, point2)
|
||||
}
|
||||
}
|
||||
}
|
||||
return pair
|
||||
}
|
||||
|
||||
|
||||
private def divideAndConquer(pointsSortedByX: List[Point], pointsSortedByY: List[Point]): Pair = {
|
||||
val numPoints = pointsSortedByX.size
|
||||
if(numPoints <= 3) {
|
||||
return bruteForce(pointsSortedByX)
|
||||
}
|
||||
|
||||
val dividingIndex = numPoints >>> 1
|
||||
val leftOfCenter = pointsSortedByX.slice(0, dividingIndex)
|
||||
val rightOfCenter = pointsSortedByX.slice(dividingIndex, numPoints)
|
||||
|
||||
var tempList = leftOfCenter.map(x => x)
|
||||
//println(tempList)
|
||||
tempList = sortByY(tempList)
|
||||
var closestPair = divideAndConquer(leftOfCenter, tempList)
|
||||
|
||||
tempList = rightOfCenter.map(x => x)
|
||||
tempList = sortByY(tempList)
|
||||
|
||||
val closestPairRight = divideAndConquer(rightOfCenter, tempList)
|
||||
|
||||
if (closestPairRight.distance < closestPair.distance)
|
||||
closestPair = closestPairRight
|
||||
|
||||
tempList = List[Point]()
|
||||
val shortestDistance = closestPair.distance
|
||||
val centerX = rightOfCenter(0).x
|
||||
|
||||
for (point <- pointsSortedByY) {
|
||||
if (Math.abs(centerX - point.x) < shortestDistance)
|
||||
tempList = tempList :+ point
|
||||
}
|
||||
|
||||
closestPair = shortestDistanceF(tempList, shortestDistance, closestPair)
|
||||
closestPair
|
||||
}
|
||||
|
||||
private def shortestDistanceF(tempList: List[Point], shortestDistance: Double, closestPair: Pair ): Pair = {
|
||||
var shortest = shortestDistance
|
||||
var bestResult = closestPair
|
||||
for (i <- 0 until tempList.size) {
|
||||
val point1 = tempList(i)
|
||||
for (j <- i + 1 until tempList.size) {
|
||||
val point2 = tempList(j)
|
||||
if ((point2.y - point1.y) >= shortestDistance)
|
||||
return closestPair
|
||||
val distance = point1 distance point2
|
||||
if (distance < closestPair.distance)
|
||||
{
|
||||
bestResult = Pair(point1, point2)
|
||||
shortest = distance
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
closestPair
|
||||
}
|
||||
|
||||
def main(args: Array[String]) {
|
||||
val numPoints = if(args.length == 0) 1000 else args(0).toInt
|
||||
|
||||
val points = ListBuffer[Point]()
|
||||
val r = new Random()
|
||||
for (i <- 0 until numPoints) {
|
||||
points.+=:(new Point(r.nextDouble(), r.nextDouble()))
|
||||
}
|
||||
println("Generated " + numPoints + " random points")
|
||||
|
||||
var startTime = System.currentTimeMillis()
|
||||
val bruteForceClosestPair = bruteForce(points.toList)
|
||||
var elapsedTime = System.currentTimeMillis() - startTime
|
||||
println("Brute force (" + elapsedTime + " ms): " + bruteForceClosestPair)
|
||||
|
||||
startTime = System.currentTimeMillis()
|
||||
val dqClosestPair = divideAndConquer(points.toList)
|
||||
elapsedTime = System.currentTimeMillis() - startTime
|
||||
println("Divide and conquer (" + elapsedTime + " ms): " + dqClosestPair)
|
||||
if (bruteForceClosestPair.distance != dqClosestPair.distance)
|
||||
println("MISMATCH")
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue